SnowConvert: General Functional Differences¶

SSC-FDM-0001¶

Note

For better readability, we have simplified the code examples by showing only the most relevant parts.

Description¶

Views that select all columns from a single table without any filtering conditions (WHERE clause) are unnecessary in Snowflake and can negatively impact query performance.

Code Example¶

Input Code (Oracle):¶
 CREATE OR REPLACE VIEW simpleView1
AS
SELECT
*
FROM
simpleTable;

CREATE OR REPLACE VIEW simpleView2
AS
SELECT
*
FROM
simpleTable GROUP BY col1;
Copy
Generated Code:¶
 CREATE OR REPLACE VIEW simpleView1
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
AS
--** SSC-FDM-0001 - VIEWS SELECTING ALL COLUMNS FROM A SINGLE TABLE ARE NOT REQUIRED IN SNOWFLAKE AND MAY IMPACT PERFORMANCE. **
SELECT
*
FROM
simpleTable;

CREATE OR REPLACE VIEW simpleView2
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
AS
--** SSC-FDM-0001 - VIEWS SELECTING ALL COLUMNS FROM A SINGLE TABLE ARE NOT REQUIRED IN SNOWFLAKE AND MAY IMPACT PERFORMANCE. **
SELECT
*
FROM
simpleTable
GROUP BY col1;
Copy

Best Practices¶

SSC-FDM-0002¶

Description¶

This message appears when a Correlated Subquery is detected. A correlated subquery references a column from the outer query. When migrating to Snowflake, these subqueries may behave differently in some cases. For more details, see Working with Subqueries.

Code Example¶

Input Code:¶
 CREATE TABLE schema1.table1(column1 NVARCHAR(50), column2 NVARCHAR(50));
CREATE TABLE schemaA.tableA(columnA NVARCHAR(50), columnB NVARCHAR(50));

--Correlated Subquery
SELECT columnA FROM schemaA.tableA ta WHERE columnA = (SELECT SUM(column1) FROM schema1.table1 t1 WHERE t1.column1 = ta.columnA);
Copy
Generated Code:¶
 CREATE OR REPLACE TABLE schema1.table1 (
column1 VARCHAR(50),
column2 VARCHAR(50))
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "transact",  "convertedOn": "10/11/2024",  "domain": "test" }}'
;

CREATE OR REPLACE TABLE schemaA.tableA (
columnA VARCHAR(50),
columnB VARCHAR(50))
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "transact",  "convertedOn": "10/11/2024",  "domain": "test" }}'
;

--Correlated Subquery
SELECT
columnA
FROM
schemaA.tableA ta
WHERE
columnA =
          --** SSC-FDM-0002 - CORRELATED SUBQUERIES MAY HAVE SOME FUNCTIONAL DIFFERENCES. **
          (SELECT
          SUM(column1) FROM
          schema1.table1 t1
          WHERE
          t1.column1 = ta.columnA
          );
Copy

Best Practices¶

SSC-FDM-0003¶

Description¶

This warning appears when there is a mismatch in conversion rates for the specified assessment field. SC automatically resolves these inconsistencies, so this message is for informational purposes only.

Note

This warning message appears only in assessment documents and will not be shown in the output code.

Best Practices¶

  • If you encounter any issues, even though SnowConvert can automatically fix them, you can still contact the SnowConvert support team at snowconvert-support@snowflake.com for assistance.

SSC-FDM-0004¶

Description¶

This warning appears in clauses related to external handling because Snowflake manages data storage differently. Unlike other databases, Snowflake doesn’t require external tables since all data should be stored within Snowflake’s internal storage system. For more details about this topic, see Data Storage Considerations.

Code Example¶

Input Code:¶
 CREATE OR REPLACE EXTERNAL TABLE external_table_test1
(
  col1 INTEGER
)
OPTIONS (
  format = 'CSV',
  uris = ['gs://my_bucket/file.csv']
);
Copy
Generated Code:¶
 --** SSC-FDM-0004 - EXTERNAL TABLE TRANSLATED TO REGULAR TABLE **
CREATE OR REPLACE TABLE external_table_test1 (
   col1 INTEGER
 )
-- OPTIONS (
--   format = 'CSV',
--   uris = ['gs://my_bucket/file.csv']
-- )
  ;
Copy

Best Practices¶

  • Data from external table files needs to be imported into your Snowflake database.

  • For additional assistance, please contact us at snowconvert-support@snowflake.com

SSC-FDM-0005¶

Description¶

The TIME data type in Snowflake stores only the time component without any timezone information.

TIME stores clock time values and performs all operations without considering time zones. For more details, see TIME.

Example Code¶

