SnowConvert: SQLServer Issues¶
SSC-EWI-TS0060¶
Severity¶
Medium
Description¶
This EWI is added when one of the following time parts is used as a parameter for a date-related function because they are not supported in Snowflake. For more information go to ‘supported date time parts (Date & Time Functions | Snowflake Documentation).
Code Example¶
Input code¶
SELECT
-- Supported
DATEPART(second, getdate()),
-- Not supported
DATEPART(millisecond, getdate()),
DATEPART(microsecond, getdate());
Output code:¶
SELECT
-- Supported
DATE_PART(second, CURRENT_TIMESTAMP() :: TIMESTAMP),
-- Not supported
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0060 - TIME PART 'millisecond' NOT SUPPORTED AS A FUNCTION PARAMETER ***/!!!
DATEPART(millisecond, CURRENT_TIMESTAMP() :: TIMESTAMP),
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0060 - TIME PART 'microsecond' NOT SUPPORTED AS A FUNCTION PARAMETER ***/!!!
DATEPART(microsecond, CURRENT_TIMESTAMP() :: TIMESTAMP);
Recommendations¶
An UDF could be created to manually extract unsupported time parts in Snowflake.
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0070¶
This EWI
is deprecated, please refer to SSC-FDM-TS0024 documentation.
Description¶
This EWI is added when the At Time Zone has the CURRENT_TIMESTAMP. This is because the result may have different results in some instances.
The main difference is that in SQL Server, CURRENT_TIMESTAMP returns the current system date and time in the server time zone and in Snowflake CURRENT_TIMESTAMP returns the current date and time in the UTC (Coordinated Universal Time) time zone.
Input Code:¶
SELECT current_timestamp at time zone 'Hawaiian Standard Time';
2024-02-08 16:52:55.317 -10:00
Output Code:¶
SELECT
CONVERT_TIMEZONE('Pacific/Honolulu', CURRENT_TIMESTAMP() !!!RESOLVE EWI!!! /*** SSC-EWI-TS0070 - CURRENT_TIMESTAMP in At Time Zone statement may have a different behavior in certain cases ***/!!!);
2024-02-08 06:53:46.994 -1000
Recommendations¶
This is an example if you want to keep the same format in Snowflake.
SELECT current_timestamp at time zone 'Hawaiian Standard Time';
2024-02-08 16:33:49.143 -10:00
In Snowflake you can use ALTER SESSION to change the default time zone. For example:
ALTER SESSION SET TIMEZONE = 'Pacific/Honolulu';
SELECT
CONVERT_TIMEZONE('Pacific/Honolulu', 'UTC', CURRENT_TIMESTAMP());
2024-02-08 16:33:49.143
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0044¶
Severity¶
Critical
Some parts of the output code are omitted for clarity reasons.
Description¶
This EWI is added for the FOR XML (https://docs.microsoft.com/en-us/sql/relational-databases/xml/for-xml-sql-server?view=sql-server-ver15)clause which is not supported in Snowflake SQL
Code Example¶
Input Code:¶
SELECT TOP 1 LastName
FROM AdventureWorks2019.Person.Person
FOR XML AUTO;
Output Code:¶
SELECT TOP 1
LastName
FROM
AdventureWorks2019.Person.Person
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0044 - FOR XML AUTO CLAUSE IS NOT SUPPORTED IN SNOWFLAKE ***/!!!
FOR XML AUTO;
Recommendations¶
Consider using UDFs to emulate the behavior of the source code. The following code provides suggestions of UDFs that can be used to achieve recreating the original behavior:
SQL Server
CREATE TABLE TEMPTABLE (Ref INT, Des NVARCHAR(100), Qty INT)
INSERT INTO tempTable VALUES (100001, 'Normal', 1), (100002, 'Foobar', 1), (100003, 'Hello World', 2)
GO
-- FOR XML
SELECT *
FROM TempTable
FOR XML AUTO
GO
-- FOR XML RAW
SELECT *
FROM TempTable
FOR XML RAW
-- FOR XML
<TempTable Ref="100001" Des="Normal" Qty="1"/><TempTable Ref="100002" Des="Foobar" Qty="1"/><TempTable Ref="100003" Des="Hello World" Qty="2"/>
-- FOR XML RAW
<row Ref="100001" Des="Normal" Qty="1"/><row Ref="100002" Des="Foobar" Qty="1"/><row Ref="100003" Des="Hello World" Qty="2"/>
Snowflake¶
CREATE OR REPLACE TABLE TEMPTABLE (
Ref INT,
Des VARCHAR(100),
Qty INT
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
;
INSERT INTO tempTable VALUES (100001, 'Normal', 1), (100002, 'Foobar', 1), (100003, 'Hello World', 2);
-- FOR XML
SELECT
*
FROM
TempTable
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0044 - FOR XML AUTO CLAUSE IS NOT SUPPORTED IN SNOWFLAKE ***/!!!
FOR XML AUTO;
-- FOR XML RAW
SELECT
*
FROM
TempTable
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0044 - FOR XML RAW CLAUSE IS NOT SUPPORTED IN SNOWFLAKE ***/!!!
FOR XML RAW;
-- FOR XML
<TempTable DES="Normal" QTY="1" REF="100001" /><TempTable DES="Foobar" QTY="1" REF="100002" /><TempTable DES="Hello World" QTY="2" REF="100003" />
-- FOR XML RAW
<row DES="Normal" QTY="1" REF="100001" /><row DES="Foobar" QTY="1" REF="100002" /><row DES="Hello World" QTY="2" REF="100003" />
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0035¶
Severity¶
Medium
Some parts of the output code are omitted for clarity reasons.
Description¶
Currently, a Cursor Variable that is declared but never initialized is not supported by SnowFlake. Thus, the EWI is added, and the code commented out.
Code Example¶
Input Code:¶
CREATE OR ALTER PROCEDURE notInitializedCursorTest
AS
BEGIN
-- Should be marked with SSC-EWI-TS0035
DECLARE @MyCursor CURSOR, @MyCursor2 CURSOR;
-- Should not be marked
DECLARE cursorVar CURSOR FORWARD_ONLY STATIC READ_ONLY
FOR
SELECT someCol
FROM someTable;
RETURN 'DONE';
END;
Output Code:¶
CREATE OR REPLACE PROCEDURE notInitializedCursorTest ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
-- Should be marked with SSC-EWI-TS0035
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0035 - CURSOR VARIABLE DECLARED BUT NEVER INITIALIZED, THIS IS NOT SUPPORTED IN SNOWFLAKE SCRIPTING ***/!!!
MYCURSOR CURSOR;
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0035 - CURSOR VARIABLE DECLARED BUT NEVER INITIALIZED, THIS IS NOT SUPPORTED IN SNOWFLAKE SCRIPTING ***/!!!
MYCURSOR2 CURSOR;
-- Should not be marked
cursorVar CURSOR
FOR
SELECT
someCol
FROM
someTable;
BEGIN
RETURN 'DONE';
END;
$$;
Recommendations¶
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0001¶
Severity¶
Critical
Some parts of the output code are omitted for clarity reasons.
Description¶
This EWI appears when SnowConvert handles a critical exception that causes the function body not to be generated during its translation.
Example Code¶
SQL Server¶
CREATE FUNCTION func1 ()
RETURNS VARCHAR
SELECT
*
FROM
TABLE1
Snowflake¶
CREATE OR REPLACE FUNCTION func1 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0001 - THE BODY WAS NOT GENERATED FOR FUNCTION 'func1' ***/!!!
AS
$$
$$;
Recommendations¶
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0025¶
Severity¶
Low
Generate Procedures and Macros using JavasScript as the target language adding the following flag -t JavaScript or –PLTargetLanguage JavaScript
Some parts of the output code are omitted for clarity reasons.
Description¶
This EWI is added when ERROR_SEVERITY (https://docs.microsoft.com/en-us/sql/t-sql/functions/error-severity-transact-sql?view=sql-server-ver15)built-in function is translated. By default, the function will return 16 as it is the most common severity in SQL Server. The generated UDF should retrie
Code Example¶
Input Code:¶
-- Additional Params: -t JavaScript
CREATE procedure proc1()
as
BEGIN TRY
-- Generate a divide-by-zero error.
SELECT 1/0 from table1;
END TRY
BEGIN CATCH
return ERROR_SEVERITY();
END CATCH;
GO
Output Code:¶
CREATE OR REPLACE PROCEDURE proc1 ()
RETURNS STRING
LANGUAGE JAVASCRIPT
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
// SnowConvert Helpers Code section is omitted.
try {
EXEC(` -- Generate a divide-by-zero error.
SELECT
TRUNC( 1/0) from
table1`);
} catch(error) {
return SELECT(` !!!RESOLVE EWI!!! /*** SSC-EWI-TS0025 - CUSTOM UDF 'ERROR_SEVERITY_UDF' INSERTED FOR ERROR_SEVERITY FUNCTION. ***/!!!
ERROR_SEVERITY_UDF()`);
}
$$;
Recommendations¶
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0074¶
Severity¶
Low
Some parts of the output code are omitted for clarity reasons.
Description¶
This EWI is added in the transformation of TRY_CAST and TRY_CONVERT functions. The exact result of these functions may change in Snowflake due to missing dependencies (SnowConvert couldn’t resolve some data types). This could be because the dependency was not in the source code.
Input Code:¶
SELECT TRY_CONVERT( INT, col1) FROM TABLE1;
SELECT TRY_CAST(COL1 AS FLOAT) FROM TABLE1
Output Code¶
SELECT
CAST(col1 AS INT) /*** SSC-FDM-TS0005 - TRY_CONVERT/TRY_CAST COULD NOT BE CONVERTED TO TRY_CAST ***/!!!RESOLVE EWI!!! /*** SSC-EWI-TS0074 - CAST RESULT MAY BE DIFFERENT FROM TRY_CONVERT FUNCTION DUE TO MISSING DEPENDENCIES ***/!!!
FROM
TABLE1;
SELECT
CAST(COL1 AS FLOAT) /*** SSC-FDM-TS0005 - TRY_CONVERT/TRY_CAST COULD NOT BE CONVERTED TO TRY_CAST ***/!!!RESOLVE EWI!!! /*** SSC-EWI-TS0074 - CAST RESULT MAY BE DIFFERENT FROM TRY_CAST FUNCTION DUE TO MISSING DEPENDENCIES ***/!!!
FROM
TABLE1;
Recommendation¶
If you need more support, you can email us at snowconvert-support@snowflake.com.
SSC-EWI-TS0034¶
Severity¶
High
Description¶
This EWI is added to the output code when the RETURNS TABLE
clause of a CREATE FUNCTION
could not be properly generated. This happens when the columns that must be specified in the resulting RETURNS TABLE
clause cannot be inferred by SnowConvert, thus leaving the RETURNS TABLE
clause empty.
Code Example¶
Input Code:¶
CREATE FUNCTION Sales.ufn_SalesByStore2()
RETURNS TABLE
AS
RETURN
(
WITH CTE AS (
SELECT DepartmentID, Name, GroupName
FROM HumanResources.Department
)
SELECT tab.* FROM CTE tab
);
GO
SELECT * FROM GetDepartmentInfo();
Output Code:¶
CREATE OR REPLACE FUNCTION Sales.ufn_SalesByStore2 ()
RETURNS TABLE(
DepartmentID STRING /*** SSC-FDM-TS0012 - INFORMATION FOR THE COLUMN DepartmentID WAS NOT FOUND. STRING DATATYPE USED TO MATCH CAST AS STRING OPERATION ***/,
Name STRING /*** SSC-FDM-TS0012 - INFORMATION FOR THE COLUMN Name WAS NOT FOUND. STRING DATATYPE USED TO MATCH CAST AS STRING OPERATION ***/,
GroupName STRING /*** SSC-FDM-TS0012 - INFORMATION FOR THE COLUMN GroupName WAS NOT FOUND. STRING DATATYPE USED TO MATCH CAST AS STRING OPERATION ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
AS
$$
--** SSC-PRF-TS0001 - PERFORMANCE WARNING - RECURSION FOR CTE NOT CHECKED. MIGHT REQUIRE RECURSIVE KEYWORD **
WITH CTE AS (
SELECT
DepartmentID,
Name,
GroupName
FROM
HumanResources.Department
)
SELECT tab.* FROM
CTE tab
$$;
SELECT
*
FROM GetDepartmentInfo() !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'TableValuedFunctionCall' NODE ***/!!!;
Recommendations¶
The causes for this issue may vary. Be sure to include all the objects that your code needs. If the issue persists even though the migration has access to all the necessary objects, please do contact us with information about your specific scenario.
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0041¶
Severity¶
Medium
Description¶
This EWI is added for the following XML data type methods (https://docs.microsoft.com/en-us/sql/t-sql/xml/xml-data-type-methods?view=sql-server-ver15) that are not supported in Snowflake SQL:
Value
Query
Exist
Modify
Nodes
Code Example¶
Input Code:¶
CREATE PROCEDURE xml_procedure
@inUserGroupsXML XML
AS
BEGIN
SELECT entities.entity.value('TypeID[1]', 'VARCHAR(100)') AS TypeID
,entities.entity.value('Name[1]', 'VARCHAR(100)') AS Name
INTO #tmpUserGroups
FROM @inUserGroupsXML.nodes('/entities/entity') entities(entity)
END;
Output Code:¶
CREATE OR REPLACE PROCEDURE xml_procedure (INUSERGROUPSXML TEXT)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
CREATE OR REPLACE TEMPORARY TABLE T_tmpUserGroups AS
SELECT
XMLGET(entity, '$') :: VARCHAR(100) AS TypeID
,
XMLGET(entity, '$') :: VARCHAR(100) AS Name
FROM
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0041 - XML TYPE METHOD nodes IS NOT SUPPORTED IN SNOWFLAKE ***/!!!
T_inUserGroupsXML('/entities/entity') entities (
entity
);
END;
$$;
Recommendations¶
Consider using UDFs to emulate the behavior of the source code
You can check this documentation (link removed) and review some possible approaches to work with XML datatypes in Snowflake.
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0010¶
Some parts in the output code are omitted for clarity reasons.
Severity¶
High
Description¶
This error is added when an invalid CTE is inside a view since views are materialized representations of queries, which means that they only define how data is retrieved and presented, not how it is manipulated.
Code Example¶
Input Code:¶
Create View viewName
as
with commonTableExpressionName (
columnName
) as
(
select
1
)
((select
1 as col2)
union
(
select
1 as col3
));
Output Code:¶
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0010 - COMMON TABLE EXPRESSION IN VIEW NOT SUPPORTED IN SNOWFLAKE. ***/!!!
CREATE OR REPLACE VIEW viewName
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
AS
!!!RESOLVE EWI!!! /*** SSC-EWI-0021 - WITH CTE NOT SUPPORTED IN SNOWFLAKE ***/!!!
with commonTableExpressionName (
columnName
) as
(
select
1
)
((select
1 as col2)
union
(
select
1 as col3
));
Recommendations¶
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0024¶
Severity¶
Low
Description¶
This EWI is added when a BULK INSERT
inside a stored procedure was not identified at all, so the dependencies for the complete transformation will not be generated. Also the transformed COPY INTO
retrieves the file from a tempStage
that needs to be created manually.
Code Example¶
Input Code:¶
CREATE PROCEDURE BULK_PROC2
AS
BULK INSERT dbo.table1 FROM 'E:\test.txt'
WITH
(
FIELDTERMINATOR ='\t',
ROWTERMINATOR ='\n'
);
GO
Output Code:¶
CREATE OR REPLACE FILE FORMAT FILE_FORMAT_638461207064166040
FIELD_DELIMITER = '\t'
RECORD_DELIMITER = '\n';
CREATE OR REPLACE STAGE STAGE_638461207064166040
FILE_FORMAT = FILE_FORMAT_638461207064166040;
--** SSC-FDM-TS0004 - PUT STATEMENT IS NOT SUPPORTED ON WEB UI. YOU SHOULD EXECUTE THE CODE THROUGH THE SNOWFLAKE CLI **
PUT file://E:\test.txt @STAGE_638461207064166040 AUTO_COMPRESS = FALSE;
CREATE OR REPLACE PROCEDURE BULK_PROC2 ()
RETURNS STRING
LANGUAGE JAVASCRIPT
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
// REGION SnowConvert Helpers Code
// END REGION
EXEC(`COPY INTO dbo.table1 FROM @STAGE_638461207064166040/test.txt`);
$$
Recommendations¶
Create a STAGE and a FILE FORMAT manually in order to retrieve the file.
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0075¶
Severity¶
Medium
Description¶
Translation for built-in procedures is not currently supported.
Example Code¶
Input Code:¶
EXEC sp_column_privileges_rowset_rmt 'Caption';
Output Code:¶
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0075 - TRANSLATION FOR BUILT-IN PROCEDURE 'sp_column_privileges_rowset_rmt' IS NOT CURRENTLY SUPPORTED. ***/!!!
EXEC sp_column_privileges_rowset_rmt 'Caption';
Recommendations¶
No end-user actions are required.
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0055¶
This EWI is deprecated, please refer to SSC-FDM-TS0020 documentation.
Severity¶
Medium
Description¶
This EWI is added when the default constraint is present in an Alter Table statement.
Currently, there is no support for that constraint. A workaround available to transform it, is when the table is previously defined to the Alter Table, in this way we identify the references, and the default constraint is unified on the table definition; otherwise, the constraint is only commented out.
Code Example¶
Input Code:¶
CREATE TABLE table1(
col1 integer,
col2 varchar collate Latin1_General_CS,
col3 date
);
ALTER TABLE table1
ADD col4 integer,
CONSTRAINT col1_constraint DEFAULT 50 FOR col1,
CONSTRAINT col1_constraint DEFAULT 30 FOR col1;
Output Code:¶
CREATE OR REPLACE TABLE table1 (
col1 INTEGER DEFAULT 50,
col2 VARCHAR COLLATE 'EN-CS',
col3 DATE
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
;
ALTER TABLE table1
ADD col4 INTEGER,
CONSTRAINT col1_constraint
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0055 - DEFAULT CONSTRAINT MAY HAVE BEEN ADDED TO TABLE DEFINITION ***/!!!
DEFAULT 50 FOR col1,
CONSTRAINT col1_constraint
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0055 - DEFAULT CONSTRAINT MAY HAVE BEEN ADDED TO TABLE DEFINITION ***/!!!
DEFAULT 30 FOR col1;
If all the content of the Alter Table is invalid, the Alter Table will be commented out.
Known Issues¶
When different default constraints are declared over the same column, only the first will be reflected on the Create Table Statement.
Recommendations¶
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0061¶
Severity¶
Medium
Some parts of the output code are omitted for clarity reasons.
Description¶
This EWI is added whenever there is an unsupported ALTER COLUMN statement
Code Example¶
Input Code:¶
ALTER TABLE SampleTable
ALTER COLUMN SampleColumn INT NULL SPARSE;
Output Code:¶
ALTER TABLE IF EXISTS SampleTable
ALTER COLUMN SampleColumn
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0061 - ALTER COLUMN COMMENTED OUT BECAUSE SPARSE COLUMN IS NOT SUPPORTED IN SNOWFLAKE ***/!!!
INT NULL SPARSE;
Recommendations¶
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0045¶
Severity¶
Low
Some parts of the output code are omitted for clarity reasons.
Description¶
This EWI is added for all the LABELS used with the GOTO (https://docs.microsoft.com/en-us/sql/t-sql/language-elements/goto-transact-sql?view=sql-server-ver15)statement in SQL Server.
Code Example¶
Input Code:¶
CREATE PROCEDURE GoToProcedure
AS
BEGIN
DECLARE @TotalMaarks INT
SET @TotalMaarks = 49
IF @TotalMaarks >= 50
GOTO Pass
IF @TotalMaarks < 50
GOTO Fail
Pass:
SELECT 1;
SELECT * FROM TABLE1;
RETURN 1;
Fail:
SELECT 2;
SELECT * FROM TABLE2;
RETURN 2;
END
Output Code:¶
CREATE OR REPLACE PROCEDURE GoToProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
TOTALMAARKS INT;
BEGIN
TOTALMAARKS := 49;
IF (:TOTALMAARKS >= 50) THEN
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'GOTO' NODE ***/!!!
GOTO Pass
END IF;
IF (:TOTALMAARKS < 50) THEN
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'GOTO' NODE ***/!!!
GOTO Fail
END IF;
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0045 - LABELED STATEMENT IS NOT SUPPORTED IN SNOWFLAKE SCRIPTING ***/!!!
Pass:
SELECT 1;
SELECT
*
FROM
TABLE1;
RETURN 1;
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0045 - LABELED STATEMENT IS NOT SUPPORTED IN SNOWFLAKE SCRIPTING ***/!!!
Fail:
SELECT 2;
SELECT
*
FROM
TABLE2;
RETURN 2;
END;
$$;
Recommendations¶
If you need more support, you can email us at snowconvert-support@snowflake.com
Related EWI¶
SSC-EWI-0073: Pending Functional Equivalence Review.
SSC-EWI-TS0009¶
Some parts in the output code are omitted for clarity reasons.
Severity¶
High
Description¶
This error is added to indicate when a transaction may contain nested transactions. In SQL Server, transactions can be nested. This means that it is possible to start a new transaction within an existing transaction. If after the first BEGIN statement, we execute another one, a new transaction will be opened and the current transaction count will be increased by one.\
On the other hand this is not supported in Snowflake, what will happen is that the second BEGIN statement will be ignored and we will still have only one transaction. For more information please refer to SQL Server Transactions (https://learn.microsoft.com/en-us/sql/t-sql/language-elements/transactions-transact-sql?view=sql-server-ver16).
Code Example¶
Input Code:¶
CREATE PROC transactionsTest
AS
BEGIN TRANSACTION
SELECT @@TRANCOUNT AS TransactionCount_AfterFirstTransaction
INSERT INTO TESTSCHEMA.TESTTABLE(ID) VALUES (1), (2)
BEGIN TRANSACTION
SELECT @@TRANCOUNT AS TransactionCount_AfterSecondTransaction
INSERT INTO TESTSCHEMA.TESTTABLE(ID) VALUES (3), (4)
COMMIT;
SELECT @@TRANCOUNT AS TransactionCount_AfterFirstCommit
COMMIT;
END;
Output Code:¶
CREATE OR REPLACE PROCEDURE transactionsTest ()
RETURNS ARRAY
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
ProcedureResultSet1 VARCHAR;
ProcedureResultSet2 VARCHAR;
ProcedureResultSet3 VARCHAR;
return_arr ARRAY := array_construct();
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0009 - THE FOLLOWING TRANSACTION MAY CONTAIN NESTED TRANSACTIONS WHICH ARE NOT SUPPORTED IN SNOWFLAKE. ***/!!!
BEGIN TRANSACTION;
ProcedureResultSet1 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:ProcedureResultSet1) AS
SELECT
:TRANCOUNT AS TransactionCount_AfterFirstTransaction;
return_arr := array_append(return_arr, :ProcedureResultSet1);
INSERT INTO TESTSCHEMA.TESTTABLE (ID) VALUES (1), (2);
BEGIN TRANSACTION;
ProcedureResultSet2 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:ProcedureResultSet2) AS
SELECT
:TRANCOUNT AS TransactionCount_AfterSecondTransaction;
return_arr := array_append(return_arr, :ProcedureResultSet2);
INSERT INTO TESTSCHEMA.TESTTABLE (ID) VALUES (3), (4);
COMMIT;
ProcedureResultSet3 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:ProcedureResultSet3) AS
SELECT
:TRANCOUNT AS TransactionCount_AfterFirstCommit;
return_arr := array_append(return_arr, :ProcedureResultSet3);
COMMIT;
--** SSC-FDM-0020 - MULTIPLE RESULT SETS ARE RETURNED IN TEMPORARY TABLES **
RETURN return_arr;
END;
$$;
-- ** SSC-EWI-0001 - UNRECOGNIZED TOKEN ON LINE '12' COLUMN '1' OF THE SOURCE CODE STARTING AT 'END'. EXPECTED 'BATCH' GRAMMAR. CODE '80'. **
--END
!!!RESOLVE EWI!!! /*** SSC-EWI-0040 - THE STATEMENT IS NOT SUPPORTED IN SNOWFLAKE ***/!!!
;
Recommendations¶
In Snowflake nested transactions will not cause compilation errors, they will simply be ignored. You can access the assessment reports to check if nested transactions are present.
If you need more support, you can email us at snowconvert-support@snowflake.com
Related EWI¶
SSC-FDM-0020: Multiple result sets are returned in temporary tables
SSC-EWI-0001: Unrecognized token on the line of the source code.
SSC-EWI-0040: Statement Not Supported.
SSC-EWI-TS0039¶
Severity¶
Medium
Description¶
This EWI is added when multiple SET Statements for the same cursor are found; All additional SET Statements are also commented out. This happens because having multiple SET Statements for the same cursor is not valid in Snowflake Scripting.
Example Code:¶
This EWI is added when multiple SET Statements for the same cursor are found; All additional SET Statements are also commented out. This happens because having multiple SET Statements for the same cursor is not valid in Snowflake Scripting.¶
Example Code:¶
Input Code:¶
CREATE OR ALTER PROCEDURE multipleSetExample
AS
BEGIN
DECLARE @MyCursor CURSOR;
DECLARE @MyCursor2 CURSOR STATIC READ_ONLY
FOR
SELECT FirstName
FROM vEmployee;
DECLARE @MyCursor3 CURSOR;
SET @MyCursor = CURSOR STATIC READ_ONLY
FOR
SELECT col3
FROM defaultTable;
SET @MyCursor3 = CURSOR STATIC READ_ONLY
FOR
SELECT *
FROM someTable;
SET @MyCursor = CURSOR DYNAMIC
FOR
SELECT col2
FROM exampleTable;
SET @MyCursor2 = CURSOR STATIC READ_ONLY
FOR
SELECT col3
FROM defaultTable;
RETURN 'DONE';
END;
Output Code:¶
CREATE OR REPLACE PROCEDURE multipleSetExample ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
MYCURSOR CURSOR
FOR
SELECT col3
FROM defaultTable;
MYCURSOR2 CURSOR
FOR
SELECT
FirstName
FROM
vEmployee;
MYCURSOR3 CURSOR
FOR
SELECT *
FROM someTable;
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0040 - THE STATEMENT IS NOT SUPPORTED IN SNOWFLAKE ***/!!!!!!RESOLVE EWI!!! /*** SSC-EWI-TS0039 - CURSOR VARIABLE MYCURSOR SET MULTIPLE TIMES, THIS IS NOT VALID IN SNOWFLAKE SCRIPTING ***/!!!
SET @MyCursor = CURSOR DYNAMIC
FOR
SELECT col2
FROM exampleTable;
!!!RESOLVE EWI!!! /*** SSC-EWI-0040 - THE STATEMENT IS NOT SUPPORTED IN SNOWFLAKE ***/!!!!!!RESOLVE EWI!!! /*** SSC-EWI-TS0039 - CURSOR VARIABLE MYCURSOR2 SET MULTIPLE TIMES, THIS IS NOT VALID IN SNOWFLAKE SCRIPTING ***/!!!
SET @MyCursor2 = CURSOR STATIC READ_ONLY
FOR
SELECT col3
FROM defaultTable;
RETURN 'DONE';
END;
$$;
Recommendations¶
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0078¶
Severity¶
Medium
Description¶
This error is added to the code when expressions like function calls, variable names, or named constants follow the default option.
Snowflake only supports explicit constants like numbers or strings.
Code Example¶
Input Code:¶
ALTER TABLE
T_ALTERTABLETEST
ADD
COLUMN COL10 INTEGER DEFAULT RANDOM(10);
Output Code:¶
--** SSC-FDM-0007 - MISSING DEPENDENT OBJECTS "T_ALTERTABLETEST", "RANDOM" **
ALTER TABLE IF EXISTS T_ALTERTABLETEST
ADD
COLUMN COL10 INTEGER
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0078 - DEFAULT OPTION NOT ALLOWED IN SNOWFLAKE ***/!!!
DEFAULT RANDOM(10);
¶
Recommendations¶
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0079¶
Severity¶
Medium
Description¶
This EWI is added when SnowConvert finds a DBCC statement inside the input code.
Most DBCC statements are not supported in Snowflake.
Code Example¶
Input Code:¶
DBCC CHECKIDENT(@a, RESEED, @b) WITH NO_INFOMSGS
Output Code:¶
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0079 - DATABASE CONSOLE COMMAND 'CHECKIDENT' IS NOT SUPPORTED. ***/!!!
DBCC CHECKIDENT(@a, RESEED, @b) WITH NO_INFOMSGS;
Recommendations¶
No additional user actions are required; it is just informative.
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0049¶
Some parts in the output code are omitted for clarity reasons.
Severity¶
Medium
Description¶
Most of the cases inIF
statements that contain a Begin ... End
block inside their body are supported. This is a successful scenario (no SSC-EWI-TS0049 generated).
Code Example¶
Input Code:¶
CREATE OR ALTER FUNCTION [PURCHASING].[FOO](@status INT)
Returns INT
As
Begin
declare @result as int = 10;
SELECT @result = quantity FROM TABLE1 WHERE COL1 = @status;
IF @result = 3
BEGIN
IF @result>0 SELECT @result=0 ELSE SELECT @result=1
SELECT @result = 1
END
return @result;
End
Output Code:¶
--** SSC-FDM-0029 - USER DEFINED FUNCTION WAS TRANSFORMED TO SNOWFLAKE PROCEDURE **
CREATE OR REPLACE PROCEDURE PURCHASING.FOO (STATUS INT)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
RESULT INT := 10;
BEGIN
SELECT
quantity
INTO
:RESULT
FROM
TABLE1
WHERE
COL1 = :STATUS;
IF (:RESULT = 3) THEN
BEGIN
IF (:RESULT >0) THEN SELECT
0
INTO
:RESULT;
ELSE
SELECT
1
INTO
:RESULT;
END IF;
SELECT
1
INTO
:RESULT;
END;
END IF;
RETURN :RESULT;
END;
$$;
In a general code example (Like the on top) the conversion is done successfully. But there are some edge cases where the “IF” statement is not converted and the EWI will be generated.
Manual Support¶
Case 1: Single Statement¶
For these cases, the transformation would be straightforward, since the transformed statement would appear in a select clause
IF @result = 0
BEGIN
SET @result =1
END
CASE WHEN (SELECT RESULT FROM CTE2)= 0 THEN
( SELECT 1 AS RESULT )
Case 2: Multiple Statements¶
For cases in which multiple statements are being transformed, we should transform the N Statement, and use it as the source table for the N+1 Statement.
IF @result = 0
BEGIN
Statement1
Statement2
Statement3
END
CASE WHEN (SELECT RESULT FROM CTE2)= 0 THEN
(
SELECT TransformedStatement3
FROM (
SELECT TransformedStatement2
FROM (
SELECT TransformedStatement1
) T1
) T2
)
Case 3: Multiple set statements¶
For these cases, it will be necessary to replicate a transformation for each set statement.
IF @result = 0
BEGIN
SET @var1 = 1
SET @var2 = 3
SET @var3 = @var2
END
WITH CTE1 AS (
SELECT
CASE WHEN (SELECT
RESULT
FROM
CTE0) = 0 THEN
(SELECT 1) AS VAR1)
WITH CTE2 AS (
SELECT
CASE WHEN (SELECT
RESULT
FROM
CTE0)= 0 THEN
(SELECT 3) AS VAR2)
WITH CTE3 AS (
SELECT
CASE WHEN (SELECT
RESULT
FROM
CTE0)= 0 THEN
(SELECT T1.VAR2
FROM ((SELECT 3) AS VAR2) AS T1) AS VAR3)
...
Recommendations¶
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0037¶
Severity¶
Medium
Some parts of the output code are omitted for clarity reasons.
Description¶
Snowflake Scripting Cursors are non-scrollable. Currently, only FETCH NEXT is supported.
Code Example¶
Input Code:¶
CREATE OR ALTER PROCEDURE scrollablecursorTest
AS
BEGIN
-- Should be marked with SSC-EWI-TS0037
DECLARE CursorVar CURSOR SCROLL STATIC READ_ONLY
FOR
SELECT FirstName
FROM vEmployee;
-- Should not be marked
DECLARE CursorVar2 CURSOR STATIC READ_ONLY
FOR
SELECT FirstName
FROM vEmployee;
DECLARE CursorVar3 CURSOR FORWARD_ONLY STATIC READ_ONLY
FOR
SELECT FirstName
FROM vEmployee;
RETURN 'DONE';
END;
Output Code:¶
CREATE OR REPLACE PROCEDURE scrollablecursorTest ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
-- Should be marked with SSC-EWI-TS0037
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0037 - SNOWFLAKE SCRIPTING CURSORS ARE NON-SCROLLABLE, ONLY FETCH NEXT IS SUPPORTED ***/!!!
CursorVar CURSOR
FOR
SELECT
FirstName
FROM
vEmployee;
-- Should not be marked
CursorVar2 CURSOR
FOR
SELECT
FirstName
FROM
vEmployee;
CursorVar3 CURSOR
FOR
SELECT
FirstName
FROM
vEmployee;
BEGIN
RETURN 'DONE';
END;
$$;
Recommendations¶
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0013¶
This EWI is deprecated, please refer to SSC-FDM-TS0013 documentation
Severity¶
Low
Description¶
This warning is added when an SQL Server computed column is transformed to its Snowflake equivalent. It is added because, in some cases, the functional equivalence could be affected.
Code Example¶
Input Code:¶
CREATE TABLE [TestTable](
[Col1] AS (CONVERT ([REAL], ExpressionValue))
);
Output Code:¶
CREATE OR REPLACE TABLE TestTable (
Col1 REAL AS (CAST(ExpressionValue AS REAL)) /*** SSC-FDM-TS0014 - COMPUTED COLUMN WAS TRANSFORMED TO ITS SNOWFLAKE EQUIVALENT, FUNCTIONAL EQUIVALENCE VERIFICATION PENDING. ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
;
Recommendations¶
No additional user actions are required; it is just informative.
Add manual changes to the not-transformed expression.
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0076¶
This EWI is deprecated, please refer to SSC-EWI-0002 documentation
Severity¶
Medium
Description¶
Default parameters may need to be reordered. Snowflake only supports default parameters at the end of the parameters declarations.
Example Code¶
Input Code:¶
CREATE PROCEDURE MySampleProc
@Param1 NVARCHAR(50) = NULL,
@Param2 NVARCHAR(10),
@Param3 NVARCHAR(10) = NULL,
@Param4 NVARCHAR(10)
AS
SELECT 1;
Output Code:¶
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0076 - DEFAULT PARAMETERS MAY NEED TO BE REORDERED. SNOWFLAKE ONLY SUPPORTS DEFAULT PARAMETERS AT THE END OF THE PARAMETERS DECLARATIONS. ***/!!!
CREATE OR REPLACE PROCEDURE MySampleProc (PARAM1 STRING DEFAULT NULL, PARAM2 STRING, PARAM3 STRING DEFAULT NULL, PARAM4 STRING)
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
ProcedureResultSet RESULTSET;
BEGIN
ProcedureResultSet := (
SELECT 1);
RETURN TABLE(ProcedureResultSet);
END;
$$;
Recommendations¶
No end-user actions are required.
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0056¶
This EWI is deprecated, please refer to SSC-FDM-TS0021 documentation
Severity¶
Low
Some parts of the output code are omitted for clarity reasons.
Description¶
This EWI is added when the Alter Table statement contains a MASKED WITH clause. The reason this is added is to inform that an approximate MASKING POLICY was created as a substitute for the MASKED WITH function.
Code Example¶
Input Code:¶
ALTER TABLE table_name
ALTER COLUMN column_name
ADD MASKED WITH (FUNCTION = 'default()');
Output Code:¶
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0057 - MASKING ROLE MUST BE DEFINED PREVIOUSLY BY THE USER ***/!!!
CREATE OR REPLACE MASKING POLICY "default" AS
(val STRING)
RETURNS STRING ->
CASE
WHEN current_role() IN ('YOUR_DEFINED_ROLE_HERE')
THEN val
ELSE 'xxxxx'
END;
ALTER TABLE IF EXISTS table_name MODIFY COLUMN column_name!!!RESOLVE EWI!!! /*** SSC-EWI-TS0056 - A MASKING POLICY WAS CREATED AS SUBSTITUTE FOR MASKED WITH ***/!!! SET MASKING POLICY "default";
The MASKING POLICY will be created previous to the ALTER TABLE statement. And it is expected to have and approximate behaviour. Some tweaks might be needed in regards to roles and user privileges.
Recommendations¶
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0023¶
Severity¶
Low
Some parts of the output code are omitted for clarity reasons.
Description¶
This EWI is added when some option in a BULK INSERT
could not be mapped. The translated bulk options should be reflected as FILE FORMAT
options.
Code Example¶
Input Code:¶
BULK INSERT #PCE FROM 'E:\PCE_Look-up_table.txt'
WITH
(
FIELDTERMINATOR ='\t',
ROWTERMINATOR ='\n',
FIRE_TRIGGERS
);
Output Code:¶
CREATE OR REPLACE FILE FORMAT FILE_FORMAT_638461199649565070
FIELD_DELIMITER = '\t'
RECORD_DELIMITER = '\n'
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0023 - 'FIRE_TRIGGERS' BULK OPTION COULD NOT BE TRANSFORMED TO ANY OF THE EXISTING FILE FORMAT OPTIONS ***/!!!
FIRE_TRIGGERS;
CREATE OR REPLACE STAGE STAGE_638461199649565070
FILE_FORMAT = FILE_FORMAT_638461199649565070;
--** SSC-FDM-TS0004 - PUT STATEMENT IS NOT SUPPORTED ON WEB UI. YOU SHOULD EXECUTE THE CODE THROUGH THE SNOWFLAKE CLI **
PUT file://E:\PCE_Look-up_table.txt @STAGE_638461199649565070 AUTO_COMPRESS = FALSE;
COPY INTO T_PCE FROM @STAGE_638461199649565070/PCE_Look-up_table.txt;
Recommendations¶
Visit the SnowSQL CLI user guide.
If you need more support, you can email us at snowconvert-support@snowflake.com
Related EWI¶
SSC-FDM-TS0004: PUT statement not supported on UI.
SSC-EWI-TS0072¶
Severity¶
Low
Some parts of the output code are omitted for clarity reasons.
Description¶
This EWI is added when SELECT statements and OUPUT parameters should be returned. In this case, the resultsets from the SELECT statements are prioritized.
Input Code:¶
CREATE PROCEDURE SOMEPROC(@product_count INT OUTPUT, @123 INT OUTPUT)
AS
BEGIN
SELECT * from AdventureWorks.HumanResources.Department;
SELECT * from AdventureWorks.HumanResources.Employee;
END
Output Code:¶
CREATE OR REPLACE PROCEDURE SOMEPROC (PRODUCT_COUNT INT, _123 INT)
RETURNS ARRAY
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
ProcedureResultSet1 VARCHAR;
ProcedureResultSet2 VARCHAR;
return_arr ARRAY := array_construct();
BEGIN
ProcedureResultSet1 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:ProcedureResultSet1) AS
SELECT
*
from
AdventureWorks.HumanResources.Department;
return_arr := array_append(return_arr, :ProcedureResultSet1);
ProcedureResultSet2 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:ProcedureResultSet2) AS
SELECT
*
from
AdventureWorks.HumanResources.Employee;
return_arr := array_append(return_arr, :ProcedureResultSet2);
--** SSC-FDM-0020 - MULTIPLE RESULT SETS ARE RETURNED IN TEMPORARY TABLES **
RETURN return_arr;
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0072 - RETURN statement will be ignored due to previous RETURN statement ***/!!!
RETURN OBJECT_CONSTRUCT('PRODUCT_COUNT', :PRODUCT_COUNT, '_123', :_123);
END;
$$;
Recommendations¶
Remove the RETURN statement that should be ignored.
If you need more support, you can email us at snowconvert-support@snowflake.com
Related EWI¶
SSC-FDM-0020: Multiple result sets are returned in temporary tables;
SSC-EWI-TS0046¶
Severity¶
Medium
Description¶
This EWI is added when referencing SQL Server system tables (https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/object-catalog-views-transact-sql?view=sql-server-ver15) not supported or whithout equivalent in Snowflake SQL.
Code Example¶
Input Code:¶
SELECT *
FROM
sys.all_sql_modules
WHERE
[STATE] = 0; -- state must be ONLINE
Output Code:¶
SELECT
*
FROM
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0046 - SYSTEM TABLE sys.all_sql_modules IS NOT SUPPORTED IN SNOWFLAKE ***/!!!
sys.all_sql_modules
WHERE
STATE = 0; -- state must be ONLINE
Recommendations¶
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0017¶
Severity¶
Low
Description¶
This EWI is added when SnowConvert finds a masked column inside a CREATE TABLE
statement. This functionality doesn’t work by adding the option in the column declaration. Manual effort is needed to have the same behavior as SQL Server.
Code Example¶
Input Code:¶
CREATE TABLE TABLE1
(
[COL1] nvarchar MASKED WITH (FUNCTION = 'default()') NULL,
[COL2] varchar(100) MASKED WITH (FUNCTION = 'partial(1, "xxxxx", 1)') NULL,
[COL3] varchar(100) MASKED WITH (FUNCTION = 'email()') NOT NULL,
[COL4] smallint MASKED WITH (FUNCTION = 'random(1, 100)') NULL
);
Output Code:¶
CREATE OR REPLACE TABLE TABLE1
(
COL1 VARCHAR
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0017 - COLUMN MASKING NOT SUPPORTED IN CREATE TABLE ***/!!!
MASKED WITH (FUNCTION = 'default()') NULL,
COL2 VARCHAR(100)
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0017 - COLUMN MASKING NOT SUPPORTED IN CREATE TABLE ***/!!!
MASKED WITH (FUNCTION = 'partial(1, "xxxxx", 1)') NULL,
COL3 VARCHAR(100)
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0017 - COLUMN MASKING NOT SUPPORTED IN CREATE TABLE ***/!!!
MASKED WITH (FUNCTION = 'email()') NOT NULL,
COL4 SMALLINT
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0017 - COLUMN MASKING NOT SUPPORTED IN CREATE TABLE ***/!!!
MASKED WITH (FUNCTION = 'random(1, 100)') NULL
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
;
Recommendations¶
SnowConvert is not generating MASKING POLICIES
in the current version, so they have to be created manually. E.g.:
The first step is to create a masking policy administrator role.
create role masking_admin;
The second one is to grant the necessary privileges to the created role.
grant create masking policy on schema PUBLIC to role masking_admin;
allow table_owner role to set or unset the ssn_mask masking policy -- (optional)
grant apply on masking policy ssn_mask to role table_owner;
The next step is to create the masking policy functions.
-- default mask
create or replace masking policy default_mask as (val string) returns string ->
case
when current_role() in ('ANALYST') then val
else 'xxxx'
end;
-- partial mask
create or replace masking policy partial_mask as (val string) returns string ->
case
when current_role() in ('ANALYST') then val
else LEFT(val,1) || 'xxxxx' || RIGHT(val,1)
end;
-- email mask
create or replace masking policy email_mask as (val string) returns string ->
case
when current_role() in ('ANALYST') then val
else LEFT(val,1) || 'XXX@XXX.com'
end;
-- random mask
create or replace masking policy random_mask as (val smallint) returns smallint ->
case
when current_role() in ('ANALYST') then val
else UNIFORM(1,100,RANDOM())::SMALLINT
end;
For sample purposes, we are taking some examples of masking functions in SQL Server, and manually translating it into its equivalent in Snowflake.
The final step is to add the masking policy to the column that originally had the masking option in SQL Server.
alter table if exists TABLE1 modify column COL1 set masking policy default_mask;
alter table if exists TABLE1 modify column COL2 set masking policy partial_mask;
alter table if exists TABLE1 modify column COL3 set masking policy email_mask;
alter table if exists TABLE1 modify column COL4 set masking policy random_mask;
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0057¶
This EWI is deprecated, please refer to SSC-FDM-TS0022 documentation
Severity¶
Low
Some parts of the output code are omitted for clarity reasons.
Description¶
This is EWI occurs when a MASKING POLICY is created and a role or privilege must be linked to it so the data masking could work properly.
Code Example¶
Input code¶
ALTER TABLE tableName
ALTER COLUMN columnName
ADD MASKED WITH (FUNCTION = 'partial(1, "xxxxx", 1)');
Output code:¶
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0057 - MASKING ROLE MUST BE DEFINED PREVIOUSLY BY THE USER ***/!!!
CREATE OR REPLACE MASKING POLICY "partial_1_xxxxx_1" AS
(val STRING)
RETURNS STRING ->
CASE
WHEN current_role() IN ('YOUR_DEFINED_ROLE_HERE')
THEN val
ELSE LEFT(val, 1) || 'xxxxx' || RIGHT(val, 1)
END;
ALTER TABLE IF EXISTS tableName MODIFY COLUMN columnName!!!RESOLVE EWI!!! /*** SSC-EWI-TS0056 - A MASKING POLICY WAS CREATED AS SUBSTITUTE FOR MASKED WITH ***/!!! SET MASKING POLICY "partial_1_xxxxx_1";
As shown on line 6, there is a placeholder where the defined roles can be placed. There is room for one or several values separated by commas. Also, here, the use of single qoutes is mandatory for each of the values.
Recommendations¶
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0063¶
Severity¶
Critical
Description¶
This EWI is added when there are Time zones that are not supported in Snowflake
Code Example¶
Input Code:¶
SELECT current_timestamp at time zone 'Turks And Caicos Standard Time';
Output Code:¶
SELECT
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0063 - TIME ZONE NOT SUPPORTED IN SNOWFLAKE ***/!!!
CURRENT_TIMESTAMP() at time zone 'Turks And Caicos Standard Time'
;
Recommendations¶
A user defined function can be created to support multiple timezones.
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0032¶
The EWI is only generated when Javascript is the target language for Stored Procedures. This is a deprecated translation feature, as Snowflake Scripting is the recommended target language for Stored Procedures.
Severity¶
High
Generate Procedures and Macros using JavasScript as the target language adding the following flag -t JavaScript or –PLTargetLanguage JavaScript
Some parts of the output code are omitted for clarity reasons.
Description¶
This EWI is added to a literal that was originally a concatenation, when the contained code had a BULK INSERT
statement. The PUT
command resulting from the BULK INSERT
translation is not supported when executing code that was originally Dynamic SQL.
For this reason, the PUT
command must be extracted from the output code and executed manually outside of the procedure that contains it. Keep in mind that if there are many BULK INSERT
statements in Dynamic SQL sentences within the procedure, it is advised to split this procedure to be able to manually execute the corresponding PUT
command for each translated BULK INSERT
.
Code Example¶
Input Code:¶
-- Additional Params: -t JavaScript
CREATE PROCEDURE [dbo].[Load_FuelMgtMasterData]
AS
BEGIN
SET NOCOUNT ON;
DECLARE
@SQLString VARCHAR(500)
, @ImportName VARCHAR(200)
, @Today DATE
, @Yesterday DATE
, @SourceAffiliates VARCHAR(200);
SET @Today = GETDATE();
SET @Yesterday = DATEADD(DAY, -1, @Today);
TRUNCATE TABLE dbo.SourceFM_Affiliates;
SET @ImportName = '\\' + +@@ServerName
+ '\WorkA\merchantportal\affiliates.txt';
SET @SQLString = 'BULK INSERT ' + @SourceAffiliates + ' FROM '''
+ @ImportName + '''';
EXEC (@SQLString);
END;
Output Code:¶
CREATE OR REPLACE PROCEDURE dbo.Load_FuelMgtMasterData ()
RETURNS STRING
LANGUAGE JAVASCRIPT
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
// SnowConvert Helpers Code section is omitted.
/*** SSC-EWI-0040 - THE STATEMENT IS NOT SUPPORTED IN SNOWFLAKE ***/
/* SET NOCOUNT ON*/
;
let SQLSTRING;
let IMPORTNAME;
let TODAY;
let YESTERDAY;
let SOURCEAFFILIATES;
TODAY = SELECT(` CURRENT_TIMESTAMP() :: TIMESTAMP`);
YESTERDAY = SELECT(` DATEADD(DAY, -1, ?)`,[TODAY]);
EXEC(`TRUNCATE TABLE dbo.SourceFM_Affiliates`);
IMPORTNAME = `\\` + SERVERNAME + `\WorkA\merchantportal\affiliates.txt`;
SQLSTRING =
// ** SSC-EWI-TS0032 - THE BULK INSERT WAS PART OF A DYNAMIC SQL, WHICH MAKES SOME OF THE TRANSLATED ELEMENTS INVALID UNLESS EXECUTED OUTSIDE DYNAMIC CODE. **
`CREATE OR REPLACE FILE FORMAT FILE_FORMAT_638461213351333410;
CREATE OR REPLACE STAGE STAGE_638461213351333410
FILE_FORMAT = FILE_FORMAT_638461213351333410;
PUT file://${IMPORTNAME} @STAGE_638461213351333410 AUTO_COMPRESS = FALSE;
COPY INTO ${SOURCEAFFILIATES} FROM @STAGE_638461213351333410/${IMPORTNAME}`;
EXEC(`${SQLSTRING}`);
$$;
Recommendations¶
Extract the
PUT
command that resulted from the DynamicBULK INSERT
statement, and execute it before calling the procedure.If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0073¶
This EWI is deprecated, please refer to SSC-FDM-TS0023 documentation
Severity¶
Low
Description¶
This EWI is added in the transformation of ERROR_MESSAGE(). The exact message of the error could change in Snowflake.
Input Code:¶
SET @varErrorMessage = ERROR_MESSAGE()
Output Code¶
BEGIN
VARERRORMESSAGE := SQLERRM !!!RESOLVE EWI!!! /*** SSC-EWI-TS0073 - ERROR MESSAGE COULD BE DIFFERENT IN SNOWFLAKE ***/!!!;
END;
Recommendation¶
If you need more support, you can email us at snowconvert-support@snowflake.com.
SSC-EWI-TS0080¶
Severity¶
High
Description¶
Users in SQL Server can use the command EXECUTE AS
to temporarily change the execution context, this modifies the execution privileges and affects the results of context-dependent functions like USER_NAME()
. The REVERT
command can be used to restore the context previous to the last EXECUTE AS
.
Snowflake only supports the definition of an execution context in procedures, using either the CREATE PROCEDURE
or ALTER PROCEDURE
statements. Changing the context at runtime is not supported.
Code Example¶
Input Code:
CREATE PROCEDURE proc1()
WITH EXECUTE AS OWNER
AS
BEGIN
SELECT USER_NAME();
EXECUTE AS CALLER;
SELECT USER_NAME();
REVERT;
SELECT USER_NAME();
END
GO
Output Code:
CREATE OR REPLACE PROCEDURE proc1 ()
RETURNS ARRAY
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "07/05/2024" }}'
EXECUTE AS OWNER
AS
$$
DECLARE
ProcedureResultSet1 VARCHAR;
ProcedureResultSet2 VARCHAR;
ProcedureResultSet3 VARCHAR;
return_arr ARRAY := array_construct();
BEGIN
ProcedureResultSet1 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:ProcedureResultSet1) AS
SELECT
CURRENT_USER();
return_arr := array_append(return_arr, :ProcedureResultSet1);
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0080 - CHANGING THE EXECUTION CONTEXT AT RUNTIME IS NOT SUPPORTED IN SNOWFLAKE. ***/!!!
EXECUTE AS CALLER;
ProcedureResultSet2 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:ProcedureResultSet2) AS
SELECT
CURRENT_USER();
return_arr := array_append(return_arr, :ProcedureResultSet2);
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0080 - CHANGING THE EXECUTION CONTEXT AT RUNTIME IS NOT SUPPORTED IN SNOWFLAKE. ***/!!!
REVERT;
ProcedureResultSet3 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:ProcedureResultSet3) AS
SELECT
CURRENT_USER();
return_arr := array_append(return_arr, :ProcedureResultSet3);
--** SSC-FDM-0020 - MULTIPLE RESULT SETS ARE RETURNED IN TEMPORARY TABLES **
RETURN return_arr;
END;
$$;
Recommendations¶
Refactor the code so it works without having to switch the context.
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0047¶
This EWI is deprecated, please refer to SSC-FDM-TS0019 documentation
Severity¶
Low
Description¶
This EWI is added to notify that the RAISERROR Error Message may differ because of the SQL Server string format.
Code Example¶
Input Code:¶
CREATE PROCEDURE RAISERROR_PROCEDURE
AS
BEGIN
RAISERROR ('This is a sample error message with the first parameter %d and the second parameter %*.*s',
10,
1,
123,
7,
7,
'param2');
END
Output Code:¶
CREATE OR REPLACE PROCEDURE RAISERROR_PROCEDURE ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0047 - RAISERROR ERROR MESSAGE MAY DIFFER BECAUSE OF THE SQL SERVER STRING FORMAT ***/!!!
SELECT
RAISERROR_UDF('This is a sample error message with the first parameter %d and the second parameter %*.*s',
10,
1, array_construct(
123,
7,
7,
'param2'));
END;
$$;
Recommendations¶
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0016¶
Some parts of the output code are omitted for clarity reasons.
Description¶
This EWI is added when SnowConvert finds an ODBC Scalar function inside the input code.
User-defined functions are not supported in ODBC Scalar Function.
Code Example¶
Input Code:¶
SELECT {fn CURRENT_DATE_UDF()};
Output Code:¶
SELECT
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'CURRENT_DATE_UDF' NODE ***/!!!
CURRENT_DATE_UDF() !!!RESOLVE EWI!!! /*** SSC-EWI-TS0016 - USER DEFINED FUNCTIONS ARE NOT SUPPORTED IN ODBC SCALAR FUNCTION. ***/!!!;
Related EWI¶
SSC-EWI-0073: Pending Functional Equivalence Review.
Recommendations¶
No additional user actions are required; it is just informative.
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0036¶
Severity¶
Medium
Some parts of the output code are omitted for clarity reasons.
Description¶
This EWI is added when Cursors other than Local Cursors are identified. Currently, Snowflake Scripting only supports Local Cursors. Thus, all Cursors are translated as Local Cursors.
Code Example¶
Input Code:¶
CREATE OR ALTER PROCEDURE globalCursorTest
AS
BEGIN
-- Should be marked with SSC-EWI-TS0036
DECLARE MyCursor CURSOR GLOBAL STATIC READ_ONLY
FOR
SELECT *
FROM exampleTable;
-- Should not be marked
DECLARE MyCursor2 CURSOR LOCAL STATIC READ_ONLY
FOR
SELECT testCol
FROM myTable;
RETURN 'DONE';
END;
CREATE OR REPLACE PROCEDURE globalCursorTest ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
-- Should be marked with SSC-EWI-TS0036
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0036 - SNOWFLAKE SCRIPTING ONLY SUPPORTS LOCAL CURSORS ***/!!!
MyCursor CURSOR
FOR
SELECT
*
FROM
exampleTable;
-- Should not be marked
MyCursor2 CURSOR
FOR
SELECT
testCol
FROM
myTable;
BEGIN
RETURN 'DONE';
END;
$$;
Recommendations¶
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0067¶
Severity¶
Critical
Some parts of the output code are omitted for clarity reasons.
Description¶
This EWI is added when there are invalid parameters in the OPENXML, specifically when the XML path cannot be accessed.
To avoid this EWI, please send the explicit node path through the parameters.
Input Code:¶
SELECT
*
FROM
OPENXML (@idoc, @path, 1) WITH (
CustomerID VARCHAR(10),
ContactName VARCHAR(20)
);
Output Code:¶
SELECT
*
FROM
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0067 - INVALID PARAMETERS IN OPENXML TABLE-VALUED FUNCTION ***/!!!
OPENXML(@idoc, @path, 1);
Input code (Explicit parameter)¶
SELECT
*
FROM
OPENXML (@idoc, '/ROOT/Customer', 1) WITH(
CustomerID VARCHAR(10),
ContactName VARCHAR(20)
);
Output code (Explicit parameter)¶
SELECT
Left(value:Customer['@CustomerID'], '10') AS 'CustomerID',
Left(value:Customer['@ContactName'], '20') AS 'ContactName'
FROM
OPENXML_UDF($idoc, ':ROOT:Customer');
Recommendations¶
Try to see if the path can be explicitly passed as a parameter.
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0043¶
Severity¶
Medium
Some parts of the output code are omitted for clarity reasons.
Description¶
This EWI is added fort the WITH XMLNAMESPACES (https://docs.microsoft.com/en-us/sql/relational-databases/xml/add-namespaces-to-queries-with-with-xmlnamespaces?view=sql-server-ver15)clause which is not supported in Snowflake SQL
Code Example¶
Input Code:¶
WITH XMLNAMESPACES ('uri' as ns1)
SELECT ProductID as 'ns1:ProductID',
Name as 'ns1:Name',
Color as 'ns1:Color'
FROM Production.Product
WHERE ProductID = 316
FOR XML RAW, ELEMENTS XSINIL
Output Code:¶
--** SSC-PRF-TS0001 - PERFORMANCE WARNING - RECURSION FOR CTE NOT CHECKED. MIGHT REQUIRE RECURSIVE KEYWORD **
WITH
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0043 - WITH XMLNAMESPACES IS NOT SUPPORTED IN SNOWFLAKE ***/!!!
XMLNAMESPACES ('uri' as VARIANT /*** SSC-FDM-TS0015 - DATA TYPE NS1 IS NOT SUPPORTED IN SNOWFLAKE ***/)
SELECT
ProductID AS "ns1:ProductID",
Name AS "ns1:Name",
Color AS "ns1:Color"
FROM
Production.Product
WHERE
ProductID = 316
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0044 - FOR XML RAW CLAUSE IS NOT SUPPORTED IN SNOWFLAKE ***/!!!
FOR XML RAW, ELEMENTS XSINIL;
Recommendations¶
Consider using UDFs to emulate the behavior of the source code. The following code provides suggestions of UDFs that can be used to achieve recreating the original behavior:
CREATE TABLE PRODUCT (ProductID INTEGER, Name VarChar(20), Color VarChar(20));
INSERT INTO PRODUCT(PRODUCTID, NAME, COLOR) VALUES(1,'UMBRELLA','RED');
INSERT INTO PRODUCT(PRODUCTID, NAME, COLOR) VALUES(2,'SHORTS','BLUE');
INSERT INTO PRODUCT(PRODUCTID, NAME, COLOR) VALUES(3,'BALL','YELLOW');
WITH XMLNAMESPACES ('uri' as ns1)
SELECT ProductID as 'ns1:ProductID',
Name as 'ns1:Name',
Color as 'ns1:Color'
FROM Product
FOR XML RAW
CREATE OR REPLACE TABLE PRODUCT (
ProductID INTEGER,
Name VARCHAR(20),
Color VARCHAR(20))
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "07/12/2024" }}'
;
INSERT INTO PRODUCT (PRODUCTID, NAME, COLOR) VALUES(1,'UMBRELLA','RED');
INSERT INTO PRODUCT (PRODUCTID, NAME, COLOR) VALUES(2,'SHORTS','BLUE');
INSERT INTO PRODUCT (PRODUCTID, NAME, COLOR) VALUES(3,'BALL','YELLOW');
--** SSC-PRF-TS0001 - PERFORMANCE WARNING - RECURSION FOR CTE NOT CHECKED. MIGHT REQUIRE RECURSIVE KEYWORD **
WITH
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0043 - WITH XMLNAMESPACES IS NOT SUPPORTED IN SNOWFLAKE ***/!!! XMLNAMESPACES ('uri' as ns1)
SELECT
ProductID AS "ns1:ProductID",
Name AS "ns1:Name",
Color AS "ns1:Color"
FROM
Product
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0044 - FOR XML RAW CLAUSE IS NOT SUPPORTED IN SNOWFLAKE ***/!!!
FOR XML RAW;
If you need more support, you can email us at snowconvert-support@snowflake.com
Related EWI¶
SSC-PRF-TS0001: Performance warning - recursion for CTE not checked. Might require a recursive keyword.
SSC-EWI-TS0044: FOR XML clause is not supported in Snowflake.
SSC-FDM-TS0015: Regexp_Substr Function only supports POSIX regular expressions.
SSC-EWI-TS0077¶
Severity¶
Low
Description¶
This message is shown when there is a collate clause that is not supported in Snowflake.
Code example¶
Input Code:¶
SELECT 'a' COLLATE Albanian_BIN;
SELECT 'a' COLLATE Albanian_CI_AI;
CREATE TABLE ExampleTable (
ID INT,
Name VARCHAR(50) COLLATE collateName
);
Output Code:¶
SELECT 'a'
-- !!!RESOLVE EWI!!! /*** SSC-EWI-TS0077 - COLLATION Albanian_BIN NOT SUPPORTED ***/!!!
-- COLLATE Albanian_BIN
;
SELECT 'a'
-- !!!RESOLVE EWI!!! /*** SSC-EWI-TS0077 - COLLATION Albanian_CI_AI NOT SUPPORTED ***/!!!
-- COLLATE Albanian_CI_AI
;
CREATE OR REPLACE TABLE ExampleTable (
ID INT,
Name VARCHAR(50)
-- !!!RESOLVE EWI!!! /*** SSC-EWI-TS0077 - COLLATION collateName NOT SUPPORTED ***/!!!
-- COLLATE collateName
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
;
Recommendations¶
No additional user actions are required.
If you need more support, you can email us at snowconvert-support@snowflake.com
SSC-EWI-TS0026¶
Severity¶
Low
Description¶
This EWI is added when a Common Table Expression With a Delete From is transformed to a Create or Replace Table.
Code Example¶
Input Code:¶
WITH Duplicated AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ID) AS RN
FROM WithQueryTest
)
DELETE FROM Duplicated
WHERE Duplicated.RN > 1
Output Code:¶
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0026 - WITH DELETE QUERY TURNED TO CREATE TABLE ***/!!!
CREATE OR REPLACE TABLE WithQueryTest AS
SELECT
*
FROM
WithQueryTest
QUALIFY
ROW_NUMBER()
OVER (PARTITION BY
ID
ORDER BY ID) = 1;
Recommendations¶
No additional user actions are required.
If you need more support, you can email us at snowconvert-support@snowflake.com