The transformation of the collate depends on its value, since it can be supported or not supported.
Currently, these are the languages that are supported for the transformation, if they are found in the collate, they will be transformed into its Snowflake equivalent.
SQL Server
Snowflake
Latin1_General
EN
Modern_Spanish
ES
French
FR
If the language is not one of the above, the collate will be commented.
The collate in SQL Server comes with additional specifications, such as CI, CS, AI, and AS. If there are additional specifications that are unsupported, they will be commented in the result.
:force:
CREATEORREPLACETABLE TABLECOLLATE
(
COL1 VARCHARCOLLATE'EN-CI-AS'/*** SSC-PRF-0002 - CASE INSENSITIVE COLUMNS CAN DECREASE THE PERFORMANCE OF QUERIES ***/)COMMENT='{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}';
As you can see, the transformation of Collate inside a Select or a Table is the same.
When OUTER APPLY is specified, one row is produced for each row of the left rowset even when the right-side rowset expression returns an empty rowset for that row. (OUTER APPLY Definition)
Despite the unsupported statement OUTER APPLY in Snowflake, there is an equivalent statement, which is LATERAL. Hence, the translation for the statement is conducted to get the same functionality through the use of alternative solutions.
Nevertheless, the LATERAL statement in Snowflake has two variations in syntax. In fact, the INNER JOIN LATERAL variation is used in this specific translation.
The INNER JOIN LATERAL grammar from Snowflake is the following:
Since the translation is an equivalence from the input, there are some limitations.
TOP and WHERE statements may be reviewed for optimal behavior.
A correlation name at the end of the statement may be needed. In Snowflake, the query does not represent a problem if the correlation name is not in the query, but functionality may change and does not form part of the accepted pattern in SQL Server.
SELECT
SATT.UNIVERSAL_NAME
FROM
SAMPLE_ATLAS AS SATT
OUTERAPPLY(SELECTTOP1 UNIVERSAL_NAME,
INTERNATIONAL_NAME,
CODE_IDENTIFIER
FROM
SAMPLE_GLOBE AS SG
WHERE
SG.GLOBE_KEY = SATT.MbrPersGenKey
ORDERBY
GLOBE_KEY
);
SELECT
UNIVERSAL_NAME
FROM
SAMPLE_ATLAS
AS SATT
OUTERAPPLY/*** MSC-ERROR - MSCCP0001 - THE FOLLOWING SUBQUERY MATCHES AT LEAST ONE OF THE PATTERNS CONSIDERED INVALID AND MAY PRODUCE COMPILATION ERRORS ***/(SELECTTOP1
UNIVERSAL_NAME,
INTERNATIONAL_NAME,
CODE_IDENTIFIER
FROM
SAMPLE_GLOBE AS SG
WHERE
SG.GLOBE_KEY = SATT.MbrPersGenKey
ORDERBY GLOBE_KEY
);
Specific statements that are not supported may comment out all the block code (example taken from: JSON Example).
SELECT
SATT.UNIVERSAL_NAME
FROM
SAMPLE_ATLAS AS SATT
INNERJOINLATERAL(SELECTTOP1 UNIVERSAL_NAME,
INTERNATIONAL_NAME,
CODE_IDENTIFIER
FROM
SAMPLE_GLOBE AS SG
WHERE
SG.GLOBE_KEY = SATT.MbrPersGenKey
ORDERBY
GLOBE_KEY
);
SELECT
familyName,
c.givenName AS childGivenName,
c.firstName AS childFirstName,
p.givenName AS petName
FROMFamilies f
LEFTOUTERJOIN
OPENJSON(f.doc)/*** MSC-WARNING - MSCEWI4030 - Equivalence from CROSS APPLY to LEFT OUTER JOIN must be checked. ***/;-- ** MSC-ERROR - MSCEWI1001 - UNRECOGNIZED TOKEN ON LINE 7 OF THE SOURCE CODE. **-- WITH (familyName nvarchar(100), children nvarchar(max) AS JSON)-- CROSS APPLY OPENJSON(children)-- WITH (givenName nvarchar(100), firstName nvarchar(100), pets nvarchar(max) AS JSON) as c-- OUTER APPLY OPENJSON (pets)-- WITH (givenName nvarchar(100)) as p
The database name specified in the USE statement, could have a change if it comes inside Square Brackets([ ]). The first bracket and the last bracket will be replaced with quotes. Example:
If a user specifies to the Conversion Tool a custom database name to be applied to all the objects by using the -d parameter, and wants the USE statements to be transformed, the Database name should be applied just to the USE statement and not to the objects. This will override the specified database from the use statement. Example:
The Print statement is not directly supported in Snowflake, but it will be translated to its closest equivalent, the SYSTEM$LOG_INFO built-in function.
The SP_EXECUTESQL system stored procedure is used to execute a Transact-SQL statement or batch that can be reused many times, or one that is built dynamically. The statement or batch can contain embedded parameters.
This functionality can be emulated in Snowflake through the EXECUTE IMMEDIATE statement and with a user-defined function (UDF) for embedded parameters.
All patterns will transform SP_EXECUTESQL into Snowflake’s EXECUTE IMMEDIATE statement and only modify the SQL string to be executed when using embedded parameters.
Warning
SSC-EWI-0030 (Usage of Dynamic SQL) will be added for all patterns. Even though the translation for SP_EXECUTESQL is equivalent to Snowflake, in this context, this EWI indicates that the SQL string might require manual fixes for the translation to execute as intended.
When no embedded parameters are being used, the SP_EXECUTESQL is transformed into an EXECUTE IMMEDIATE statement and use the SQL string without modifications.
For embedded parameters for data binding, the SP_EXECUTESQL is transformed into an EXECUTE IMMEDIATE statement, and the SQL string is modified through the TRANSFORM_SP_EXECUTE_SQL_STRING_UDF.
The result of the EXECUTE IMMEDIATE is assigned to the ProcedureResultSet variable and later returned as TABLE(ProcedureResultSet).
For embedded OUTPUT parameters, the SP_EXECUTESQL is transformed into an EXECUTE IMMEDIATE statement, and the SQL string is modified through the TRANSFORM_SP_EXECUTE_SQL_STRING_UDF.
Additionally, a SELECT $1, ..., $n INTO :outputParam1, ..., :outputParamN FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())) is added to the result of each column to the corresponding OUTPUT parameter.
Warning
SSC-FDM-TS0028 is added to the SELECT INTO statement. It is essential for the parameters in the INTO clause to appear in the same order as they were assigned in the original SQL String.
Otherwise, manual changes are required to meet this requirement.
CREATEPROCEDURE QUERY_WITH_DIRECT_PARAMS_VALUES_ALL
ASBEGINDECLARE@MaxAge INT;DECLARE@MaxId INT;EXECUTE sp_executesql
N'SELECT @MaxAgeOUT = max(AGE), @MaxIdOut = max(ID) FROM PERSONS WHERE ID < @id AND AGE < @age;',
N'@age INT, @id INT, @MaxAgeOUT INT OUTPUT, @MaxIdOUT INT OUTPUT',30,100,@MaxAge OUTPUT,@MaxId OUTPUT;SELECT@MaxAge,@MaxId;END
GO
EXEC QUERY_WITH_DIRECT_PARAMS_VALUES_ALL;
This pattern follows the same rules as the previous patterns. However, assigning the result of the EXECUTE IMMEDIATE statement might not be added if the SQL string is not a simple single query with or without embedded parameters.
Furthermore, the SQL string must start with the literal value 'SELECT' for SnowConvert AI to correctly identify that a SELECT statement is going to be executed.
Snowflake Scripting procedures only allow one result set to be returned per procedure.
To replicate Transact-SQL behavior, when two or more result sets are to be returned, they are stored in temporary tables. The Snowflake Scripting procedure will return an array containing the names of the temporary tables. For more information, check SSC-FDM-0020.
SP_EXECUTESQL can execute more than one SQL statement inside the SQL string. Snowflake also supports executing multiple SQL statements, but need to be enclosed in a BEGIN ... END block.
Furthermore, when executing multiple statements from a BEGIN ... END block, the EXECUTE IMMEDIATE will not return a resultset.
The translation for these cases is not yet supported by SnowConvert AI.
For more information, check SSC-EWI-0030.
Thus, when this case is detected, in the translated code, the EXECUTE IMMEDIATE will not be assigned to the ProcedureResultSet.
000006(0A000): Uncaughtexceptionoftype'STATEMENT_ERROR'on line 10atposition4: MultipleSQL statements in a singleAPIcall are not supported;useoneAPIcallperstatement instead.
When the SQL string is built dynamically through concatenations, SnowConvert AI might not detect what statement is going to be executed. Thus, in the translated code, the EXECUTE IMMEDIATE will not be assigned to the ProcedureResultSet.
000006(0A000): Uncaughtexceptionoftype'STATEMENT_ERROR'on line 10atposition4: MultipleSQL statements in a singleAPIcall are not supported;useoneAPIcallperstatement instead.
If the SQL string starts with a SELECT statement and is followed by more statements, SnowConvert AI will detect this as a valid code and try to assign the result of the EXECUTE IMMEDIATE to the ProcedureResultSet. This leads to a compilation error.
For more information, check SSC-EWI-0030.
000006(0A000): Uncaughtexceptionoftype'STATEMENT_ERROR'on line 10atposition4: MultipleSQL statements in a singleAPIcall are not supported;useoneAPIcallperstatement instead.
Stored Procedure to Rename certain objects in SQL Server
Applies to
SQL Server
Azure Synapse Analytics
The SP_RENAME system store procedure can be emulated in Snowflake in certain scenarios. In general, the equivalent is the EXECUTE IMMEDIATE using a dynamic statement with the ALTER TABLE and the original parameters.
In SQL Server, WAITFOR DELAY pauses execution for a specified duration. SnowConvert AI transforms WAITFOR DELAY statements to Snowflake’s CALL SYSTEM$WAIT() function, which provides equivalent delay functionality.
The time string is parsed and converted to seconds (or milliseconds for sub-second precision). Variables and parameters are passed through directly with an EWI warning, since SYSTEM$WAIT expects a numeric value rather than a time string.
Note
WAITFOR TIME (which pauses until a specific time of day) has no Snowflake equivalent and remains flagged with SSC-EWI-0073.
CREATEORREPLACEPROCEDURE proc1 (WAITTIME INT)RETURNSVARCHARLANGUAGESQLEXECUTEASCALLERAS$$
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0094 - WAITFOR DELAY WITH VARIABLE ':WAITTIME' WAS CONVERTED TO SYSTEM$WAIT, BUT THE VARIABLE MAY CONTAIN A TIME STRING IN 'HH:MM:SS' FORMAT. SYSTEM$WAIT EXPECTS A NUMERIC VALUE IN SECONDS. ***/!!!
CALL SYSTEM$WAIT(:WAITTIME);
END;
$$;
WAITFOR TIME (pause until a specific time of day) has no Snowflake equivalent and is flagged with SSC-EWI-0073.
When a variable is used, SSC-EWI-TS0094 is emitted because SYSTEM$WAIT expects a numeric value but the variable may contain a time string in 'HH:MM:SS' format.
SnowConvert AI comments out CREATE STATISTICS statements because Snowflake automatically collects optimizer statistics and does not require this statement.
Any operational process that explicitly creates or refreshes statistics in SQL Server should be reviewed, because Snowflake manages optimizer statistics automatically.
Snowflake does not support synonyms. SnowConvert AI comments out CREATE SYNONYM statements with the SSC-FDM-TS0059 marker and replaces all references to the synonymn with the original base object name, so the generated Snowflake code is functionally equivalent.
----** SSC-FDM-TS0059 - SYNONYMS ARE NOT SUPPORTED IN SNOWFLAKE. REFERENCES TO THIS SYNONYM HAVE BEEN REPLACED WITH THE ORIGINAL OBJECT NAME. **--CREATE SYNONYM MyProduct FOR inventory.product;
----** SSC-FDM-TS0059 - SYNONYMS ARE NOT SUPPORTED IN SNOWFLAKE. REFERENCES TO THIS SYNONYM HAVE BEEN REPLACED WITH THE ORIGINAL OBJECT NAME. **--CREATE SYNONYM MyProduct FOR inventory.product;SELECT*FROM
inventory.product;