Input Code:¶
 CREATE TABLE TABLE_TIME_TYPE (
    COLNAME TIME (9) WITH TIME ZONE
);
Copy
Generated Code:¶
 CREATE OR REPLACE TABLE TABLE_TIME_TYPE (
    COLNAME TIME(9) /*** SSC-FDM-0005 - TIME ZONE NOT SUPPORTED FOR TIME DATA TYPE ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;
Copy

Best Practices¶

SSC-FDM-0006¶

Description¶

This message appears when creating a column with the NUMBER data type in a table. It warns about potential arithmetic differences in Snowflake when working with decimal scales in intermediate calculations. These differences could cause some operations to fail. For more details, see Snowflake’s post on intermediate numbers in Snowflake and Number out of representable range.

To prevent arithmetic calculation issues, we recommend running data sampling tests first. This will help you determine the correct precision and scale values needed for your operations.

Example Codes¶

Simple Table with Number Columns¶

Input Code (Oracle):¶
 CREATE TABLE table1
(
column1 NUMBER,
column2 NUMBER (20, 4)
);
Copy
Generated Code:¶
 CREATE OR REPLACE TABLE table1
(
column1 NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/,
column2 NUMBER(20, 4) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
Copy

Examples of Arithmetic Issues¶

The following examples demonstrate how arithmetic operations can lead to unexpected results when working with Number columns:

Snowflake Code with Division Error:¶
 CREATE OR REPLACE TABLE number_table( column1 NUMBER(38, 19) );

INSERT INTO number_table VALUES (1);

SELECT column1 / column1 FROM number_table;
Copy
Snowflake Code with Multiplication Error:¶
 CREATE OR REPLACE TABLE number_table( column1 NUMBER(38, 20) );

INSERT INTO number_table VALUES (1);

SELECT column1 * column1 FROM number_table;
Copy

When executing SELECT statements in Snowflake, an error message will be displayed.

Number exceeds the allowed range for data type FIXEDSB16 (nullable). The value 1.0000000000000000000 cannot be stored in this data type.

This error occurs when the calculation result exceeds Snowflake’s maximum storage capacity. To resolve this issue, reduce the scale (number of decimal places) by 1 in each example. This will allow the operation to complete successfully.

Snowflake Code with Division:¶
 CREATE OR REPLACE TABLE number_table( column1 NUMBER(38, 18) );

INSERT INTO number_table VALUES (1);

SELECT column1 / column1 FROM number_table;
Copy
Snowflake Code with Multiplication:¶
 CREATE OR REPLACE TABLE numbertable( column1 NUMBER(38, 19) );

INSERT INTO number_table VALUES (1);

SELECT column1 * column1 FROM number_table;
Copy

To minimize migration errors, SnowConvert automatically sets the default scale of Numbers to 18.

Best Practices¶

  • Check that intermediate values in your operations don’t exceed Snowflake’s maximum scale of 37.

  • Analyze data samples to confirm your required precision and scale settings before executing operations.

  • Often, after data sampling or business discussions, you may find that different precision settings are more appropriate. For example, MONEY columns typically use NUMBER(20,4). Since changing column data types in Snowflake isn’t straightforward, you can refer to this post on our forum for guidance on modifying column data types while preserving data.

  • For additional assistance, contact us at snowconvert-support@snowflake.com

SSC-FDM-0007¶

Note

Code snippets have been simplified to focus on key concepts

Description¶

A deployment error may occur when SnowConvert cannot find a required dependency or resolve certain data types. This can happen when the dependent object is missing from the source code.

Example Code¶

Input Code:¶
 CREATE VIEW VIEW01 AS SELECT * FROM TABLE1;
Copy
Generated Code:¶
 --** SSC-FDM-0007 - MISSING DEPENDENT OBJECT "TABLE1" **
CREATE OR REPLACE VIEW VIEW01
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
AS
--** SSC-FDM-0001 - VIEWS SELECTING ALL COLUMNS FROM A SINGLE TABLE ARE NOT REQUIRED IN SNOWFLAKE AND MAY IMPACT PERFORMANCE. **
SELECT
* FROM
TABLE1;
Copy

Note

The TABLE1 definition has not been provided in this example.

Best Practices¶

  • Verify that all object dependencies are included in your source code.

  • Review any object references in the code to ensure they are properly handled.

  • For additional assistance, contact us at snowconvert-support@snowflake.com

SSC-FDM-0008¶

Note

For better readability, we have simplified some sections of the code in this example.

Description ¶

When creating tables in Snowflake, the ON COMMIT clause can only be used with temporal tables. If you include an ON COMMIT clause in a non-temporal table definition, it will be commented out in the converted code. Additionally, since Snowflake doesn’t support ON COMMIT DELETE, this option will also be commented out during conversion.

Example Code¶

Input Code¶
 CREATE TABLE TABLE01 (COLNAME VARCHAR(20)) ON COMMIT PRESERVE ROWS
CREATE TEMPORARY TABLE TABLE02 (COLNAME VARCHAR(20)) ON COMMIT DELETE ROWS
Copy
Generated Code¶
 CREATE OR REPLACE TABLE TABLE01 (
COLNAME VARCHAR(20))
----** SSC-FDM-0008 - ON COMMIT NOT SUPPORTED **
--ON COMMIT PRESERVE ROWS
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
;

CREATE OR REPLACE TEMPORARY TABLE TABLE02 (
COLNAME VARCHAR(20))
----** SSC-FDM-0008 - ON COMMIT NOT SUPPORTED **
--ON COMMIT DELETE ROWS
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
;
Copy

Best Practices¶

SSC-FDM-0009¶

Description ¶

Global temporary tables are complex because they can be created in different ways, as shown in Snowflake’s documentation.

Example Code¶

Input Code¶
 CREATE OR REPLACE GLOBAL TEMPORARY TABLE GLOBAL_TEMP_TABLE
(
    col3 INTEGER,
    col4 VARCHAR(50)
);
Copy
Generated Code¶
 --** SSC-FDM-0009 - GLOBAL TEMPORARY TABLE FUNCTIONALITY NOT SUPPORTED. **
CREATE OR REPLACE TABLE GLOBAL_TEMP_TABLE
    (
        col3 INTEGER,
        col4 VARCHAR(50)
    )
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
Copy

Best Practices¶

SSC-FDM-0010¶

Description ¶

This message appears when SnowConvert detects a DEFAULT SYSDATE clause where the column’s data type is not DATE or TIMESTAMP. In such cases, SnowConvert automatically converts the data type to DATE.

Example Code¶

Input Code¶
 CREATE TABLE "SYSDATE_DEFAULT_TEST_TABLE_1"( 
 "COLUMN1" VARCHAR2(30 BYTE) DEFAULT SYSDATE
);
Copy
Generated Code¶
 CREATE OR REPLACE TABLE "SYSDATE_DEFAULT_TEST_TABLE_1" (
  "COLUMN1" TIMESTAMP DEFAULT CURRENT_TIMESTAMP() /*** SSC-FDM-0010 - CONVERTED FROM VARCHAR2 TO DATE FOR CURRENT_DATE DEFAULT ***/
 )
 COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
 ;
