SnowConvert: funktionale Unterschiede bei Teradata

SSC-FDM-TD0001

Beschreibung

Diese Meldung erscheint, wenn SnowConvert den Datentyp BLOB erkennt. Da Snowflake BLOB nicht unterstützt, konvertiert es den Datentyp automatisch in BINARY.

Codebeispiel

Eingabecode:
 CREATE TABLE TableExample
(
ColumnExample BLOB
)
Copy
Generierter Code:
 CREATE OR REPLACE TABLE TableExample
(
ColumnExample BINARY /*** SSC-FDM-TD0001 - COLUMN CONVERTED FROM BLOB DATA TYPE ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;
Copy

Best Practices

SSC-FDM-TD0002

Beschreibung

Diese Meldung erscheint, wenn SnowConvert den Datentyp CLOB erkennt. Da SnowConvert CLOB nicht unterstützt, wird der Datentyp automatisch in VARCHAR konvertiert.

Codebeispiel

Eingabecode:
 CREATE TABLE TableExample
(
ColumnExample CLOB
)
Copy
Generierter Code:
 CREATE OR REPLACE TABLE TableExample
(
ColumnExample VARCHAR /*** SSC-FDM-TD0002 - COLUMN CONVERTED FROM CLOB DATA TYPE ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;
Copy

Best Practices

SSC-FDM-TD0003

Beschreibung

Wenn SnowConvert Skriptdateien nach Snowflake Scripting migriert, konvertiert es automatisch Variablenplatzhalter im Bash-Format ($variable oder ${variable}) in das entsprechende SnowSQL-Format (&variable oder &{variable}).

Dieses Skript benötigt SnowSQL, um erfolgreich ausgeführt zu werden. Bevor Sie das migrierte Skript in SnowSQL ausführen, beachten Sie bitte Folgendes:

Beispielcode

Eingabecode:
 .LOGON dbc, dbc;

select '$variable', '${variable}', '${variable}_concatenated';

select $colname from $tablename where info = $id;

select ${colname} from ${tablename} where info = ${id};

.LOGOFF;
Copy
Generierter Code:
-- Additional Params: -q snowscript

EXECUTE IMMEDIATE
$$
  --** SSC-FDM-TD0003 - BASH VARIABLES FOUND, USING SNOWSQL WITH VARIABLE SUBSTITUTION ENABLED IS REQUIRED TO RUN THIS SCRIPT **
  DECLARE
    STATUS_OBJECT OBJECT := OBJECT_CONSTRUCT('SQLCODE', 0);
  BEGIN
    --.LOGON dbc, dbc
    !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'BTLogOn' NODE ***/!!!
    null;
    BEGIN
      SELECT
        '&variable',
        '&{variable}',
        '&{variable}_concatenated';
      STATUS_OBJECT := OBJECT_CONSTRUCT('SQLROWCOUNT', SQLROWCOUNT);
    EXCEPTION
      WHEN OTHER THEN
        STATUS_OBJECT := OBJECT_CONSTRUCT('SQLCODE', SQLCODE, 'SQLERRM', SQLERRM, 'SQLSTATE', SQLSTATE);
    END;
    BEGIN
      SELECT
        &colname
      from
        &tablename
      where
        info = &id;
      STATUS_OBJECT := OBJECT_CONSTRUCT('SQLROWCOUNT', SQLROWCOUNT);
    EXCEPTION
      WHEN OTHER THEN
        STATUS_OBJECT := OBJECT_CONSTRUCT('SQLCODE', SQLCODE, 'SQLERRM', SQLERRM, 'SQLSTATE', SQLSTATE);
    END;
    BEGIN
      SELECT
        &{colname}
      from
        &{tablename}
      where
        info = &{id};
      STATUS_OBJECT := OBJECT_CONSTRUCT('SQLROWCOUNT', SQLROWCOUNT);
    EXCEPTION
      WHEN OTHER THEN
        STATUS_OBJECT := OBJECT_CONSTRUCT('SQLCODE', SQLCODE, 'SQLERRM', SQLERRM, 'SQLSTATE', SQLSTATE);
    END;
    --.LOGOFF
    !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'LogOff' NODE ***/!!!
    null;
  END
$$
Copy

Best Practices

SSC-FDM-TD0004

Beschreibung

Der Datentyp PERIOD von Teradata stellt Zeitintervalle dar. Jede PERIOD hat einen Start- und einen Endwert desselben Typs (TIME, DATE, oder TIMESTAMP). Teradata bietet integrierte Funktionen wie PERIOD, BEGIN, END und OVERLAPS zur Erstellung und Verwaltung dieser Zeitintervalle.

Da Snowflake den Datentyp Period nicht unterstützt, konvertiert SnowConvert diesen Typ und die damit verbundenen Funktionen mithilfe spezieller Transformationsregeln:

  • Period-Datentypdeklarationen in Spaltentabellen werden in zwei Spalten gleichen Typs umgewandelt.

  • Die Period-Wertkonstruktorfunktion ist in zwei separate Konstruktoren aufgeteilt: einen für den Startwert und einen für den Endwert.

  • Funktionen, die Parameter vom Typ Period benötigen, werden in benutzerdefinierte Funktionen (UDFs) konvertiert. Diese UDFs erfordern normalerweise zwei Parameter: einen für den Startwert und einen für den Endwert.

Beispielcode

Eingabecode:
 -- Additional Params: --SplitPeriodDatatype
CREATE TABLE DateTable
(
	COL1 PERIOD(DATE) DEFAULT PERIOD (DATE '2005-02-03', UNTIL_CHANGED)
);
Copy
Generierter Code:
CREATE OR REPLACE TABLE DateTable
(
	COL1_begin DATE DEFAULT DATE '2005-02-03',
	COL1_end DATE DEFAULT DATE '9999-12-31' /*** SSC-FDM-TD0004 - PERIOD DATA TYPES ARE HANDLED AS TWO DATA FIELDS ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
;
Copy

Best Practices

SSC-FDM-TD0005

Beschreibung

Teradata ermöglicht es Benutzern, mit dem Befehl SET TIME ZONE einen beliebigen Zeitzonenoffset zwischen -12:59 und +14:00 festzulegen. Snowflake unterstützt jedoch nur Zeitzonen, die offiziell in der IANA-Zeitzonendatenbank aufgeführt sind.

Wenn Sie SET TIME ZONE mit einem bestimmten Offset verwenden, passt Snowflake diesen automatisch an die nächstgelegene IANA-Standardzeitzone an, wenn der angegebene Offset nicht genau mit einer Standardzeitzone übereinstimmt. Wenn dies geschieht, zeigt Snowflake eine Warnmeldung an, um Sie auf die Anpassung hinzuweisen.

Beispielcode

Eingabecode:
-- Will be rounded to Asia/Colombo (+05:30)
SET TIME ZONE '05:26';
Copy
Generierter Code:
 -- Will be rounded to Asia/Colombo (+05:30)
--** SSC-FDM-TD0005 - NON-STANDARD TIME ZONE OFFSETS NOT SUPPORTED IN SNOWFLAKE, ROUNDED TO NEAREST VALID TIME ZONE **
ALTER SESSION SET TIMEZONE = 'Asia/Colombo';
Copy

Best Practices

SSC-FDM-TD0006

Beschreibung

Diese Meldung erscheint, wenn SnowConvert eine Ansicht erkennt, die die WITH CHECK OPTION-Klausel enthält. Da Snowflake dieses Feature nicht unterstützt, wird die Klausel im konvertierten Code automatisch auskommentiert.

Mit dieser Klausel können Sie INSERT- und UPDATE-Operationen für aktualisierbare Ansichten durchführen. Wenn Sie diese Befehle für die Ansicht ausführen, werden die Änderungen automatisch auf die zugrunde liegende Tabelle angewendet, die mit dieser Ansicht verknüpft ist.

Die WHERE-Klausel filtert die Zeilen, die von dem Befehl in der Ansicht betroffen sind.

Weitere Informationen zu dieser Klausel und ihrer Funktionalität finden Sie in der offiziellen Teradata-Dokumentation.

Beispielcode

Eingabecode:
REPLACE VIEW VIEWWITHOPTIONTEST AS
LOCKING ROW FOR ACCESS
SELECT 
    *        
FROM SOMETABLE
WHERE app_id = 'SUPPLIER'
WITH CHECK OPTION;
Copy
Generierter Code:
 CREATE OR REPLACE VIEW VIEWWITHOPTIONTEST
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
AS
SELECT
    *
FROM
    SOMETABLE
WHERE app_id = 'SUPPLIER'
--    --** SSC-FDM-TD0006 - VIEW WITH OPTION NOT SUPPORTED IN SNOWFLAKE **
--    WITH CHECK OPTION
                     ;
Copy

Best Practices

SSC-FDM-TD0007

Beschreibung

Diese Meldung erscheint, wenn SnowConvert bei der Transformation von Code mit einem Variant-Datentyp auf eine COLLATE-Klausel stößt. Da Variant-Datentypen keine COLLATE-Klauseln unterstützen, entfernt SnowConvert die COLLATE-Klausel und zeigt eine entsprechende Meldung an.

Beispielcode

Eingabecode:
CREATE TABLE TableExample
(
ColumnExample JSON(2500) NOT CASESPECIFIC
)
Copy
Generierter Code:
 CREATE OR REPLACE TABLE TableExample
(
ColumnExample VARIANT
--                      NOT CASESPECIFIC /*** SSC-FDM-TD0007 - VARIANT COLUMN DOES NOT SUPPORT COLLATION ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;
Copy

Der Datentyp JSON wird automatisch in VARIANT konvertiert. Alle NOT CASESPECIFIC-Spezifikationen werden in ihre entsprechende COLLATE-Klausel umgewandelt.

Best Practices

SSC-FDM-TD0008

Beschreibung

Wenn Sie in Snowflake nicht-literale Begrenzungszeichen verwenden, die Leerzeichen enthalten, müssen Sie das Backslash-Zeichen escapen, um die ordnungsgemäße Funktionalität zu gewährleisten.

Beispielcode

Eingabecode
SELECT NVP('store = whole foods&&store: ?Bristol farms','store', '&&', valueDelimiter, 2);
Copy
Ausgabecode
 SELECT
PUBLIC.NVP_UDF('store = whole foods&&store: ?Bristol farms', 'store', '&&', valueDelimiter, 2) /*** SSC-FDM-TD0008 - WHEN NVP_UDF FOURTH PARAMETER IS NON-LITERAL AND IT CONTAINS A BACKSLASH, THAT BACKSLASH NEEDS TO BE ESCAPED ***/;
Copy

Best Practices

SSC-FDM-TD0009

Beschreibung

Diese Meldung erscheint, wenn SnowConvert eine DEFAULT SESSION mit einem anderen Datentyp als VARCHAR erkennt. In solchen Fällen wandelt SnowConvert den Datentyp automatisch in VARCHAR um und erzeugt eine Benachrichtigung.

Codebeispiel

Eingabecode:
 CREATE TABLE TableExample
(
ColumnExample INTEGER DEFAULT SESSION,
ColumnExample2 VARCHAR DEFAULT SESSION
)
Copy
Generierter Code:
 CREATE OR REPLACE TABLE TableExample
(
ColumnExample VARCHAR DEFAULT CURRENT_SESSION() /*** SSC-FDM-TD0009 - CONVERTED FROM INTEGER TO VARCHAR FOR CURRENT_SESSION DEFAULT ***/,
ColumnExample2 VARCHAR DEFAULT CURRENT_SESSION()
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;
Copy

Lassen Sie uns dieses Beispiel untersuchen. Die Spalte mit dem Namen „ColumnExample“ ist mit einem INTEGER-Datentyp definiert und hat die Einstellung DEFAULT SESSION. Da der Datentyp INTEGER und nicht VARCHAR ist, wandelt das System ihn in der Ausgabe automatisch in VARCHAR um.

Der Datentyp von ColumnExample2 bleibt unverändert, da er bereits als VARCHAR definiert ist.

Best Practices

SSC-FDM-TD0010

Beschreibung

Die Teradata-Tabelle DBC.COLUMNSV wird der Snowflake-Tabelle INFORMATION_SCHEMA.COLUMNS zugeordnet. Bitte beachten Sie jedoch Folgendes:

  1. Einige Teradata-Spalten haben keine entsprechenden Spalten in Snowflake.

  2. Wenn Spalten zwischen Systemen übereinstimmen, kann der Dateninhalt unterschiedlich sein.

Eine Beispielansicht der Tabellenstruktur DBC.COLUMNSV in Teradata

Eine Beispielansicht der Tabelle INFORMATION_SCHEMA.COLUMNS in Snowflake

Beachten Sie, dass Snowflake keine entsprechende Spalte für ColumnFormat hat. Außerdem scheint DATA_TYPE zwar der Spalte ColumnType von Teradata zu entsprechen, aber ihre Inhalte unterscheiden sich erheblich.

Codebeispiel

Eingabecode:
 SELECT columnname FROM dbc.columnsV WHERE tablename = 'TableN';
Copy
Generierter Code:
 SELECT
COLUMN_NAME AS COLUMNNAME
FROM
--** SSC-FDM-TD0010 - USES OF TABLE DBC.COLUMNSV ARE CONVERTED TO INFORMATION_SCHEMA.COLUMNS, BUT SOME COLUMNS MIGHT NOT HAVE AND EXACT MATCH IN SNOWFLAKE **
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = 'TableN';
Copy

Best Practices

  • Vergleichen Sie die in Teradata verwendeten Spalten mit den in Snowflake verfügbaren, um sicherzustellen, dass sie Ihren Anforderungen entsprechen.

  • Wenn Sie weitere Hilfe benötigen, kontaktieren Sie uns unter snowconvert-support@snowflake.com

SSC-FDM-TD0011

Beschreibung

Snowflake unterstützt keine Unicode-BMP-Zeichen (Basic Multilingual Plane). Diese Meldung erscheint, wenn SnowConvert durch Unicode-Zeichen begrenzte Teradata-Zeichenliterale, die Unicode-BMP-Escape-Sequenzen enthalten, in das Snowflake-Format konvertiert.

Beispielcode

Eingabecode:
 SELECT U&'hola #+005132 mundo' UESCAPE '#';
Copy
Generierter Code:
 SELECT
--** SSC-FDM-TD0011 - UNICODE BMP IS NOT SUPPORTED IN SNOWFLAKE **
'hola \u+005132 mundo';
Copy

Best Practices

  • Überprüfen Sie, ob es ein Unicode-Zeichen gibt, das Ihren Anforderungen entspricht.

  • Wenn Sie weitere Hilfe benötigen, kontaktieren Sie uns bitte unter snowconvert-support@snowflake.com

SSC-FDM-TD0012

Bemerkung

Diese FDM ist veraltet. Weitere Informationen finden Sie unter SSC-EWI-TD0006.

Beschreibung

Der Datentyp FLOAT unterstützt keine Standardwerte mit der Spezifikation DEFAULT TIME, DEFAULT DATE, DEFAULT CURRENT_DATE, DEFAULT CURRENT_TIME oder DEFAULT CURRENT_TIMESTAMP.

Beispielcode

Teradata:
CREATE TABLE T_2004
(
    -- In the output code all of these columns will be FLOAT type
    -- and will include the SSC-FDM-TD0012 message.
    COL1 FLOAT DEFAULT TIME,
    COL2 FLOAT DEFAULT DATE,
    COL3 FLOAT DEFAULT CURRENT_DATE,
    COL4 FLOAT DEFAULT CURRENT_TIME,
    COL5 FLOAT DEFAULT CURRENT_TIMESTAMP
);
Copy
Snowflake Scripting
 CREATE TABLE T_2004
(
    -- In the output code all of these columns will be FLOAT type
    -- and will include the SSC-FDM-TD0012 message.
    COL1 FLOAT DEFAULT TIME /*** SSC-FDM-TD0012 - DEFAULT CURRENT_TIME NOT VALID FOR DATA TYPE ***/,
    COL2 FLOAT DEFAULT DATE /*** SSC-FDM-TD0012 - DEFAULT CURRENT_DATE NOT VALID FOR DATA TYPE ***/,
    COL3 FLOAT DEFAULT CURRENT_DATE /*** SSC-FDM-TD0012 - DEFAULT CURRENT_DATE NOT VALID FOR DATA TYPE ***/,
    COL4 FLOAT DEFAULT CURRENT_TIME /*** SSC-FDM-TD0012 - DEFAULT CURRENT_TIME NOT VALID FOR DATA TYPE ***/,
    COL5 FLOAT DEFAULT CURRENT_TIMESTAMP /*** SSC-FDM-TD0012 - DEFAULT CURRENT_TIMESTAMP NOT VALID FOR DATA TYPE ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;
Copy

Best Practices

SSC-FDM-TD0013

Beschreibung

Diese Meldung erscheint, weil der in der integrierten Variablen BTEQ ERRORCODE gespeicherte Fehlercode nicht direkt einem entsprechenden Code in Snowflake Scripting zugeordnet werden kann.

Beispielcode

Eingabecode:
SELECT * FROM table1;
 
.IF ERRORCODE<>0 THEN .EXIT 1

.QUIT 0
Copy
Ausgabecode:
 -- Additional Params: -q snowscript

EXECUTE IMMEDIATE
$$
  DECLARE
    STATUS_OBJECT OBJECT := OBJECT_CONSTRUCT('SQLCODE', 0);
  BEGIN
    BEGIN
      SELECT
        *
      FROM
        table1;
      STATUS_OBJECT := OBJECT_CONSTRUCT('SQLROWCOUNT', SQLROWCOUNT);
    EXCEPTION
      WHEN OTHER THEN
        STATUS_OBJECT := OBJECT_CONSTRUCT('SQLCODE', SQLCODE, 'SQLERRM', SQLERRM, 'SQLSTATE', SQLSTATE);
    END;
    IF (STATUS_OBJECT['SQLCODE'] /*** SSC-FDM-TD0013 - THE SNOWFLAKE ERROR CODE MISMATCH THE ORIGINAL TERADATA ERROR CODE ***/ != 0) THEN
      RETURN 1;
    END IF;
    RETURN 0;
  END
$$
Copy

Best Practices

SSC-FDM-TD0014

Beschreibung

Diese Warnung erscheint, wenn Sie BTEQ-Code migrieren, der SQL-Anweisungen aus einer Umgebungsdatei ausführt (zum Beispiel $(<$INPUT_SQL_FILE)). Es gibt einen wichtigen Verhaltensunterschied: Während BTEQ die Ausführung der verbleibenden Anweisungen fortsetzt, selbst wenn eine fehlschlägt, stoppt der generierte Python-Code die Ausführung, wenn er auf einen Fehler stößt.

Beispielcode

Teradata BTEQ:
 .logmech LDAP;
.logon $LOGON_STR;
.SET DEFAULTS;


$(<$INPUT_SQL_FILE)

.export reset
.logoff
.quit
Copy
Python:
#*** Generated code is based on the SnowConvert Python Helpers version 2.0.6 ***

from snowconvert.helpers import exec_file
import os
import sys
import snowconvert.helpers
from snowconvert.helpers import Export
from snowconvert.helpers import exec
from snowconvert.helpers import BeginLoading
con = None
#** SSC-FDM-TD0022 - SHELL VARIABLES FOUND, RUNNING THIS CODE IN A SHELL SCRIPT IS REQUIRED **
def main():
  snowconvert.helpers.configure_log()
  con = snowconvert.helpers.log_on()
  #** SSC-FDM-0027 - REMOVED NEXT STATEMENT, NOT APPLICABLE IN SNOWFLAKE. LOGMECH **
  #.logmech LDAP;
   
  #** SSC-FDM-0027 - REMOVED NEXT STATEMENT, NOT APPLICABLE IN SNOWFLAKE. LOGON **
  #.logon $LOGON_STR
   
  #** SSC-EWI-TD0005 - THE STATEMENT WAS CONVERTED BUT ITS FUNCTIONALITY IS NOT IMPLEMENTED YET **
  Export.defaults()
  #** SSC-FDM-TD0014 - EXECUTION OF FILE WITH SQL STATEMENTS STOPS WHEN AN ERROR OCCURS **
  exec_file("$INPUT_SQL_FILE")
  #** SSC-EWI-TD0005 - THE STATEMENT WAS CONVERTED BUT ITS FUNCTIONALITY IS NOT IMPLEMENTED YET **
  Export.reset()
  #** SSC-FDM-0027 - REMOVED NEXT STATEMENT, NOT APPLICABLE IN SNOWFLAKE. LOGOFF **
  #.logoff
   
  snowconvert.helpers.quit_application()

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

Best Practices

SSC-FDM-TD0015

Bemerkung

Diese FDM wird nicht mehr unterstützt. Weitere Informationen finden Sie unter SSC-EWI-0009.

Beschreibung

Snowflake unterstützt derzeit nur die POSIX Basic Regular Expression-Syntax. Erweiterte Features regulärer Ausdrücke sind nicht verfügbar.

Diese Warnung erscheint immer dann, wenn ein Funktionsaufruf von REGEX_SUBSTR, REGEX_REPLACE oder REGEX_INSTR in Snowflake konvertiert wird. Sie weist Benutzer darauf hin, dass einige Features für reguläre Ausdrücke in Snowflake möglicherweise nicht unterstützt werden. Wichtige nicht unterstützte Features sind lookahead, lookbehind, und non-capturing groups.

Beispielcode

Teradata:
 SELECT REGEXP_SUBSTR('qaqequ','q(?=u)', 1, 1);
Copy
Snowflake Scripting:
 SELECT
--** SSC-FDM-TD0015 - REGEXP_SUBSTR FUNCTION ONLY SUPPORTS POSIX REGULAR EXPRESSIONS **
REGEXP_SUBSTR('qaqequ','q(?=u)', 1, 1);
Copy

Best Practices

  • Überprüfen Sie jedes Muster regulärer Ausdrücke, um festzustellen, ob manuelle Änderungen erforderlich sind. Weitere Einzelheiten über die Regex-Funktionen von SnowFlakeund alternative Optionen finden Sie hier.

  • Wenn Sie weitere Hilfe benötigen, kontaktieren Sie uns unter snowconvert-support@snowflake.com

SSC-FDM-TD0016

Beschreibung

In Teradata enthalten die Funktionen für reguläre Ausdrücke (REGEX_SUBSTR, REGEX_REPLACE und REGEX_INSTR) einen Parameter namens „match_arg“. Dieser Parameter ist ein Zeichenargument, das bestimmte Werte akzeptiert.

  • 'i': Vergleicht Zeichen unabhängig von ihrer Groß-/Kleinschreibung

  • 'c': Vergleicht Zeichen genau, wie sie erscheinen, unter Berücksichtigung der Groß-/Kleinschreibung

  • 'n': Erlaubt einen Punkt (.) für den Vergleich mit Zeilenumbruchzeichen

  • 'm': Behandelt die Eingabezeichenfolge als mehrere separate Zeilen statt als kontinuierliche Zeile

  • 'l': Gibt NULL zurück, wenn die Eingabezeichenfolge größer als 16 MB ist, statt einen Fehler zu generieren

  • 'x': Ignoriert Leerzeichen und Leerraumzeichen im Muster.

Die Funktion akzeptiert mehrere Zeichen als Eingabe.

In Snowflake verwenden diese Funktionen _ regexp_parameters_ als entsprechendes Argument. Dieses Argument ist eine Zeichenfolge, die ein oder mehrere Zeichen enthält, die festlegen, wie sich der Mustervergleich mit regulären Ausdrücken verhalten soll. Folgende Werte werden unterstützt:

  • c: Macht den Mustervergleich abhängig von der Groß-/Kleinschreibung

  • i: Macht den Mustervergleich unabhängig von der Groß-/Kleinschreibung

  • m: Ermöglicht den Vergleich über mehrere Zeilen

  • e: Ermöglicht die Extraktion von Teilmustern aus dem Treffer

  • s: Erlaubt die Verwendung des Platzhalters Punkt (.) für Zeilenumbruchzeichen

Wie Sie sehen, sind die Datentypindikatoren 'i', 'c', 'm' in beiden Sprachen identisch. Der Teradata-Wert 'n' entspricht 's' im Zielsystem. Für die Teradata-Werte 'l' und 'x' gibt es jedoch keine Entsprechungen.

Wenn Sie den Wert 'x' verwenden, wird die Funktionalität mit der Funktion REGEXP_REPLACE repliziert. Der Parameter 'l' kann jedoch nicht repliziert werden, was zu einer Warnmeldung führt.

Eingabecode:

 SELECT REGEXP_SUBSTR('Chip Chop','ch(i|o)p', 1, 1, 'i'), 
       REGEXP_SUBSTR('Chip Chop','ch(i|o)p', 1, 1, 'c'),
       REGEXP_SUBSTR('Chip Chop','ch(i|o)p', 1, 1, 'm'),
       REGEXP_SUBSTR('Chip Chop','ch(i|o)p', 1, 1, 'n'),
       REGEXP_SUBSTR('Chip Chop','ch(i|o)p', 1, 1, 'l'),
       REGEXP_SUBSTR('Chip Chop','ch(i|o)p', 1, 1, 'x');
Copy
Generierter Code:
 SELECT
       REGEXP_SUBSTR('Chip Chop', 'ch(i|o)p', 1, 1, 'i'),
       REGEXP_SUBSTR('Chip Chop', 'ch(i|o)p', 1, 1, 'c'),
       REGEXP_SUBSTR('Chip Chop', 'ch(i|o)p', 1, 1, 'm'),
       REGEXP_SUBSTR('Chip Chop', 'ch(i|o)p', 1, 1, 's'),
       --** SSC-FDM-TD0016 - VALUE 'l' FOR PARAMETER 'match_arg' IS NOT SUPPORTED IN SNOWFLAKE **
       REGEXP_SUBSTR('Chip Chop', 'ch(i|o)p', 1, 1),
       REGEXP_SUBSTR('Chip Chop', 'ch(i|o)p', 1, 1);
Copy

Best Practices

SSC-FDM-TD0017

Bemerkung

Diese FDM ist veraltet. Weitere Informationen finden Sie unter SSC-EWI-TD0076.

Beschreibung

Fremdtabellen in Teradata ermöglichen Ihnen den Zugriff auf Daten, die an externen Speicherorten wie Amazon S3, Azure Blob Storage und Google Cloud Storage gespeichert sind. Snowflake unterstützt diese spezielle Syntax zwar nicht, aber Sie können eine ähnliche Funktionalität erreichen mit:

  • Externe Tabellen

  • Iceberg-Tabellen

  • Standardtabellen

Fremdtabellen

Beispielcode

Eingabecode:
 SELECT cust_id, income, age FROM 
FOREIGN TABLE (SELECT cust_id, income, age FROM twm_customer)@hadoop1 T1;
Copy
Ausgabecode:
 SELECT
cust_id,
income,
age FROM
--** SSC-FDM-TD0017 - THE USE OF FOREIGN TABLES IS NOT SUPPORTED IN SNOWFLAKE. **
 FOREIGN TABLE (SELECT cust_id, income, age FROM twm_customer)@hadoop1 T1;
Copy

Empfehlungen

  • Um Teradata-Fremdtabellen zu ersetzen, können Sie externe Tabellen in Snowflake verwenden. Mit diesen Tabellen können Sie Daten, die in Cloud-Speicherplattformen (Amazon S3, Google Cloud Storage oder Microsoft Azure) gespeichert sind, so abfragen, als ob sie in einer Datenbank gespeichert wären. Externe Tabellen unterstützen alle Datenformate, die mit COPY INTO

  • Die Iceberg-Tabellen von Snowflake bieten eine weitere Lösung. Diese Tabellen verwenden offene Formate und speichern Daten in Parquet-Dateien in Ihrem eigenen Cloud-Speicher.

  • Standard-Snowflake-Tabellen können ähnliche Funktionalität wie Teradata-Fremdtabellen bieten.

  • Wenn Sie weitere Hilfe benötigen, kontaktieren Sie uns bitte unter snowconvert-support@snowflake.com

  • SSC-FDM-TD0018

    Bemerkung

    Diese FDM wird nicht mehr unterstützt. Weitere Informationen finden Sie unter SSC-EWI-TD0063.

    Beschreibung

    Dieser Fehler tritt auf, wenn SnowConvert einen JSON-Pfad nicht verarbeiten kann, weil das Zeichenfolgenformat entweder ungültig ist oder von Snowflake nicht unterstützt wird.

    Beispielcode

    Eingabecode:
     SELECT
        *
    FROM
    JSON_TABLE (
        ON (
            SELECT
                id,
                trainSchedule as ts
            FROM
                demo.PUBLIC.Train T
        ) USING rowexpr('$weekShedule.Monday[*]') colexpr(
            '[{"jsonpath"  "$.time",
                  "type"" : "CHAR ( 12 )"}]'
        )
    ) AS JT(Id, Ordinal, Time, City);
    
    Copy
    Generierter Code:
     SELECT
        *
    FROM
        --** SSC-FDM-TD0018 - UNRECOGNIZED JSON PATH $weekShedule.Monday[*] **
    JSON_TABLE (
        ON
           !!!RESOLVE EWI!!! /*** SSC-EWI-0108 - THE FOLLOWING SUBQUERY MATCHES AT LEAST ONE OF THE PATTERNS CONSIDERED INVALID AND MAY PRODUCE COMPILATION ERRORS ***/!!! (
               SELECT
                   id,
                   trainSchedule as ts
    FROM
                   demo.PUBLIC.Train T
        ) USING rowexpr('$weekShedule.Monday[*]') colexpr(
            '[{"jsonpath"  "$.time",
                  "type"" : "CHAR ( 12 )"}]'
        )
    ) AS JT(Id, Ordinal, Time, City);
    
    Copy

    Empfehlungen

    • Überprüfen Sie, ob der JSON-Pfad korrekt formatiert ist und keine ungültigen Zeichen enthält.

    • Wenn Sie weitere Hilfe benötigen, kontaktieren Sie uns bitte unter snowconvert-support@snowflake.com

    SSC-FDM-TD0019

    Beschreibung

    Mit Teradata können Benutzer Abfragebänder (Metadaten-Tags) auf drei verschiedenen Ebenen festlegen: Transaktion, Sitzung und Profil. Benutzer können diese Abfragebandwerte mit Funktionen wie GetQueryBandValue abrufen.

    Snowflake verwendet den Parameter query_tag anstelle von Abfragebändern. Sie können query_tag auf Sitzungs-, Benutzer- oder Kontoebene festlegen. Beachten Sie, dass Snowflake keine Profile unterstützt.

    Dieses Featuremigrationsdetail (Feature Migration Detail, FMD) weist Benutzer darauf hin, dass Snowflake keine Abfrage-Tags auf Transaktions- oder Profilebene unterstützt. Stattdessen werden als Alternative Abfrage-Tags auf Sitzungsebene verwendet. Diese Änderung kann die Funktionalität in bestimmten Szenarien beeinträchtigen.

    Beispielcode

    Eingabecode:
     SELECT GETQUERYBANDVALUE(3, 'account');
    
    Copy
    Generierter Code
     SELECT
    --** SSC-FDM-TD0019 - TRANSACTION AND PROFILE LEVEL QUERY TAGS NOT SUPPORTED IN SNOWFLAKE, REFERENCING SESSION QUERY TAG INSTEAD **
    GETQUERYBANDVALUE_UDF('account');
    
    Copy

    Empfehlungen

    • Aktualisieren Sie Ihren Code, um Abfragebänder auf Sitzungsebene zu implementieren.

    • Wenn Sie weitere Hilfe benötigen, kontaktieren Sie uns bitte unter snowconvert-support@snowflake.com

    SSC-FDM-TD0020

    Bemerkung

    Der Übersichtlichkeit halber haben wir den Code vereinfacht, indem wir einige Abschnitte weggelassen haben.

    Beschreibung

    Dieser Fehler tritt auf, wenn SnowConvert versucht, JSON-Daten während einer Transformation zu verarbeiten, aber entweder auf falsch formatiertes JSON oder ungültige JSON-Inhalte stößt.

    Beispielcode

    Eingabecode:
     SELECT
    *
    FROM 
     JSON_TABLE
    (ON (SELECT id,
    trainSchedule as ts
    FROM demo.PUBLIC.Train T)
    USING rowexpr('$.weekShedule.Monday[*]')
          colexpr('[ {"ordinal"  true},
                     {"jsonpath"  "$.time",
                      "type"" : "CHAR ( 12 )"},
                     {"jsonpath"  "$.city",
                      "type" : "VARCHAR ( 12 )"}]'))
    AS JT(Id, Ordinal, Time, City);
    
    SELECT
    *
    FROM 
     JSON_TABLE
    (ON (SELECT id, 
    trainSchedule as ts
    FROM demo.PUBLIC.Train T)
    USING rowexpr('$.weekShedule.Monday[*]')
          colexpr('{"jsonpath"  "$.time",
                      "type"" : "CHAR ( 12 )"}'))
    AS JT(Id, Ordinal, Time, City);
    
    Copy
    Generierter Code:
     SELECT
     *
     FROM
     (
      SELECT
       id
      --** SSC-FDM-TD0020 - UNRECOGNIZED JSON LITERAL [ {"ordinal" true}, {"jsonpath" "$.time", "type"" : "CHAR ( 12 )"}, {"jsonpath" "$.city", "type" : "VARCHAR ( 12 )"}] **
      FROM
       demo.PUBLIC.Train T,
       TABLE(FLATTEN(INPUT =>
       trainSchedule:weekShedule.Monday)) rowexpr
     ) JT;
    
     SELECT
     *
     FROM
     (
      SELECT
       id
      --** SSC-FDM-TD0020 - UNRECOGNIZED JSON LITERAL {"jsonpath" "$.time", "type"" : "CHAR ( 12 )"} **
      FROM
       demo.PUBLIC.Train T,
       TABLE(FLATTEN(INPUT =>
       trainSchedule:weekShedule.Monday)) rowexpr
     ) JT;
    
    Copy

    Empfehlungen

    • Vergewissern Sie sich, dass Ihr JSON dem erforderlichen Teradata-Grammatikformat entspricht.

    • Wenn Sie weitere Hilfe benötigen, kontaktieren Sie uns unter snowconvert-support@snowflake.com

    SSC-FDM-TD0021

    Bemerkung

    Diese EWI-Meldung ist veraltet. Aktuelle Informationen entnehmen Sie bitte der Dokumentation zu SSC-EWI-TD0046.

    Beschreibung

    Dieser Fehler tritt auf, wenn Sie eine Abfrage ausführen, die die Tabelle DBC.DATABASES referenziert und versucht, eine Spalte auszuwählen, für die es keine entsprechende Übereinstimmung in Snowflake gibt.

    Beispielcode

    Eingabe:
     CREATE VIEW SAMPLE_VIEW
    AS
    SELECT PROTECTIONTYPE FROM DBC.DATABASES;
    
    Copy
    Ausgabe:
     CREATE OR REPLACE VIEW SAMPLE_VIEW
    COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "teradata",  "convertedOn": "08/14/2024" }}'
    AS
    SELECT
    !!!RESOLVE EWI!!! /*** SSC-EWI-TD0046 - BUILT-IN REFERENCE TO PROTECTIONTYPE IS NOT SUPPORTED IN SNOWFLAKE ***/!!!
    PROTECTIONTYPE FROM
    INFORMATION_SCHEMA.DATABASES;
    
    Copy

    Empfehlungen

    SSC-FDM-TD0022

    Beschreibung

    In Teradata-Skripten dienen Shell-Variablen als temporäre Speichercontainer für Werte, die Sie in Ihrem Skript verwenden und ändern können. Um eine Shell-Variable zu erstellen, verwenden Sie ein Dollarzeichen ($) gefolgt von einem Variablennamen. Optional können Sie den Variablennamen in geschweifte Klammern {} einschließen. Um einer Shell-Variablen einen Wert zuzuweisen, verwenden Sie das Gleichheitszeichen (=).

    #!/bin/bash
    
    ## define a shell variable
    tablename="mytable"
    
    ## use the variable in a Teradata SQL query
    bteq <<EOF
        .LOGON myhost/myuser,mypassword
        SELECT * FROM ${tablename};
        .LOGOFF
    EOF
    
    
    Copy

    Shell-Variablen dienen einem ähnlichen Zweck wie die Zeichenfolgeninterpolation. Wenn Skripte in Python konvertiert werden, behalten Shell-Variablen ihre Funktionalität, indem der konvertierte Code innerhalb eines Shell-Skripts (.sh-Datei) ausgeführt wird. Um diese Funktionalität zu erhalten, müssen die Shell-Variablen im konvertierten Code dem Format des ursprünglichen Eingabecodes entsprechen.

    Beispielcode

    Eingabecode:

     SELECT $column FROM ${tablename}
    
    Copy
    Generierter Code
     #*** Generated code is based on the SnowConvert Python Helpers version 2.0.6 ***
     
    import os
    import sys
    import snowconvert.helpers
    from snowconvert.helpers import Export
    from snowconvert.helpers import exec
    from snowconvert.helpers import BeginLoading
    con = None
    #** SSC-FDM-TD0022 - SHELL VARIABLES FOUND, RUNNING THIS CODE IN A SHELL SCRIPT IS REQUIRED **
    def main():
      snowconvert.helpers.configure_log()
      con = snowconvert.helpers.log_on()
      exec("""
        SELECT
          $column
        FROM
          ${tablename}
        """)
      snowconvert.helpers.quit_application()
    
    if __name__ == "__main__":
      main()
    
    Copy

    Empfehlungen

    • Sie müssen den konvertierten Code mit einem Shell-Skript ausführen.

    • Wenn Sie weitere Hilfe benötigen, kontaktieren Sie uns bitte unter snowconvert-support@snowflake.com

    SSC-FDM-TD0023

    Beschreibung

    Diese Featuredifferenzmeldung (Feature Difference Message, FDM) erscheint, wenn SnowConvert die Ähnlichkeitsfunktion von Teradata in Snowflake konvertiert. Bitte beachten Sie, dass sich das Verhalten der Funktion auf den beiden Plattformen unterscheiden kann.

    Beispielcode

    Nehmen wir die folgenden Daten als Beispiel.

    -Anweisungen kompatibel sind.

    ID

    a

    b

    1

    2

    Gute nacht

    Ich weis nicht

    3

    Ich weiß nicht

    Ich wei? nicht

    4

    Ich weiß nicht

    Ich wei? nicht

    5

    Ich weiß nicht

    Ich weiss nicht

    6

    Snowflake

    Oracle

    7

    święta

    swieta

    8

    NULL

    9

    NULL

    NULL

    Eingabecode:
    -- Additional Params: -q SnowScript
    SELECT * FROM StringSimilarity (
      ON (
        SELECT id, CAST(a AS VARCHAR(200)) AS a, CAST(b AS VARCHAR(200)) AS b
        FROM table_1
      ) PARTITION BY ANY
      USING
      ComparisonColumnPairs ('jaro_winkler(a,b) AS sim_fn')
      Accumulate ('id')
    ) AS dt ORDER BY 1;
    
    Copy
    Idsim_fn
    10
    20.565079365
    31
    40.959047619
    50
    60.611111111
    70.7777777777777777
    80
    90
    Generierter Code
     SELECT
    * FROM
    --** SSC-FDM-TD0023 - STRING SIMILARITY MIGHT HAVE A DIFFERENT BEHAVIOR. **
    (
       SELECT
         id,
         JAROWINKLER_UDF(a, b) AS sim_fn
       FROM table_1
     ) dt ORDER BY 1;
    
    Copy

    ID

    SIM_FN

    1

    0,000000

    2

    0,560000

    3

    0,970000

    4

    0,950000

    5

    0,000000

    6

    0,610000

    7

    0,770000

    8

    0,000000

    9

    0,000000

Empfehlungen

SSC-FDM-TD0024

Beschreibung

Diese Warnung erscheint, wenn SnowConvert eine CREATE TABLE-Anweisung mit der Option SET erkennt. Da Snowflake SET TABLE nicht unterstützt, entfernt SnowConvert diese Option während der Konvertierung.

Beispielcode

Teradata:
 CREATE SET TABLE TableExample
(
ColumnExample Number
)
Copy
 CREATE SET VOLATILE TABLE SOMETABLE, LOG AS 
(SELECT ColumnExample FROM TableExample);
Copy
Snowflake Scripting:
 --** SSC-FDM-TD0024 - SET TABLE FUNCTIONALITY NOT SUPPORTED. TABLE MIGHT HAVE DUPLICATE ROWS **
CREATE OR REPLACE TABLE TableExample
(
ColumnExample NUMBER(38, 18)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;
Copy
 --** SSC-FDM-TD0024 - SET TABLE FUNCTIONALITY NOT SUPPORTED. TABLE MIGHT HAVE DUPLICATE ROWS **
CREATE OR REPLACE TEMPORARY TABLE SOMETABLE
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
AS
(
SELECT
ColumnExample FROM
TableExample
);
Copy

Empfehlungen

SSC-FDM-TD0025

Beschreibung

Die Zeitfeatures der Teradata-Datenbank, zu denen zeitbasierte Tabellen und zeitbasierte Operationen (DDL und DML) gehören, können nicht direkt in Snowflake repliziert werden. Snowflake unterstützt derzeit keine zeitbasierten Tabellen oder zeitbasierte Datenverwaltung in der gleichen Weise wie Teradata. Weitere Informationen über die zeitbasierten Features von Teradata finden Sie unter Teradata Database Temporal Support.

Diese Anweisungen werden von SnowConvert während des Parsens erkannt, aber sie werden während des Übersetzungsprozesses entfernt, um die Kompatibilität mit der Ausführungsumgebung von Snowflake zu gewährleisten.

Wenn eine abort-Anweisung auftritt, wird sie in einen Delete-Befehl umgewandelt. Dadurch wird eine gleichwertige Funktionalität beibehalten, da Sie ein Rollback von Transaktionsoperationen durchführen und die Datenbank in ihrem ursprünglichen Zustand wiederherstellen können.

Beispielcode

Das folgende Beispiel zeigt, wie eine zeitbasierte SELECT-Anweisung in eine SELECT-Standardanweisung konvertiert wird.

Eingabecode:
 SEQUENCED VALIDTIME  
   SELECT
   Policy_ID,
   Customer_ID
   FROM Policy
      WHERE Policy_Type = 'AU';
Copy
Ausgabecode:
 ----** SSC-FDM-TD0025 - TEMPORAL FORMS ARE NOT SUPPORTED IN SNOWFLAKE **
--SEQUENCED VALIDTIME
SELECT
   Policy_ID,
   Customer_ID
   FROM
   Policy
      WHERE Policy_Type = 'AU';
Copy

Wenn ein Rollback einer Transaktion ausgeführt werden muss, wird der Befehl Abort verwendet, um alle während dieser Transaktion vorgenommenen Änderungen rückgängig zu machen.

Eingabecode:
 CREATE OR REPLACE PROCEDURE TEST.ABORT_STATS()
BEGIN
    CURRENT VALIDTIME AND NONSEQUENCED TRANSACTIONTIME ABORT 
     FROM table_1 
     WHERE table_1.x1 = 1;
END;
Copy
Ausgabecode:
 CREATE OR REPLACE PROCEDURE TEST.ABORT_STATS ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
    BEGIN
        --    CURRENT VALIDTIME AND NONSEQUENCED TRANSACTIONTIME
        --** SSC-FDM-TD0025 - TEMPORAL FORMS ARE NOT SUPPORTED IN SNOWFLAKE **
        LET _ROW_COUNT FLOAT;
        SELECT
            COUNT(*)
        INTO
            _ROW_COUNT
            FROM
            table_1
                 WHERE table_1.x1 = 1;
            IF (_ROW_COUNT > 0) THEN
            ROLLBACK;
            END IF;
    END;
$$;
Copy

Empfehlungen

SSC-FDM-TD0026

Bemerkung

Der Übersichtlichkeit halber haben wir den Code vereinfacht, indem wir einige Teile weggelassen haben.

Beschreibung

Bei der Replikation der Funktionalität der SQL-Anweisung IF kombinieren Entwickler häufig die Befehle GOTO mit den Befehlen IF und LABEL. Diese Kombinationen können direkt in if-, if-else- oder if-elseif-else-Anweisungen konvertiert werden. In solchen Fällen sollten Sie die GOTO-Befehle entfernen, damit sie nicht in LABEL-Abschnitte umgewandelt werden, da sie nicht mehr benötigt werden.

Beispielcode

Eingabecode:

 -- Additional Params: --scriptsTargetLanguage SnowScript
.If ActivityCount = 0 THEN .GOTO endIf
DROP TABLE TABLE1;
.Label endIf
SELECT A FROM TABLE1;
Copy

Generierter Code

 EXECUTE IMMEDIATE
$$
  DECLARE
    STATUS_OBJECT OBJECT := OBJECT_CONSTRUCT('SQLCODE', 0);
  BEGIN
    IF (NOT (STATUS_OBJECT['SQLROWCOUNT'] = 0)) THEN
      --** SSC-FDM-TD0026 - GOTO endIf WAS REMOVED DUE TO IF STATEMENT INVERSION **
       
      BEGIN
        DROP TABLE TABLE1;
        STATUS_OBJECT := OBJECT_CONSTRUCT('SQLROWCOUNT', SQLROWCOUNT);
      EXCEPTION
        WHEN OTHER THEN
          STATUS_OBJECT := OBJECT_CONSTRUCT('SQLCODE', SQLCODE, 'SQLERRM', SQLERRM, 'SQLSTATE', SQLSTATE);
      END;
    END IF;
    /*.Label endIf*/
    --** SSC-FDM-0027 - REMOVED NEXT STATEMENT, NOT APPLICABLE IN SNOWFLAKE.  **
     
    BEGIN
      SELECT
        A
      FROM
        TABLE1;
      STATUS_OBJECT := OBJECT_CONSTRUCT('SQLROWCOUNT', SQLROWCOUNT);
    EXCEPTION
      WHEN OTHER THEN
        STATUS_OBJECT := OBJECT_CONSTRUCT('SQLCODE', SQLCODE, 'SQLERRM', SQLERRM, 'SQLSTATE', SQLSTATE);
    END;
  END
$$
Copy
Empfehlungen

SSC-FDM-TD0027

Bemerkung

Diese FDM wird nicht mehr unterstützt. Weitere Informationen finden Sie unter SSC-EWI-TD0061.

Beschreibung

SnowConvert (SC) kann die Funktion TD_UNPIVOT von Teradata transformieren. Mit dieser Funktion können Sie Spaltendaten in Zeilen umwandeln und so die Analyse und Bearbeitung Ihrer Daten erleichtern.

Diese Transformation benötigt Informationen über die Spaltennamen in der/den Tabelle(n), um korrekt zu funktionieren. Wenn diese Informationen nicht verfügbar sind, kann die Umwandlung unvollständig sein, und es können Spalten im Ergebnis fehlen. In solchen Fällen wird eine EWI-Meldung (Error, Warning, Information) erzeugt.

Beispielcode

Eingabecode:
 CREATE TABLE unpivotTable  (
	myKey INTEGER NOT NULL PRIMARY KEY,
	firstSemesterIncome DECIMAL(10,2),
	secondSemesterIncome DECIMAL(10,2),
	firstSemesterExpenses DECIMAL(10,2),
	secondSemesterExpenses DECIMAL(10,2)
);

SELECT * FROM
 TD_UNPIVOT(
 	ON unpivotTable 
 	USING
 	VALUE_COLUMNS('Income', 'Expenses')
 	UNPIVOT_COLUMN('Semester')
 	COLUMN_LIST('firstSemesterIncome, firstSemesterExpenses', 'secondSemesterIncome, secondSemesterExpenses')
 	COLUMN_ALIAS_LIST('First', 'Second')
 )X ORDER BY mykey;

SELECT * FROM
 TD_UNPIVOT(
 	ON unknownTable
 	USING
 	VALUE_COLUMNS('MonthIncome')
 	UNPIVOT_COLUMN('Months')
 	COLUMN_LIST('januaryIncome', 'februaryIncome', 'marchIncome', 'aprilIncome')
 	COLUMN_ALIAS_LIST('January', 'February', 'March', 'April')
 )X ORDER BY yearKey;
Copy
Ausgabecode:
 CREATE TABLE unpivotTable (
	myKey INTEGER NOT NULL PRIMARY KEY,
	firstSemesterIncome DECIMAL(10,2),
	secondSemesterIncome DECIMAL(10,2),
	firstSemesterExpenses DECIMAL(10,2),
	secondSemesterExpenses DECIMAL(10,2)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;

SELECT
	* FROM
	(
		SELECT
			myKey,
			TRIM(GET_IGNORE_CASE(OBJECT_CONSTRUCT('FIRSTSEMESTERINCOME', 'First', 'FIRSTSEMESTEREXPENSES', 'First', 'SECONDSEMESTERINCOME', 'Second', 'SECONDSEMESTEREXPENSES', 'Second'), Semester), '"') AS Semester,
			Income,
			Expenses
		FROM
			unpivotTable UNPIVOT(Income FOR Semester IN (
				firstSemesterIncome,
				secondSemesterIncome
			)) UNPIVOT(Expenses FOR Semester1 IN (
				firstSemesterExpenses,
				secondSemesterExpenses
			))
		WHERE
			Semester = 'FIRSTSEMESTERINCOME'
			AND Semester1 = 'FIRSTSEMESTEREXPENSES'
			OR Semester = 'SECONDSEMESTERINCOME'
			AND Semester1 = 'SECONDSEMESTEREXPENSES'
	) X ORDER BY mykey;

	SELECT
	* FROM
	--** SSC-FDM-TD0027 - TD_UNPIVOT TRANSFORMATION REQUIRES COLUMN INFORMATION THAT COULD NOT BE FOUND, COLUMNS MISSING IN RESULT **
	(
		SELECT
			TRIM(GET_IGNORE_CASE(OBJECT_CONSTRUCT('JANUARYINCOME', 'January', 'FEBRUARYINCOME', 'February', 'MARCHINCOME', 'March', 'APRILINCOME', 'April'), Months), '"') AS Months,
			MonthIncome
		FROM
			unknownTable UNPIVOT(MonthIncome FOR Months IN (
				januaryIncome,
				februaryIncome,
				marchIncome,
				aprilIncome
			))
	) X ORDER BY yearKey;
Copy

Empfehlungen

  • Sie können dem Konvertierungstool Spalteninformationen auf eine der beiden folgenden Arten zur Verfügung stellen:

    • Fügen Sie die Tabellenspezifikation in dieselbe Datei ein wie den Aufruf von TD_UNPIVOT.

    • Listen Sie bestimmte Spalten in der SELECT-Abfrage des ON-Ausdrucks auf, anstatt SELECT * oder nur den Tabellennamen zu verwenden.

  • Wenn Sie ALLE Spalten aus den Eingabetabellen entpivotieren, können Sie dieses Problem ignorieren. Wenn Sie jedoch nur einige Spalten entpivotieren, führt dies zu fehlenden Daten.

  • Wenn Sie zusätzliche Unterstützung benötigen, kontaktieren Sie uns bitte unter snowconvert-support@snowflake.com

SSC-FDM-TD0028

Bemerkung

Diese FDM wird nicht mehr unterstützt. Weitere Informationen finden Sie unter SSC-EWI-TD0060.

Beschreibung

Das Tool SnowConvert kann die Funktion JSON_TABLE umwandeln, aber es muss die spezifischen Spaltennamen kennen, die in der Unterabfrage JSON_TABLE ON ausgewählt werden, um die Umwandlung korrekt durchzuführen.

Diese Warnung erscheint, wenn Spaltennamen in einer Unterabfrage nicht explizit angegeben werden (z. B. bei Verwendung von SELECT *) und das System die Strukturinformationen der Tabelle nicht finden kann. Ohne diese Information kann das System die spezifischen Spaltennamen, auf die verwiesen wird, nicht ermitteln.

Beispielcode

Eingabecode:
 CREATE TABLE demo.Train (
    firstCol INT,
    jsonCol JSON(400),
    thirdCol VARCHAR(30)
);

SELECT * FROM JSON_TABLE 
(ON (SELECT T.*
           FROM demo.Train T)
USING rowexpr('$.schools[*]')
               colexpr('[ {"jsonpath" : "$.name",
                           "type" : "CHAR(20)"},
                          {"jsonpath" : "$.type",
                           "type" : "VARCHAR(20)"}]')
)
AS JT;

SELECT * FROM JSON_TABLE 
(ON (SELECT T.*
           FROM demo.missingTable T)
USING rowexpr('$.schools[*]')
               colexpr('[ {"jsonpath" : "$.name",
                           "type" : "CHAR(20)"},
                          {"jsonpath" : "$.type",
                           "type" : "VARCHAR(20)"}]')
)
AS JT;
Copy
Ausgabecode:
 CREATE TABLE demo.Train (
    firstCol INT,
    jsonCol VARIANT,
    thirdCol VARCHAR(30)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
;

SELECT
    * FROM
    (
        SELECT
            firstCol,
            rowexpr.value:name :: CHAR(20) AS Column_0,
            rowexpr.value:type :: VARCHAR(20) AS Column_1,
            thirdCol
        FROM
            demo.Train T,
            TABLE(FLATTEN(INPUT => jsonCol:schools)) rowexpr
    ) JT;

    SELECT
    * FROM
    --** SSC-FDM-TD0028 - JSON_TABLE NOT TRANSFORMED, COLUMN NAMES COULD NOT BE RETRIEVED FROM SEMANTIC INFORMATION **
    JSON_TABLE
   (ON
       !!!RESOLVE EWI!!! /*** SSC-EWI-0108 - THE FOLLOWING SUBQUERY MATCHES AT LEAST ONE OF THE PATTERNS CONSIDERED INVALID AND MAY PRODUCE COMPILATION ERRORS ***/!!! (
        SELECT
            T.*
                  FROM
            demo.missingTable T)
   USING rowexpr('$.schools[*]')
                  colexpr('[ {"jsonpath" : "$.name",
                           "type" : "CHAR(20)"},
                          {"jsonpath" : "$.type",
                           "type" : "VARCHAR(20)"}]')
   )
   AS JT;
Copy

Empfehlungen

  • Stellen Sie sicher, dass Sie die Tabellendefinition mit einbeziehen, wenn Sie den Code für SnowConvert bereitstellen. Ohne sie müssen Sie den Code erneut ausführen.

  • Wenn Sie weitere Hilfe benötigen, kontaktieren Sie uns unter snowconvert-support@snowflake.com

SSC-FDM-TD0029

Formatierungselemente, die von Sitzungsparametern abhängen

Die folgenden Teradata-Formatelemente sind Snowflake-Funktionen zugeordnet, die bestimmte Sitzungsparametereinstellungen erfordern. Um konsistente Ergebnisse zwischen Teradata und Snowflake zu gewährleisten, müssen Sie diese Sitzungsparameter so konfigurieren, dass sie mit Ihren Teradata-Einstellungen übereinstimmen:

  • D: Der Funktion DAYOFWEEK zugeordnet. Die Ergebnisse unterscheiden sich zwischen Teradata und Snowflake aufgrund der unterschiedlichen Standardeinstellungen. Teradata verwendet den Sonntag als ersten Tag der Woche, während Snowflake den Montag verwendet. Dies wird durch den Sitzungsparameter WEEK_START gesteuert.

  • WW: Der Funktion WEEK zugeordnet. Das Verhalten wird durch den Sitzungsparameter WEEK_OF_YEAR_POLICY gesteuert. Die Standardeinstellung von Snowflake folgt dem ISO-Standard (die erste Woche muss mindestens vier Tage im Januar enthalten). Teradata betrachtet den 1. Januar als den Beginn der ersten Woche.

Um Sitzungsparameter zu ändern, verwenden Sie den Befehl ALTER SESSION SET parameter_name = value. Weitere Einzelheiten zu den verfügbaren Sitzungsparametern finden Sie auf dieser Seite.

Ein-Parameter-Version von TO_CHAR

Die Funktion TO_CHAR(Datetime) mit einem einzigen Parameter verwendet die in Ihren Sitzungsparametern definierten Standardformate für Datum und Uhrzeit. Diese Parameter umfassen:

  • TIMESTAMP_LTZ_OUTPUT_FORMAT

  • TIMESTAMP_NTZ_OUTPUT_FORMAT

  • TIMESTAMP_TZ_OUTPUT_FORMAT

  • TIME_OUTPUT_FORMAT

Um ein konsistentes Verhalten zwischen Teradata und Snowflake zu gewährleisten, stellen Sie sicher, dass diese Parameter mit Ihren Teradata-Einstellungen übereinstimmen.

Bei der Konvertierung von numerischen Werten in Zeichenfolgen mit TO_CHAR(Numeric) verwendet Snowflake automatisch entweder das Format TM9 oder TME, um eine kompakte Zeichenfolgendarstellung zu erzeugen. Da Teradata standardmäßig auch kompakte Zahlendarstellungen erstellt, ist keine zusätzliche Formatierung erforderlich.

Beispielcode

Eingabecode:
 select to_char(date '2008-09-13', 'DD/RM/YYYY');

select to_char(date '2010-10-20', 'DS');

select to_char(1255.495, 'SC9999.9999', 'nls_iso_currency = ''EUR''');

select to_char(45620);
Copy
Ausgabecode:
 SELECT
TO_CHAR(date '2008-09-13', 'DD/') || PUBLIC.ROMAN_NUMERALS_MONTH_UDF(date '2008-09-13') || TO_CHAR(date '2008-09-13', '/YYYY') /*** SSC-FDM-TD0029 - SNOWFLAKE SUPPORTED FORMATS FOR TO_CHAR DIFFER FROM TERADATA AND MAY FAIL OR HAVE DIFFERENT BEHAVIOR ***/;

SELECT
TO_CHAR(date '2010-10-20', 'MM/DD/YYYY') /*** SSC-FDM-TD0029 - SNOWFLAKE SUPPORTED FORMATS FOR TO_CHAR DIFFER FROM TERADATA AND MAY FAIL OR HAVE DIFFERENT BEHAVIOR ***/;

SELECT
PUBLIC.INSERT_CURRENCY_UDF(TO_CHAR(1255.495, 'S9999.0000'), 2, 'EUR') /*** SSC-FDM-TD0029 - SNOWFLAKE SUPPORTED FORMATS FOR TO_CHAR DIFFER FROM TERADATA AND MAY FAIL OR HAVE DIFFERENT BEHAVIOR ***/;

SELECT
TO_CHAR(45620) /*** SSC-FDM-TD0029 - SNOWFLAKE SUPPORTED FORMATS FOR TO_CHAR DIFFER FROM TERADATA AND MAY FAIL OR HAVE DIFFERENT BEHAVIOR ***/;
Copy

Best Practices

  • Wenn Sie mit Formatfunktionen (FF) arbeiten, verwenden Sie DateTime-Typen, die mit der Genauigkeit von Teradata übereinstimmen, oder geben Sie eine Genauigkeit im FORMAT-Element an, um ein konsistentes Verhalten zu gewährleisten.

  • Stellen Sie bei der Formatierung der Zeitzone sicher, dass der erste Parameter vom Typ TIMESTAMP_TZ ist, um konsistente Ergebnisse zu erzielen. Beachten Sie, dass der Datentyp TIME von Snowflake keine Zeitzoneninformationen unterstützt.

  • Konfigurieren Sie die Sitzungsparameter so, dass sie mit den Standardwerten von Teradata übereinstimmen, um ein einheitliches Verhalten zu gewährleisten.

  • Wenn Sie weitere Hilfe benötigen, kontaktieren Sie uns unter snowconvert-support@snowflake.com

SSC-FDM-TD0030

Beschreibung

Wenn SC eine GOTO-Anweisung durch einen LABEL-Abschnitt ersetzt, fügt es automatisch eine RETURN-Anweisung am Ende des Abschnitts ein, falls eine solche nicht vorhanden ist. Dadurch wird sichergestellt, dass der Ausführungsfluss des Programms derselbe bleibt wie im ursprünglichen Code.

Wenn ein BTEQ-GOTO-Befehl ausgeführt wird, werden alle Anweisungen zwischen dem GOTO-Befehl und dem entsprechenden LABEL übersprungen. Um eine unbeabsichtigte Ausführung nach Erreichen des LABEL zu verhindern, sollten Sie eine RETURN-Anweisung in den LABEL-Abschnitt einfügen.

Es ist wichtig zu wissen, dass der GOTO-Befehl alle Anweisungen überspringt, bis er ein passendes LABEL findet. Die Programmausführung wird dann von diesem LABEL aus fortgesetzt. Das Programm führt keine LABEL-Abschnitte aus, die vor dem GOTO-Befehl erscheinen.

Beispielcode

Eingabecode:
 -- Additional Params: --scriptsTargetLanguage SnowScript
.LOGON dbc,dbc;
select 'STATEMENTS';
.GOTO LABEL_B
select 'IGNORED STATEMENTS';
.label LABEL_B
select 'LABEL_B STATEMENTS';
Copy
Ausgabecode
 EXECUTE IMMEDIATE
$$
  DECLARE
    STATUS_OBJECT OBJECT := OBJECT_CONSTRUCT('SQLCODE', 0);
  BEGIN
    -- Additional Params: --scriptsTargetLanguage SnowScript
    --.LOGON dbc,dbc
    !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'BTLogOn' NODE ***/!!!
    null;
    BEGIN
      SELECT
        'STATEMENTS';
      STATUS_OBJECT := OBJECT_CONSTRUCT('SQLROWCOUNT', SQLROWCOUNT);
    EXCEPTION
      WHEN OTHER THEN
        STATUS_OBJECT := OBJECT_CONSTRUCT('SQLCODE', SQLCODE, 'SQLERRM', SQLERRM, 'SQLSTATE', SQLSTATE);
    END;
     
    /*.label LABEL_B*/
     
    BEGIN
      SELECT
        'LABEL_B STATEMENTS';
      STATUS_OBJECT := OBJECT_CONSTRUCT('SQLROWCOUNT', SQLROWCOUNT);
    EXCEPTION
      WHEN OTHER THEN
        STATUS_OBJECT := OBJECT_CONSTRUCT('SQLCODE', SQLCODE, 'SQLERRM', SQLERRM, 'SQLSTATE', SQLSTATE);
    END;
    --** SSC-FDM-TD0030 - A RETURN STATEMENT WAS ADDED AT THE END OF THE LABEL SECTION LABEL_B TO ENSURE THE SAME EXECUTION FLOW **
    RETURN 0;
    BEGIN
      SELECT
        'IGNORED STATEMENTS';
      STATUS_OBJECT := OBJECT_CONSTRUCT('SQLROWCOUNT', SQLROWCOUNT);
    EXCEPTION
      WHEN OTHER THEN
        STATUS_OBJECT := OBJECT_CONSTRUCT('SQLCODE', SQLCODE, 'SQLERRM', SQLERRM, 'SQLSTATE', SQLSTATE);
    END;
    /*.label LABEL_B*/
    --** SSC-FDM-0027 - REMOVED NEXT STATEMENT, NOT APPLICABLE IN SNOWFLAKE.  **
     
    BEGIN
      SELECT
        'LABEL_B STATEMENTS';
      STATUS_OBJECT := OBJECT_CONSTRUCT('SQLROWCOUNT', SQLROWCOUNT);
    EXCEPTION
      WHEN OTHER THEN
        STATUS_OBJECT := OBJECT_CONSTRUCT('SQLCODE', SQLCODE, 'SQLERRM', SQLERRM, 'SQLSTATE', SQLSTATE);
    END;
  END
$$
Copy

Empfehlungen

SSC-FDM-TD0031

Beschreibung

Die Teradata-Funktion ST_SPHERICALDISTANCE verwendet die Haversin-Formel, um die Entfernung zwischen zwei Punkten auf der Erde anhand von Kugelkoordinaten zu berechnen. Im Gegensatz dazu verwendet die Funktion ST_DISTANCE von Snowflake eine andere Methode zur Messung der Entfernung zwischen zwei geografischen Punkten.

Beispielcode

Eingabecode:
 --The distance between New York and Los Angeles
Select Cast('POINT(-73.989308 40.741895)' As ST_GEOMETRY) As location1,
	Cast('POINT(40.741895 34.053691)' As ST_GEOMETRY) As location2,
	location1.ST_SPHERICALDISTANCE(location2) As Distance_In_km;
Copy
Teradata-Ergebnisse

location1

location2

Distance_In_Km

POINT (-73.989308 40.741895)

POINT (40.741895 34.053691)

9351139,978062356

Ausgabecode
 --The distance between New York and Los Angeles
SELECT
	TO_GEOGRAPHY('POINT(-73.989308 40.741895)') As location1,
	TO_GEOGRAPHY('POINT(40.741895 34.053691)') As location2,
	--** SSC-FDM-TD0031 - ST_DISTANCE RESULTS ARE SLIGHTLY DIFFERENT FROM ST_SPHERICALDISTANCE **
	ST_DISTANCE(
	location1, location2) As Distance_In_km;
Copy
Snowflake-Ergebnisse

LOCATION1

LOCATION2

DISTANCE_IN_KM

{ „coordinates“: [ -73.989308, 40.741895 ], „type“: „Point“ }

{ „coordinates“: [ 40.741895, 34.053691 ], „type“: „Point“ }

9351154,65572674

Empfehlungen

SSC-FDM-TD0032

Bemerkung

Der Übersichtlichkeit halber haben wir einige Abschnitte des Ausgabecodes vereinfacht.

Beschreibung

Dieser Fehler tritt auf, wenn ein LIKE-Ausdruck die [NOT] CASESPECIFIC-Klausel enthält.

Beispielcode

Eingabecode:
 SELECT * FROM MY_TABLE
WHERE Name Like 'Marco%' (NOT CASESPECIFIC);
Copy
Ausgabecode
 SELECT
* FROM
MY_TABLE
WHERE Name LIKE 'Marco%' /*** SSC-FDM-TD0032 - NOT CASESPECIFIC CLAUSE WAS REMOVED ***/;
Copy

Empfehlungen

  • Das Verhalten von TERADATA bezüglich der Groß-/Kleinschreibung wird durch die Systemkonfigurationseinstellung TMODE bestimmt.

  • Wenn Sie weitere Hilfe benötigen, kontaktieren Sie uns bitte unter snowconvert-support@snowflake.com

SSC-FDM-TD0033

Beschreibung

Die Statusvariable ACTIVITY_COUNT zeigt an, wie viele Zeilen durch eine DML-Anweisung (wie INSERT, UPDATE oder DELETE) geändert wurden, wenn sie entweder in eingebettetem SQL oder gespeicherten Prozeduren verwendet wird. Weitere Informationen finden Sie hier.

Um das Verhalten von ACTIVITY_COUNT zu replizieren, können Sie die in der Übersetzungsspezifikation beschriebene Problemumgehung verwenden.

 SELECT $1 FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()));
Copy

Es sind jedoch einige Beschränkungen zu beachten:

Einschränkungen

Erster Fall

Wenn Sie ACTIVITY_COUNT mehrfach aufrufen, bevor Sie eine andere DML-Anweisung ausführen, erhalten Sie möglicherweise falsche Ergebnisse. Stellen Sie sicher, dass Sie zwischen jedem Aufruf von ACTIVITY_COUNT eine DML-Anweisung ausführen, um genaue Werte zu erhalten.

 REPLACE PROCEDURE InsertEmployeeSalaryAndLog_1 ()
BEGIN
    DECLARE row_count1 INT;

    INSERT INTO employees (employee_id, first_name, last_name, department_id, salary)
    VALUES (101, 'Alice', 'Smith', 10, 70000.00);

    -- Get the ACTIVITY_COUNT
    SET row_count1 = ACTIVITY_COUNT;
    SET row_count1 = ACTIVITY_COUNT;

    -- Insert the ACTIVITY_COUNT into the activity_log table
    INSERT INTO activity_log (operation, row_count)
    VALUES ('INSERT PROCEDURE', row_count1);
END;

REPLACE PROCEDURE InsertEmployeeSalaryAndLog_2 ()
BEGIN
    DECLARE row_count1 INT;
    DECLARE message VARCHAR(100);

    INSERT INTO employees (employee_id, first_name, last_name, department_id, salary)
    VALUES (101, 'Alice', 'Smith', 10, 70000.00);

    -- Get the ACTIVITY_COUNT
    SET row_count1 = ACTIVITY_COUNT + 1;
    SET row_count1 = ACTIVITY_COUNT;

    -- Insert the ACTIVITY_COUNT into the activity_log table
    INSERT INTO activity_log (operation, row_count)
    VALUES ('INSERT PROCEDURE', row_count1);
END;
Copy
 CREATE OR REPLACE PROCEDURE InsertEmployeeSalaryAndLog_1 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "teradata",  "convertedOn": "07/15/2024" }}'
EXECUTE AS CALLER
AS
$$
    DECLARE
        row_count1 INT;
    BEGIN
         
        INSERT INTO employees (employee_id, first_name, last_name, department_id, salary)
        VALUES (101, 'Alice', 'Smith', 10, 70000.00);

           -- Get the ACTIVITY_COUNT
        row_count1 := (
            SELECT
                $1
            FROM
                TABLE(RESULT_SCAN(LAST_QUERY_ID()))
        ) /*** SSC-FDM-TD0033 - 'ACTIVITY_COUNT' TRANSFORMATION MIGHT REQUIRE MANUAL ADJUSTMENTS ***/;
        row_count1 := (
            SELECT
                $1
            FROM
                TABLE(RESULT_SCAN(LAST_QUERY_ID()))
        ) /*** SSC-FDM-TD0033 - 'ACTIVITY_COUNT' TRANSFORMATION MIGHT REQUIRE MANUAL ADJUSTMENTS ***/;

        -- Insert the ACTIVITY_COUNT into the activity_log table
        INSERT INTO activity_log (operation, row_count)
        VALUES ('INSERT PROCEDURE', :row_count1);
    END;
$$;

CREATE OR REPLACE PROCEDURE InsertEmployeeSalaryAndLog_2 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "teradata",  "convertedOn": "07/15/2024" }}'
EXECUTE AS CALLER
AS
$$
    DECLARE
        row_count1 INT;
        message VARCHAR(100);
    BEGIN
         
         
        INSERT INTO employees (employee_id, first_name, last_name, department_id, salary)
        VALUES (101, 'Alice', 'Smith', 10, 70000.00);

           -- Get the ACTIVITY_COUNT
        row_count1 := (
            SELECT
                $1
            FROM
                TABLE(RESULT_SCAN(LAST_QUERY_ID()))
        ) /*** SSC-FDM-TD0033 - 'ACTIVITY_COUNT' TRANSFORMATION MIGHT REQUIRE MANUAL ADJUSTMENTS ***/ + 1;
        row_count1 := (
            SELECT
                $1
            FROM
                TABLE(RESULT_SCAN(LAST_QUERY_ID()))
        ) /*** SSC-FDM-TD0033 - 'ACTIVITY_COUNT' TRANSFORMATION MIGHT REQUIRE MANUAL ADJUSTMENTS ***/;

        -- Insert the ACTIVITY_COUNT into the activity_log table
        INSERT INTO activity_log (operation, row_count)
        VALUES ('INSERT PROCEDURE', :row_count1);
    END;
$$;
Copy

Wenn Sie ACTIVITY_COUNT in Teradata verwenden, können Sie die Variable mehrfach nach einer DML-Anweisung (wie INSERT) aufrufen, und es wird stets die Anzahl der von dieser Anweisung betroffenen Zeilen zurückgeben. In Snowflake verwendet der transformierte Code jedoch LAST_QUERY_ID(), das sich anders verhält. Das Ergebnis von LAST_QUERY_ID() hängt von der zuletzt ausgeführten Abfrage ab, so dass mehrere Aufrufe möglicherweise nicht denselben Wert liefern, wenn dazwischen andere Abfragen ausgeführt werden.

Die gespeicherte Prozedur InsertEmployeeSalaryAndLog_1() funktioniert, ohne dass Änderungen erforderlich sind. Sie können dies überprüfen, indem Sie den Abfrageverlauf in chronologischer Reihenfolge von unten nach oben durchgehen.

Abfrageverlauf der Ausführung von InsertEmployeeSalaryAndLog_1()

  1. Die INSERT-Anweisung wird zuerst ausgeführt, und LAST_QUERY_ID() referenziert diesen Vorgang.

  2. Die erste SELECT-Anweisung mit ACTIVITY_COUNT wird ausgeführt und setzt $1 auf 1. LAST_QUERY_ID() verweist nun auf diese SELECT-Anweisung.

  3. Die zweite SELECT-Anweisung mit ACTIVITY_COUNT wird ausgeführt. Da die vorangegangene Anweisung 1 zurückgegeben hat, bleibt $1 für diese SELECT-Anweisung 1.

  4. Der Wert 1 wird in row_count1 gespeichert und dann in die Tabelle activity_log eingefügt.

Für die Prozedur InsertEmployeeSalaryAndLog_2() sind manuelle Änderungen erforderlich. Sehen wir uns den Abfrageverlauf in chronologischer Reihenfolge an, beginnend mit den ältesten Einträgen.

Abfrageverlauf mit den Ausführungsergebnissen der Prozedur InsertEmployeeSalaryAndLog_2()

  1. Wenn die INSERT-Anweisung ausgeführt wird, referenziert LAST_QUERY_ID() diese spezielle Anweisung.

  2. Während der ersten SELECT-Anweisung mit ACTIVITY_COUNT ist $1 gleich 1. Allerdings enthält der QUERY_TEXT + 10, wodurch sich das Endergebnis ändert. An dieser Stelle verweist LAST_QUERY_ID() auf diese SELECT-Anweisung.

  3. Wenn die zweite SELECT-Anweisung mit ACTIVITY_COUNT ausgeführt wird, gibt sie aufgrund der vorherigen Abfrage 11 (statt 1) zurück. Dieser Wert wird in $1 gespeichert.

  4. Die Variable row_count1 erhält den Wert 11, der dann in der Tabelle activity_log gespeichert wird.

Die folgenden Werte werden in der Tabelle activity_log gespeichert:

LOG_ID

OPERATION

ROW_COUNT

LOG_TIMESTAMP

1

INSERT PROCEDURE

1

2024-07-15 09:22:21.725

101

INSERT PROCEDURE

11

2024-07-15 09:22:26.248

Anpassungen für den ersten Fall

Laut der Snowflake-Dokumentation für LAST_QUERY_ID können Sie bestimmte Abfragen über eine Positionsnummer abrufen. Beispiel:

  • LAST_QUERY_ID(-1) ruft die letzte Abfrage ab.

  • LAST_QUERY_ID(-2) ruft die zweitletzte Abfrage ab. Und so weiter für ältere Abfragen.

Die Lösung für das Problem in InsertEmployeeSalaryAndLog_2() besteht darin, LAST_QUERY_ID(-2) in der zweiten SELECT-Anweisung zu verwenden, wenn Sie ACTIVITY_COUNT abrufen. Dadurch wird sichergestellt, dass wir die Zeilenzahl aus der vorherigen INSERT-Anweisung erhalten.

 ...
INSERT INTO employees (employee_id, first_name, last_name, department_id, salary)
        VALUES (101, 'Alice', 'Smith', 10, 70000.00);

           -- Get the ACTIVITY_COUNT
        row_count1 := (
            SELECT
                $1
            FROM
                TABLE(RESULT_SCAN(LAST_QUERY_ID()))
        ) /*** SSC-FDM-TD0033 - 'ACTIVITY_COUNT' TRANSFORMATION MIGHT REQUIRE MANUAL ADJUSTMENTS ***/ + 1;
        row_count1 := (
            SELECT
                $1
            FROM
                TABLE(RESULT_SCAN(LAST_QUERY_ID(-2)))
        ) /*** SSC-FDM-TD0033 - 'ACTIVITY_COUNT' TRANSFORMATION MIGHT REQUIRE MANUAL ADJUSTMENTS ***/;
...
Copy

Zweiter Fall

Wenn ACTIVITY_COUNT nach der Ausführung einer Nicht-DML-Anweisung (z. B. SELECT) verwendet wird, gibt sie nicht die korrekte Anzahl der betroffenen Zeilen zurück.

REPLACE PROCEDURE InsertEmployeeSalaryAndLog_3 ()
BEGIN
    DECLARE row_count1 INT;
    DECLARE emp_id INT;
    DECLARE message VARCHAR(100);

    INSERT INTO employees (employee_id, first_name, last_name, department_id, salary)
    VALUES (101, 'Alice', 'Smith', 10, 70000.00);

    SELECT employee_id INTO emp_id FROM employees;
    -- Get the ACTIVITY_COUNT
    SET row_count1 = ACTIVITY_COUNT;
    SET message = 'EMPLOYEE INSERTED - ID: ' || emp_id;

    -- Insert the ACTIVITY_COUNT into the activity_log table
    INSERT INTO activity_log (operation, row_count)
    VALUES (message, row_count1);
END;
Copy
 CREATE OR REPLACE PROCEDURE InsertEmployeeSalaryAndLog_3 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "teradata",  "convertedOn": "07/15/2024" }}'