Copy

Best Practices¶

SSC-FDM-0011¶

Note

This FDM is no longer supported. For more information, please see SSC-EWI-0045.

Description ¶

Column names that are reserved keywords in Snowflake but are valid in the source database.

Example Code¶

Input Code (Oracle):¶
 CREATE TABLE T1
(
    LOCALTIME VARCHAR,
    CURRENT_USER VARCHAR
);
Copy
Generated Code:¶
 CREATE OR REPLACE TABLE T1
    (
    --** SSC-FDM-0011 - COLUMN NAME 'LOCALTIME' IS A SNOWFLAKE RESERVED KEYWORD **
    "LOCALTIME" VARCHAR,
    --** SSC-FDM-0011 - COLUMN NAME 'CURRENT_USER' IS A SNOWFLAKE RESERVED KEYWORD **
    "CURRENT_USER" VARCHAR
    )
    COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
    ;
Copy

Best Practices¶

SSC-FDM-0012¶

Description ¶

This warning appears when a Constraint constraintName is used in a column’s default expression. Since Snowflake does not support constraints in default expressions, the constraint and its constraintName are automatically removed, and a warning message is generated.

Example Code¶

Input Code¶
 CREATE TABLE TABLE1 ( 
COL1 VARCHAR (10) CONSTRAINT constraintName DEFAULT ('0') NOT NULL 
);
Copy
Generated Code¶
 CREATE OR REPLACE TABLE TABLE1 (
COL1 VARCHAR(10)
                 --** SSC-FDM-0012 - CONSTRAINT IN DEFAULT EXPRESSION IS NOT SUPPORTED IN SNOWFLAKE **
                 DEFAULT ('0') NOT NULL
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
;
Copy

Best Practices¶

SSC-FDM-0013¶

Description ¶

A warning message has been added to highlight cases where timezone expressions cannot be evaluated during conversion. While SnowConvert can successfully map literal timezone strings to their Snowflake equivalents, it cannot determine timezone values that are specified through expressions. This limitation means that the runtime results in Snowflake may differ from the source system when dynamic timezone expressions are used.

Example Code¶

Input Code (Oracle)¶
 SELECT TIMESTAMP '1998-12-25 09:26:50.12' AT TIME ZONE SESSIONTIMEZONE FROM DUAL;
SELECT TIMESTAMP '1998-12-25 09:26:50.12' AT TIME ZONE Expression FROM DUAL;
Copy
Generated Code¶
 SELECT
--** SSC-FDM-0013 - TIMEZONE EXPRESSION COULD NOT BE MAPPED, RESULTS MAY BE DIFFERENT **
TO_TIMESTAMP_LTZ( TIMESTAMP '1998-12-25 09:26:50.12')
FROM DUAL;

SELECT
--** SSC-FDM-0013 - TIMEZONE EXPRESSION COULD NOT BE MAPPED, RESULTS MAY BE DIFFERENT **
CONVERT_TIMEZONE(Expression, TIMESTAMP '1998-12-25 09:26:50.12')
FROM DUAL;
Copy
Source Code (Teradata)¶
 select TIMESTAMP '1998-12-25 09:26:50.12' AT TIME ZONE SESSIONTIMEZONE;
select current_timestamp at time zone CONCAT(' America ', ' Pacific'); 
select current_timestamp at time zone (SELECT COL1 FROM TABLE1 WHERE COL2 = 2);
Copy
Output Code¶
 SELECT
CONVERT_TIMEZONE(SESSIONTIMEZONE, TIMESTAMP '1998-12-25 09:26:50.12') /*** SSC-FDM-0013 - TIMEZONE EXPRESSION COULD NOT BE MAPPED, RESULTS MAY BE DIFFERENT ***/;

SELECT
CONVERT_TIMEZONE(CONCAT(' America ', ' Pacific'), CURRENT_TIMESTAMP) /*** SSC-FDM-0013 - TIMEZONE EXPRESSION COULD NOT BE MAPPED, RESULTS MAY BE DIFFERENT ***/;

SELECT
CONVERT_TIMEZONE((
SELECT
COL1 FROM
TABLE1
WHERE COL2 = 2), CURRENT_TIMESTAMP) /*** SSC-FDM-0013 - TIMEZONE EXPRESSION COULD NOT BE MAPPED, RESULTS MAY BE DIFFERENT ***/;
Copy

Timezone Compatibility with Oracle¶

Most Oracle timezone names are directly compatible with Snowflake, allowing for smooth migration. However, some timezone expressions are not currently supported in Snowflake and will generate a functional difference message during migration.

  • Africa/Douala

  • Asia/Ulaanbaatar

  • Asia/Yekaterinburg

  • Canada/Saskatchewan

  • Central Standard Time (CST)

  • Pacific Standard Time (PST)

  • US/Pacific

Best Practices¶

SSC-FDM-0014¶

Note

This FDM is no longer supported. For more information, please see SSC-EWI-0035.

Description¶

The CHECK constraint is not supported in Snowflake, but this limitation does not impact the functionality of your database.

Example Code¶

Input Code Oracle :¶
 CREATE TABLE "Schema"."BaseTable"(
  "COLUMN1" VARCHAR2(255),
  CHECK ( COLUMN1 IS NOT NULL )
);
Copy
Generated Code:¶
 CREATE OR REPLACE TABLE "Schema"."BaseTable" (
    "COLUMN1" VARCHAR(255)
--                          ,
--    --** SSC-FDM-0014 - CHECK STATEMENT NOT SUPPORTED **
--    CHECK ( COLUMN1 IS NOT NULL )
  )
  COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
  ;
Copy
Input Code Teradata:¶
 CREATE TABLE TABLE1,
    NO FALLBACK,
    NO BEFORE JOURNAL,
    NO AFTER JOURNAL
(
    COL0 BYTEINT,
    CONSTRAINT constraint_name CHECK (COL1 < COL2)
)
Copy
Generated Code:¶
 CREATE TABLE TABLE1
(
    COL0 BYTEINT
--                ,
--    --** SSC-FDM-0014 - CHECK STATEMENT NOT SUPPORTED **
--    CONSTRAINT constraint_name CHECK (COL1 < COL2)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;
Copy
Input Code SqlServer¶
 ALTER TABLE table_name2
ADD column_name VARCHAR(255)
CONSTRAINT constraint_name 
CHECK NOT FOR REPLICATION (column_name > 1);
Copy
Generated Code:¶
 ALTER TABLE IF EXISTS table_name2
ADD column_name VARCHAR(255)
----** SSC-FDM-0014 - CHECK STATEMENT NOT SUPPORTED **
--CONSTRAINT constraint_name
--CHECK NOT FOR REPLICATION (column_name > 1)
                                           ;
Copy

Best Practices¶

SSC-FDM-0015¶

Description ¶

This error occurs when SnowConvert cannot find either:

  • A user-defined Custom Type definition

  • A recognized Oracle built-in data type

Example code¶

Input Code (Oracle):¶
 --Type was never defined
--CREATE TYPE type1;

CREATE TABLE table1
(
column1 type1
);
Copy
Generated Code:¶
 --Type was never defined
--CREATE TYPE type1;

CREATE OR REPLACE TABLE table1
(
column1 VARIANT /*** SSC-FDM-TS0015 - DATA TYPE TYPE1 IS NOT SUPPORTED IN SNOWFLAKE ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
;
Copy

Best Practices¶

SSC-FDM-0016¶

Description ¶

Snowflake Scripting does not support constant values. When the Snowflake Scripting feature is enabled, all constants within procedures are automatically converted to variables.

Example code¶

Oracle:¶
 CREATE OR REPLACE PROCEDURE p_constants
AS
my_const1 CONSTANT NUMBER := 40;
my_const2 CONSTANT NUMBER NOT NULL := 40;
BEGIN
NULL;
END;
Copy
Snowflake Scripting¶
 CREATE OR REPLACE PROCEDURE p_constants ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
--** SSC-FDM-0016 - CONSTANTS ARE NOT SUPPORTED BY SNOWFLAKE SCRIPTING. IT WAS TRANSFORMED TO A VARIABLE **
my_const1 NUMBER(38, 18) := 40;
--** SSC-FDM-0016 - CONSTANTS ARE NOT SUPPORTED BY SNOWFLAKE SCRIPTING. IT WAS TRANSFORMED TO A VARIABLE **
--** SSC-FDM-OR0025 - NOT NULL CONSTRAINT IS NOT SUPPORTED BY SNOWFLAKE **
my_const2 NUMBER(38, 18) := 40;
BEGIN
NULL;
END;
$$;
Copy

Best Practices¶

SSC-FDM-0017¶

Description¶

System versioning, enabled by the WITH SYSTEM VERSIONING clause in ANSI SQL, tracks historical changes to table data. However, this feature is not currently available in Snowflake.

Code Example¶

Input Code:¶
 CREATE TABLE t1 (
    ID INT PRIMARY KEY,
    Name VARCHAR(50),
    SysStartTime TIMESTAMP,
    SysEndTime TIMESTAMP
) WITH SYSTEM VERSIONING;
Copy
Generated Code:¶
 CREATE TABLE t1 (
    ID INT PRIMARY KEY,
    Name VARCHAR(50),
    SysStartTime TIMESTAMP,
    SysEndTime TIMESTAMP
)
----** SSC-FDM-0017 - WITH SYSTEM VERSIONING CLAUSE IS NOT SUPPORTED BY SNOWFLAKE. **
--WITH SYSTEM VERSIONING
                      ;
Copy

Best Practices¶

  • Snowflake’s Time Travel feature allows you to access historical data, including changed or deleted data, within a specified time period. This feature enables you to:

    • Recover accidentally or intentionally deleted data objects (tables, schemas, and databases)

    • Create copies and backups of data from specific points in time

    • Track and analyze how data has been used or modified over time

  • For additional assistance, please contact us at snowconvert-support@snowflake.com

SSC-FDM-0018¶

Description¶

The CHARACTER SET column option, which defines the permitted characters that can be stored in a column, is not supported in Snowflake.

Code Example¶

Input Code:¶
 CREATE TABLE TABLE01(
    COLNAME VARCHAR(20) CHARACTER SET character_specification
);
Copy
Generated Code:¶
 CREATE TABLE TABLE01 (
    COLNAME VARCHAR(20)
--                        --** SSC-FDM-0018 - CHARACTER SET CLAUSE IS NOT SUPPORTED BY SNOWFLAKE. **
--                        CHARACTER SET character_specification
);
Copy

Best Practices¶

SSC-FDM-0019¶

Description¶

This warning indicates that SnowConvert could not access the semantic information for a specific object. This typically occurs when there are multiple objects with identical names in your code. When this happens, SnowConvert cannot properly analyze the object’s semantic information.

Example Code¶

Input Code:¶
 CREATE TABLE T1
(
    COL1 INTEGER
);


CREATE TABLE T1
(
    COL2 INTEGER
);
Copy
Generated Code:¶
 CREATE OR REPLACE TABLE T1
(
    COL1 INTEGER
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;

--** SSC-FDM-0019 - SEMANTIC INFORMATION COULD NOT BE LOADED FOR T1. CHECK IF THE NAME IS INVALID OR DUPLICATED. **
CREATE TABLE T1
(
    COL2 INTEGER
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;
Copy

Best Practices¶

  • Review your input code for any duplicate objects, as these can interfere with the proper loading of semantic information.

  • For additional assistance, please contact us at snowconvert-support@snowflake.com

SSC-FDM-0020¶

Description¶

A Snowflake Scripting procedure can only return one result set when executed.

When a procedure needs to return multiple result sets (similar to Teradata’s behavior), the results are stored in temporary tables. The Snowflake Scripting procedure returns an array containing the names of these temporary tables.

Example code¶

Input Code (Teradata):¶
 REPLACE MACRO sampleMacro AS 
(
    SELECT CURRENT_DATE AS DT;
    SELECT CURRENT_DATE AS DT_TWO;
);
Copy
Generated Code:¶
 CREATE OR REPLACE PROCEDURE sampleMacro ()
RETURNS ARRAY
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
    DECLARE
        return_arr ARRAY := array_construct();
        tbl_nm VARCHAR;
    BEGIN
        tbl_nm := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
        CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:tbl_nm) AS
            SELECT
                CURRENT_DATE() AS DT;
        return_arr := array_append(return_arr, :tbl_nm);
        tbl_nm := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
        CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:tbl_nm) AS
            SELECT
                CURRENT_DATE() AS DT_TWO;
        return_arr := array_append(return_arr, :tbl_nm);
        --** SSC-FDM-0020 - MULTIPLE RESULT SETS ARE RETURNED IN TEMPORARY TABLES **
        RETURN return_arr;
    END;
$$;
Copy

Best Practices¶

  • Run a SELECT query using the temporary table names returned by the procedure to view the results.

  • Keep procedures simple by making them return a single result set instead of multiple ones. This makes the results easier to handle.

  • For additional help, contact us at snowconvert-support@snowflake.com

SSC-FDM-0021¶

Description¶

Snowflake does not use traditional database indexes. Instead, it automatically creates and manages micro-partitions for all tables to optimize query performance. When using SnowConvert, any code related to index creation will be commented out since it is not needed in Snowflake. These micro-partitions automatically improve the speed of DML operations without requiring any manual management.

While this configuration typically provides good query performance, you can further optimize it by implementing data clustering keys. For more details about micro-partitions and data clustering, please refer to Micro-partitions & Data Clustering.

Example Code¶

Input Code (Oracle):¶
 CREATE INDEX index1
ON table1(column1);
Copy
Generated Code:¶
 ----** SSC-FDM-0021 - CREATE INDEX IS NOT SUPPORTED BY SNOWFLAKE **
----** SSC-FDM-0007 - MISSING DEPENDENT OBJECT "table1" **
--CREATE INDEX index1
--ON table1(column1)
                  ;
Copy

Best Practices¶

  • Data clustering can improve query performance by organizing data in tables more efficiently.

  • For additional support, please contact us at snowconvert-support@snowflake.com

SSC-FDM-0022¶

Severity¶

Poor

Description¶

A warning appears when an unsupported Window Frame Unit has been converted to Rows, which may cause differences in the output. For example, Snowflake does not support the GROUPS unit, so it must be converted to Rows.

Please note that this message appears when a Window Frame Unit is either not fully supported or needs modification. This includes cases where the RANGE unit requires changes.

Example Code¶

Here is a sample dataset that we will use to explain the concept.

C_NAME

C_BIRTH_DAY

USA

1

USA

4

Poland

9

Canada

10

USA

5

Canada

12

Costa Rica

3

Poland

4

USA

2

Costa Rica

7

Costa Rica

10

Oracle:¶
SELECT
    C_NAME,
    SUM(C_BIRTH_DAY)
    OVER (ORDER BY C_BIRTH_DAY
    RANGE BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS MAX1
FROM WINDOW_TABLE;
Copy

C_NAME

MAX1

USA

-

USA

1

Costa Rica

3

USA

6

Poland

6

USA

14

Costa Rica

19

Poland

26

Canada

35

Costa Rica

35

Canada

55

Snowflake:¶
 SELECT
    C_NAME,
    SUM(C_BIRTH_DAY)
    OVER (ORDER BY C_BIRTH_DAY ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING /*** SSC-FDM-0022 - WINDOW FRAME UNIT 'RANGE' WAS CHANGED TO ROWS ***/) AS MAX1
    FROM
WINDOW_TABLE;
Copy

C_NAME

MAX1

USA

-

USA

1

Costa Rica

3

USA

6

Poland

10

USA

14

Costa Rica

19

Poland

26

Canada

35

Costa Rica

45

Canada

55

Recommendations¶

  • Add an ORDER BY clause to your queries to ensure consistent row ordering when running in Snowflake.

  • For additional assistance, please contact us at snowconvert-support@snowflake.com

SSC-FDM-0023¶

Severity¶

Intermediate

Description¶

SnowConvert converts Global Temporary tables into standard Create Table statements. Please note that any references to these transformed tables may not function as originally intended.

Code example¶

Input¶
 create global temporary table t1 
    (col1 varchar); 
create view view1 as 
    select col1 from t1;
Copy
Output¶
 --** SSC-FDM-0009 - GLOBAL TEMPORARY TABLE FUNCTIONALITY NOT SUPPORTED. **
CREATE OR REPLACE TABLE t1
    (col1 varchar)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
;

CREATE OR REPLACE VIEW view1
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
AS
select col1 from
    --** SSC-FDM-0023 - A Global Temporary Table is being referenced **
    t1;
Copy

Recommendations¶

SSC-FDM-0024¶

Note

This FDM feature is no longer supported. For more information, please see SSC-EWI-0058.

Description¶

This error occurs when you try to use an unsupported statement within a CREATE PROCEDURE command in Snowflake Scripting.

Example code¶

Input Code (Oracle):¶
 CREATE OR REPLACE PROCEDURE PROC01
IS
  number_variable INTEGER;
BEGIN
  EXECUTE IMMEDIATE 'SELECT 1 FROM DUAL' INTO number_variable;
END;
Copy
Generated Code:¶
 CREATE OR REPLACE PROCEDURE PROC01 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
  DECLARE
    number_variable INTEGER;
  BEGIN
    EXECUTE IMMEDIATE 'SELECT 1 FROM DUAL'
--                                           --** SSC-FDM-0024 - FUNCTIONALITY FOR 'EXECUTE IMMEDIATE RETURNING CLAUSE' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING **
--                                           INTO number_variable
                                                               ;
  END;
$$;
Copy

Recommendations¶

SSC-FDM-0026¶

Note

This FDM feature is no longer supported. For more information, please see SSC-EWI-0028.

Description¶

This error occurs when you attempt to use a data type that is not compatible with Snowflake.

Example¶

Input Code (Oracle):¶
 CREATE TABLE MYTABLE
(
    COL1 SYS.ANYDATASET
);
Copy
Generated Code:¶
 CREATE OR REPLACE TABLE MYTABLE
    (
    --** SSC-FDM-0026 - TYPE NOT SUPPORTED BY SNOWFLAKE **
        COL1 SYS.ANYDATASET
    )
    COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
    ;
Copy

Recommendations¶

SSC-FDM-0027¶

Note

For better readability, we have simplified some sections of the output code.

Description¶

This message indicates that a statement from the source code cannot be converted to Snowflake because there is no equivalent functionality in Snowflake. The statement is no longer necessary and will be removed from the converted code. However, SC preserves the original statement as a comment for reference.

Example Code¶

Input Code:¶
 .LOGTABLE tduser.Employee_log;  
   .BEGIN MLOAD TABLES Employee_Stg;  
      .LAYOUT Employee;  
      .FIELD in_EmployeeNo * VARCHAR(10);  
      .FIELD in_FirstName * VARCHAR(30); 
      .FIELD in_LastName * VARCHAR(30);  
      .FIELD in_BirthDate * VARCHAR(10); 
      .FIELD in_JoinedDate * VARCHAR(10);  
      .FIELD in_DepartmentNo * VARCHAR(02);

      .dml label EmpLabel
  IGNORE DUPLICATE INSERT ROWS; 
      INSERT INTO Employee_Stg (
         EmployeeNo,
         FirstName,
         LastName,
         BirthDate,
         JoinedDate,
         DepartmentNo
      )  
      VALUES (
         :in_EmployeeNo,
         :in_FirstName,
         :in_Lastname,
         :in_BirthDate,
         :in_JoinedDate,
         :in_DepartmentNo
      );
      .IMPORT INFILE employee.txt  
      FORMAT VARTEXT ','
      LAYOUT Employee
      APPLY EmpLabel;  
   .END MLOAD;  
LOGOFF;
Copy
Generated Code:¶
 #*** Generated code is based on the SnowConvert Python Helpers version 2.0.6 ***
// SnowConvert Helpers Code section is omitted.
 
import os
import sys
import snowconvert.helpers
from snowconvert.helpers import Export
from snowconvert.helpers import exec
from snowconvert.helpers import BeginLoading
con = None
def main():
  snowconvert.helpers.configure_log()
  con = snowconvert.helpers.log_on()
  #** SSC-FDM-0027 - REMOVED NEXT STATEMENT, NOT APPLICABLE IN SNOWFLAKE.  **
  #.LOGTABLE tduser.Employee_log
   
  #** SSC-FDM-0027 - REMOVED NEXT STATEMENT, NOT APPLICABLE IN SNOWFLAKE.  **
  #.BEGIN MLOAD TABLES Employee_Stg
   
  Employee_TableName = "Employee_TEMP_TABLE"
  Employee_Columns = """in_EmployeeNo VARCHAR(10), 
in_FirstName VARCHAR(30), 
in_LastName VARCHAR(30), 
in_BirthDate VARCHAR(10), 
in_JoinedDate VARCHAR(10), 
in_DepartmentNo VARCHAR(02)"""
  Employee_Conditions = """in_EmployeeNo AS in_EmployeeNo, in_FirstName AS in_FirstName, in_LastName AS in_LastName, in_BirthDate AS in_BirthDate, in_JoinedDate AS in_JoinedDate, in_DepartmentNo AS in_DepartmentNo"""
  def EmpLabel(tempTableName, queryConditions = ""):
    exec(f"""INSERT INTO Employee_Stg (EmployeeNo, FirstName, LastName, BirthDate, JoinedDate, DepartmentNo)
SELECT
   SRC.in_EmployeeNo,
   SRC.in_FirstName,
   :in_Lastname,
   SRC.in_BirthDate,
   SRC.in_JoinedDate,
   SRC.in_DepartmentNo
FROM {tempTableName} SRC {queryConditions}""")
  #** SSC-FDM-0027 - REMOVED NEXT STATEMENT, NOT APPLICABLE IN SNOWFLAKE. TRANSLATED BELOW **
  #.IMPORT INFILE employee.txt FORMAT VARTEXT ',' LAYOUT Employee APPLY EmpLabel
   
  snowconvert.helpers.import_file_to_temptable(fr"employee.txt", Employee_TableName, Employee_Columns, Employee_Conditions, ',')
  EmpLabel(Employee_TableName)
  exec(f"""DROP TABLE {Employee_TableName}""")

  if con is not None:
    con.close()
    con = None
  snowconvert.helpers.quit_application()

if __name__ == "__main__":
  main()
Copy

Recommendations¶

SSC-FDM-0028¶

Note

This FDM feature is no longer supported. For more information, please see SSC-EWI-0021.

Description¶

This error occurs when your source code contains a node or statement that is not compatible with Snowflake’s functionality.

Example Code¶

Input Code:¶
 WITH my_av ANALYTIC VIEW AS
(USING sales_av HIERARCHIES(time_hier) ADD MEASURES(lag_sales AS (LAG(sales) OVER (HIERARCHY time_hier OFFSET 1 )))) 
SELECT aValue from my_av;
Copy
Output Code:¶
 ----** SSC-FDM-0028 - SubavFactoring NOT SUPPORTED IN SNOWFLAKE **
--WITH my_av ANALYTIC VIEW AS
--(USING sales_av HIERARCHIES(time_hier) ADD MEASURES(lag_sales AS (LAG(sales) OVER (HIERARCHY time_hier OFFSET 1 ))))
--SELECT aValue from my_av
                        ;
Copy

Recommendations¶

  • This error occurs when there is no equivalent Snowflake functionality for the source code being converted.

  • For additional support, please contact us at snowconvert-support@snowflake.com

SSC-FDM-0029¶

Severity¶

Minimal

Description¶

Snowflake’s user-defined functions have different capabilities compared to Oracle or SQL Server. When migrating these functions to Snowflake, they are converted into stored procedures to maintain the same functionality. This conversion will change how you use them in your queries.

Example Code¶

SQL Server:¶
 CREATE OR ALTER FUNCTION PURCHASING.FOO()
RETURNS INT
AS
BEGIN
    DECLARE @i int = 0, @p int;
    Select @p = COUNT(*) FROM PURCHASING.VENDOR
    
    WHILE (@p < 1000)
    BEGIN
        SET @i = @i + 1
        SET @p = @p + @i
    END
        
    IF (@i = 6)
        RETURN 1
    
    RETURN @p
END;
Copy
 --** SSC-FDM-0029 - USER DEFINED FUNCTION WAS TRANSFORMED TO SNOWFLAKE PROCEDURE **
CREATE OR REPLACE PROCEDURE PURCHASING.FOO ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
    DECLARE
        I INT := 0;
        P INT;
    BEGIN
         
        Select
            COUNT(*)
        INTO
            :P
 FROM
            PURCHASING.VENDOR;
        WHILE (:P < 1000) LOOP
            I := :I + 1;
            P := :P + :I;
        END LOOP;
        IF ((:I = 6)) THEN
            RETURN 1;
        END IF;
        RETURN :P;
    END;
$$;
Copy
Oracle:¶
 CREATE FUNCTION employee_function (param1 in NUMBER) RETURN NUMBER is
  var1    employees.employee_ID%TYPE;
  var2    employees.manager_ID%TYPE;
  var3    employees.title%TYPE;
BEGIN
  SELECT employee_ID, manager_ID, title
  INTO var1, var2, var3
  FROM employees
    START WITH manager_ID = param1
    CONNECT BY manager_ID = PRIOR employee_id;
  RETURN var1;
EXCEPTION
   WHEN no_data_found THEN RETURN param1;
END employee_function;
Copy
 --** SSC-FDM-0029 - USER DEFINED FUNCTION WAS TRANSFORMED TO SNOWFLAKE PROCEDURE **
CREATE OR REPLACE PROCEDURE employee_function (param1 NUMBER(38, 18))
RETURNS NUMBER(38, 18)
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "oracle",  "convertedOn": "11/14/2024",  "domain": "test" }}'
EXECUTE AS CALLER
AS
$$
  DECLARE
    var1    employees.employee_ID%TYPE;
    var2    employees.manager_ID%TYPE;
    var3    employees.title%TYPE;
  BEGIN
    SELECT employee_ID, manager_ID, title
    INTO
      :var1,
      :var2,
      :var3
    FROM
      employees
      START WITH manager_ID = :param1
    CONNECT BY
      manager_ID = PRIOR employee_id;
    RETURN :var1;
  EXCEPTION
     WHEN no_data_found THEN
      RETURN :param1;
  END;
$$;
Copy

Best Practices¶

  • Break down complex queries into smaller, individual queries while preserving the original logic.

  • Restructure the source code to align with Snowflake’s user-defined functions approach.

  • For additional assistance, contact us at snowconvert-support@snowflake.com

SSC-FDM-0030¶

Description¶

The identifier contains characters that are not supported in the output language. These characters have been replaced with their corresponding UTF-8 codes.

Example Code¶

Input Code (Oracle):¶
 CREATE PROCEDURE PROC1
AS
    "VAR0" INT;
    "VAR`/1Í·" VARCHAR(20);
    "o*/o" FLOAT;
    " . " INT;
    ". ." INT;
    "123Name" INT;
    "return" INT;
    yield INT;
    ident#10 INT;
BEGIN
    NULL;
END;
Copy
Output Code:¶
 CREATE OR REPLACE PROCEDURE PROC1 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
    DECLARE
        "VAR0" INT;
        --** SSC-FDM-0030 - IDENTIFIER '"VAR`/1Í·"' HAS INVALID CHARACTERS. CHARACTERS WERE REPLACED WITH THEIR UTF-8 CODES **
        VAR_u60_u2F1_uCD_B7 VARCHAR(20);
        --** SSC-FDM-0030 - IDENTIFIER '"o*/o"' HAS INVALID CHARACTERS. CHARACTERS WERE REPLACED WITH THEIR UTF-8 CODES **
        o_u2A_u2Fo FLOAT;
        --** SSC-FDM-0030 - IDENTIFIER '" . "' HAS INVALID CHARACTERS. CHARACTERS WERE REPLACED WITH THEIR UTF-8 CODES **
        _u20_u2E_u20 INT;
        --** SSC-FDM-0030 - IDENTIFIER '". ."' HAS INVALID CHARACTERS. CHARACTERS WERE REPLACED WITH THEIR UTF-8 CODES **
        _u2E_u20_u2E INT;
        "123Name" INT;
        "return" INT;
        yield INT;
        IDENT_HASHTAG_10 INT;
    BEGIN
        NULL;
    END;