EXECUTE AS CALLER
AS
$$
    DECLARE
        row_count1 INT;
        emp_id INT;
        message VARCHAR(100);
    BEGIN
         
         
         
        INSERT INTO employees (employee_id, first_name, last_name, department_id, salary)
        VALUES (101, 'Alice', 'Smith', 10, 70000.00);
        SELECT
            employee_id INTO
            :emp_id
        FROM
            employees;
               -- Get the ACTIVITY_COUNT
               row_count1 := (
            SELECT
                $1
            FROM
                TABLE(RESULT_SCAN(LAST_QUERY_ID()))
               ) /*** SSC-FDM-TD0033 - 'ACTIVITY_COUNT' TRANSFORMATION MIGHT REQUIRE MANUAL ADJUSTMENTS ***/;
               message := 'EMPLOYEE INSERTED - ID: ' || emp_id;

               -- Insert the ACTIVITY_COUNT into the activity_log table
               INSERT INTO activity_log (operation, row_count)
               VALUES (:message, :row_count1);
    END;
$$;
Copy

Die Funktion LAST_QUERY_ID gibt einen falschen Wert für row_count1 zurück, da sie die falsche Abfrage referenziert. Sie können dies überprüfen, indem Sie den Abfrageverlauf in umgekehrter chronologischer Reihenfolge durchgehen.