$$;
Copy

Recommendations¶

SSC-FDM-0031¶

Description¶

Snowflake converts Materialized Views (and Teradata’s Join Indexes) into Dynamic Tables. When creating Dynamic Tables in Snowflake, you must specify two required parameters:

  • TARGET_LAG: Defines the maximum allowed lag time

  • WAREHOUSE: Specifies which virtual warehouse to use

If you do not specify these parameters in the configuration options, the system will automatically apply default values during the conversion process.

Read more about the required parameters for Dynamic Tables here.

Example Code¶

Input Code (Oracle):¶
 CREATE MATERIALIZED VIEW mv1
AS SELECT * FROM table1;
Copy
Output Code:¶
 CREATE OR REPLACE DYNAMIC TABLE mv1
--** SSC-FDM-0031 - DYNAMIC TABLE REQUIRED PARAMETERS SET BY DEFAULT **
TARGET_LAG='1 day'
WAREHOUSE=UPDATE_DUMMY_WAREHOUSE
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"oracle"}}'
AS
--** SSC-FDM-0001 - VIEWS SELECTING ALL COLUMNS FROM A SINGLE TABLE ARE NOT REQUIRED IN SNOWFLAKE AND MAY IMPACT PERFORMANCE. **
SELECT * FROM
table1;
Copy

Recommendations¶

SSC-FDM-0032¶

Description¶

When performing multiple transformations, SnowConvert needs to verify the parameter values. This verification process can only be completed when the parameters contain actual values (literals) rather than variables or expressions.

This warning appears when SnowConvert cannot determine a parameter’s value because it was passed by reference. As a result, the function or statement cannot be fully transformed.

Example Code¶

Input Code (Redshift):¶
 SELECT TO_CHAR(DATE '2001-01-01', 'YYY/MM/DD'),
TO_CHAR(DATE '2001-01-01', f)
FROM (SELECT 'YYY/MM/DD' as f);
Copy
Output Code:¶
 SELECT
PUBLIC.YEAR_PART_UDF(DATE '2001-01-01', 3) || TO_CHAR(DATE '2001-01-01', '/MM/DD'),
--** SSC-FDM-0032 - PARAMETER 'format_string' IS NOT A LITERAL VALUE, TRANSFORMATION COULD NOT BE FULLY APPLIED **
TO_CHAR(DATE '2001-01-01', f)
FROM (SELECT 'YYY/MM/DD' as f);
Copy

Recommendations¶

SSC-FDM-0033¶

Description¶

This message explains the differences in row sampling behavior between Teradata and Snowflake. While Teradata returns a consistent number of rows in its non-deterministic sampling, Snowflake may return slightly more or fewer rows. This variation in row count is normal and expected in Snowflake due to its probability-based sampling approach.

To ensure consistent and reproducible results when retrieving data from Snowflake, it is recommended to use a seed value in your query. This will generate deterministic output, meaning you’ll get the same values and quantity of results each time you run the query.

Example Code¶

Input Code (Teradata):¶
 SELECT * FROM Employee SAMPLE 2;
SELECT * FROM Employee SAMPLE 0.25;
Copy
Output Code:¶
 SELECT
    * FROM
    Employee
--** SSC-FDM-0033 - SAMPLE CLAUSE BEHAVES DIFFERENTLY IN SNOWFLAKE **
SAMPLE(2 ROWS);

SELECT
    * FROM
    Employee
--** SSC-FDM-0033 - SAMPLE CLAUSE BEHAVES DIFFERENTLY IN SNOWFLAKE **
SAMPLE(25);
Copy

Recommendations¶