Abfrageverlauf mit den Ergebnissen der Ausführung von InsertEmployeeSalaryAndLog_3()

  1. Zuerst wird eine INSERT Anweisung ausgeführt. Die Funktion LAST_QUERY_ID() referenziert diese INSERT-Operation.

  2. Als nächstes wird eine SELECT INTO-Anweisung ausgeführt, die $1 auf 101 setzt. Die Funktion LAST_QUERY_ID() verweist nun auf diese SELECT INTO-Operation.

  3. Dann wird eine SELECT-Anweisung ausgeführt, um ACTIVITY_COUNT zu erhalten. Da die letzte Abfrage 101 ergab, enthält $1 den Wert 101 anstelle des erwarteten Wertes 1.

  4. Das Ergebnis ist, dass row_count1 101 speichert, was dann in der Tabelle activity_log aufgezeichnet wird.

Die folgenden Werte werden im activity_log aufgezeichnet:

LOG_ID

OPERATION

ROW_COUNT

LOG_TIMESTAMP

1

EMPLOYEE INSERTED - ID: 101

101

2024-07-15 11:00:38.000

Anpassungen für den zweiten Fall

  1. Um dieses Problem zu beheben, verwenden Sie LAST_QUERY_ID mit der richtigen Abfragereferenznummer. Beispiel: LAST_QUERY_ID(-2) ruft die gewünschte Abfrage ab.

 ...
row_count1 := (
            SELECT
                $1
            FROM
                TABLE(RESULT_SCAN(LAST_QUERY_ID(-2)))
               ) /*** SSC-FDM-TD0033 - 'ACTIVITY_COUNT' TRANSFORMATION MIGHT REQUIRE MANUAL ADJUSTMENTS ***/;
               ...
Copy
  1. Sie können den Erfolg der INSERT-Anweisung auch überprüfen, indem Sie ACTIVITY_COUNT mit einer SELECT-Anweisung direkt nach dem Einfügen überprüfen.

...
INSERT INTO employees (employee_id, first_name, last_name, department_id, salary)
VALUES (101, 'Alice', 'Smith', 10, 70000.00);
-- Get the ACTIVITY_COUNT
       row_count1 := (
    SELECT
        $1
    FROM
        TABLE(RESULT_SCAN(LAST_QUERY_ID()))
       ) /*** SSC-FDM-TD0033 - 'ACTIVITY_COUNT' TRANSFORMATION MIGHT REQUIRE MANUAL ADJUSTMENTS ***/;
SELECT
    employee_id INTO
    :emp_id
FROM
    employees;
       message := 'EMPLOYEE INSERTED - ID: ' || emp_id;
...
Copy

Empfehlungen

  • Wenn Sie LAST_QUERY_ID verwenden, vergewissern Sie sich, dass Sie die gewünschte Abfrage referenzieren.

  • Führen Sie ACTIVITY_COUNT unmittelbar nach Ihrer DML-Anweisung aus, um eine genaue Auswertung zu gewährleisten.

  • Wenn Sie weitere Hilfe benötigen, kontaktieren Sie uns unter snowconvert-support@snowflake.com