SnowConvert : différences fonctionnelles de Teradata

SSC-FDM-TD0001

Description

Ce message apparaît lorsque SnowConvert détecte un type de données BLOB. Comme Snowflake ne prend pas en charge BLOB, il convertit automatiquement le type de données en type binaire.

Exemple de code

Code d’entrée :
 CREATE TABLE TableExample
(
ColumnExample BLOB
)
Copy
Code généré :
 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

Meilleures pratiques

  • Aucune action n’est requise de votre part.

  • Pour une assistance supplémentaire, veuillez nous contacter à l’adresse suivante : snowconvert-support@snowflake.com

SSC-FDM-TD0002

Description

Ce message apparaît lorsque SnowConvert rencontre un type de données CLOB. Comme SnowConvert ne prend pas en charge CLOB, il le convertit automatiquement en VARCHAR.

Exemple de code

Code d’entrée :
 CREATE TABLE TableExample
(
ColumnExample CLOB
)
Copy
Code généré :
 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

Meilleures pratiques

  • Aucune action n’est requise de votre part.

  • Pour une assistance supplémentaire, veuillez nous contacter à l’adresse suivante : snowconvert-support@snowflake.com

SSC-FDM-TD0003

Description

Lorsque SnowConvert migre des fichiers de script vers Snowflake Scripting, il convertit automatiquement les caractères de remplacement des variables de style Bash ($variable ou ${variable}) dans leur format équivalent SnowSQL (&variable ou &{variable}).

Ce script nécessite SnowSQL pour être exécuté correctement. Avant d’exécuter le script migré dans SnowSQL, veuillez noter ce qui suit :

Exemple de code

Code d’entrée :
 .LOGON dbc, dbc;

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

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

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

.LOGOFF;
Copy
Code généré :
-- 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

Meilleures pratiques

SSC-FDM-TD0004

Description

Le type de données PERIOD de Teradata représente les intervalles de temps. Chaque PERIOD a une valeur de départ et une valeur d’arrivée du même type (TIME, DATE ou TIMESTAMP). Teradata fournit des fonctions intégrées telles que PERIOD, BEGIN, END et OVERLAPS pour créer et gérer ces intervalles de temps.

Snowflake ne prenant pas en charge le type de données période, SnowConvert convertit ce type et ses fonctions associées à l’aide de règles de transformation spécifiques :

  • Les déclarations de type période dans les tables de colonnes sont converties en deux colonnes de type identique.

  • La fonction de construction de la valeur de la période est divisée en deux constructeurs distincts : un pour la valeur de départ et un pour la valeur d’arrivée.

  • Les fonctions qui nécessitent des paramètres de type période sont converties en fonctions définies par l’utilisateur (UDFs). Ces UDFs nécessitent généralement deux paramètres : un pour la valeur de départ et un pour la valeur d’arrivée.

Exemple de code

Code d’entrée :
 -- Additional Params: --SplitPeriodDatatype
CREATE TABLE DateTable
(
	COL1 PERIOD(DATE) DEFAULT PERIOD (DATE '2005-02-03', UNTIL_CHANGED)
);
Copy
Code généré :
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

Meilleures pratiques

SSC-FDM-TD0005

Description

Teradata permet aux utilisateurs de définir un décalage de fuseau horaire entre -12:59 et +14:00 à l’aide de la commande SET TIME ZONE. Cependant, Snowflake ne prend en charge que les fuseaux horaires officiellement annoncés dans la base de données des fuseaux horairesIANA.

Lorsque vous utilisez SET TIME ZONE avec un décalage spécifique, Snowflake l’ajustera automatiquement pour qu’il corresponde au fuseau horaire standard IANA le plus proche si le décalage spécifié ne correspond pas exactement à un fuseau horaire standard. Lorsque cela se produit, Snowflake affiche un message d’avertissement pour vous avertir de l’ajustement.

Exemple de code

Code d’entrée :
-- Will be rounded to Asia/Colombo (+05:30)
SET TIME ZONE '05:26';
Copy
Code généré :
 -- 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

Meilleures pratiques

  • Aucune action n’est requise de votre part.

  • Pour une assistance supplémentaire, veuillez nous contacter à l’adresse suivante : snowconvert-support@snowflake.com

SSC-FDM-TD0006

Description

Ce message apparaît lorsque SnowConvert détecte une vue contenant la clause WITH CHECK OPTION. Snowflake ne prenant pas en charge cette fonction, la clause est automatiquement commentée dans le code converti.

Cette clause vous permet d’effectuer les opérations INSERT et UPDATE sur les vues actualisables. Lorsque vous exécutez ces commandes sur la vue, les modifications sont automatiquement appliquées à la table sous-jacente associée à cette vue.

La clause WHERE filtre les lignes qui seront affectées par la commande dans la vue.

Pour plus d’informations sur cette clause et ses fonctionnalités, veuillez vous référer à la documentation officielle de Teradata.

Exemple de code

Code d’entrée :
REPLACE VIEW VIEWWITHOPTIONTEST AS
LOCKING ROW FOR ACCESS
SELECT 
    *        
FROM SOMETABLE
WHERE app_id = 'SUPPLIER'
WITH CHECK OPTION;
Copy
Code généré :
 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

Meilleures pratiques

SSC-FDM-TD0007

Description

Ce message apparaît lorsque SnowConvert rencontre une clause COLLATE lors de la transformation de code avec un type de données Variante. Étant donné que les types de données variantes ne prennent pas en charge les clauses COLLATE, SnowConvert supprimera la clause COLLATE et affichera un message de notification.

Exemple de code

Code d’entrée :
CREATE TABLE TableExample
(
ColumnExample JSON(2500) NOT CASESPECIFIC
)
Copy
Code généré :
 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

Le type de données JSON est automatiquement converti en VARIANT. Toute spécification NOT CASESPECIFIC est transformée en clause équivalente COLLATE.

Meilleures pratiques

  • Aucune action n’est requise de votre part.

  • Pour une assistance supplémentaire, veuillez nous contacter à l’adresse suivante : snowconvert-support@snowflake.com

SSC-FDM-TD0008

Description

Lorsque vous utilisez des délimiteurs non littéraux contenant des espaces dans Snowflake, vous devez échapper le caractère d’échappement pour garantir une bonne fonctionnalité.

Exemple de code

Code d’entrée
SELECT NVP('store = whole foods&&store: ?Bristol farms','store', '&&', valueDelimiter, 2);
Copy
Code de sortie
 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

Meilleures pratiques

SSC-FDM-TD0009

Description

Ce message apparaît lorsque SnowConvert détecte un DEFAULT SESSION dont le type de données est différent de VARCHAR. Dans de tels cas, SnowConvert convertit automatiquement le type de données en VARCHAR et génère un message de notification.

Exemple de code

Code d’entrée :
 CREATE TABLE TableExample
(
ColumnExample INTEGER DEFAULT SESSION,
ColumnExample2 VARCHAR DEFAULT SESSION
)
Copy
Code généré :
 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

Examinons cet exemple. La colonne nommée « ColumnExample » est définie avec un type de données INTEGER et possède un paramètre DEFAULT SESSION. Comme le type de données est INTEGER et non VARCHAR, le système le convertit automatiquement en VARCHAR dans la sortie.

Le type de données de ColumnExample2 reste inchangé car il est déjà défini comme VARCHAR.

Meilleures pratiques

  • Aucune action n’est requise de votre part.

  • Pour une assistance supplémentaire, veuillez nous contacter à l’adresse suivante : snowconvert-support@snowflake.com

SSC-FDM-TD0010

Description

La table Teradata DBC.COLUMNSV est mappée à la table Snowflake INFORMATION_SCHEMA.COLUMNS. Toutefois, veuillez noter que :

  1. Certaines colonnes de Teradata n’ont pas de colonnes correspondantes dans Snowflake

  2. Lorsque les colonnes correspondent d’un système à l’autre, le contenu des données peut être différent

Une vue échantillon de la structure de la table DBC.COLUMNSV dans Teradata

Une vue échantillon de la table INFORMATION_SCHEMA.COLUMNS dans Snowflake

Remarquez que Snowflake n’a pas de colonne équivalente pour « ColumnFormat ». En outre, bien que la colonne « DATA_TYPE » semble correspondre à la colonne « ColumnType » de Teradata, leur contenu est sensiblement différent.

Exemple de code

Code d’entrée :
 SELECT columnname FROM dbc.columnsV WHERE tablename = 'TableN';
Copy
Code généré :
 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

Meilleures pratiques

  • Comparez les colonnes utilisées dans Teradata avec celles disponibles dans Snowflake pour vous assurer qu’elles répondent à vos exigences.

  • Pour toute assistance supplémentaire, contactez-nous à l’adresse suivante : snowconvert-support@snowflake.com

SSC-FDM-TD0011

Description

Snowflake ne prend pas en charge les caractères Unicode Basic Multilingual Plane (BMP). Ce message s’affiche lorsque SnowConvert convertit au format Snowflake de Teradata Unicode Delimited Character Literal contenant des séquences d’échappement Unicode BMP.

Exemple de code

Code d’entrée :
 SELECT U&'hola #+005132 mundo' UESCAPE '#';
Copy
Code généré :
 SELECT
--** SSC-FDM-TD0011 - UNICODE BMP IS NOT SUPPORTED IN SNOWFLAKE **
'hola \u+005132 mundo';
Copy

Meilleures pratiques

  • Vérifiez s’il existe un caractère Unicode correspondant à vos exigences.

  • Pour toute assistance supplémentaire, veuillez nous contacter à l’adresse suivante : snowconvert-support@snowflake.com

SSC-FDM-TD0012

Note

Cette FDM a été supprimée. Pour plus d’informations, veuillez consulter SSC-EWI-TD0006.

Description

Le type de données FLOAT ne prend pas en charge les valeurs par défaut à l’aide des spécifications DEFAULT TIME, DEFAULT DATE, DEFAULT CURRENT_DATE, DEFAULT CURRENT_TIME ou DEFAULT CURRENT_TIMESTAMP.

Exemple de code

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
Exécution de scripts Snowflake
 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

Meilleures pratiques

  • Aucune action n’est requise de votre part.

  • Pour une assistance supplémentaire, veuillez nous contacter à l’adresse suivante : snowconvert-support@snowflake.com

SSC-FDM-TD0013

Description

Ce message apparaît parce que le code d’erreur stocké dans la variable intégrée BTEQ ERRORCODE ne peut pas être directement mappé à un code équivalent dans Snowflake Scripting.

Exemple de code

Code d’entrée :
SELECT * FROM table1;
 
.IF ERRORCODE<>0 THEN .EXIT 1

.QUIT 0
Copy
Code de sortie :
 -- 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

Meilleures pratiques

SSC-FDM-TD0014

Description

Cet avertissement apparaît lors de la migration du code BTEQ qui exécute des instructions SQL à partir d’un fichier d’environnement (par exemple, $(<$INPUT_SQL_FILE)). Il convient de noter une différence de comportement importante : alors que BTEQ continue d’exécuter les instructions restantes même si l’une d’entre elles échoue, le code généré par Python arrête son exécution dès qu’il rencontre une erreur.

Exemple de code

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

Meilleures pratiques

SSC-FDM-TD0015

Note

Ce FDM n’est plus pris en charge. Pour plus d’informations, veuillez consulter SSC-EWI-0009.

Description

Snowflake ne prend en charge actuellement que la syntaxe POSIX Basic Regular Expression. Les fonctions avancées d’expression régulière ne sont pas disponibles.

Cet avertissement apparaît chaque fois qu’un appel de fonction à REGEX_SUBSTR, REGEX_REPLACE ou REGEX_INSTR est converti en Snowflake. Il alerte les utilisateurs sur le fait que certaines fonctions d’expression régulière peuvent ne pas être prises en charge par Snowflake. Les fonctions importantes non prises en charge sont lookahead, lookbehind et non-capturing groups.

Exemple de code

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

Meilleures pratiques

  • Examinez chaque modèle d’expression régulière pour déterminer si des modifications manuelles sont nécessaires. Pour plus de détails sur les capacités regex de SnowFlake et les options alternatives, voir ici.

  • Pour toute assistance supplémentaire, contactez-nous à l’adresse suivante : snowconvert-support@snowflake.com

SSC-FDM-TD0016

Description

Dans Teradata, les fonctions d’expression régulière (REGEX_SUBSTR, _REGEX_REPLACE et REGEX_INSTR) comprennent un paramètre appelé « match_arg ». Ce paramètre est un argument de caractère qui accepte des valeurs spécifiques.

  • 'i' : correspond aux caractères quelle que soit leur casse (majuscule ou minuscule).

  • 'c' : recherche les caractères tels qu’ils apparaissent, en tenant compte de la casse.

  • 'n' : permet au point (.) de correspondre aux caractères de nouvelle ligne.

  • 'm' : traite la chaîne d’entrée comme plusieurs lignes séparées plutôt que comme une seule ligne continue.

  • 'l' : renvoie NULL lorsque la chaîne d’entrée est plus grande que 16 MB, au lieu de générer une erreur.

  • 'x' : ignore les espaces et les caractères d’espacement dans le modèle.

La fonction accepte plusieurs caractères en entrée.

Dans Snowflake, ces fonctions utilisent _ regexp_parameters_ comme argument équivalent. Cet argument est une chaîne contenant un ou plusieurs caractères qui définissent le comportement de la recherche de modèles d’expressions régulières. Les valeurs prises en charge sont les suivantes :

  • c : rend la recherche de modèles sensible à la casse

  • i : rend le modèle insensible à la casse

  • m : permet la correspondance entre plusieurs lignes

  • e : permet d’extraire des sous-modèles de la correspondance

  • s : permet au caractère générique point (.) de correspondre aux caractères de la nouvelle ligne

Comme indiqué, les indicateurs de type de données 'i', 'c', 'm' sont identiques dans les deux langues. La valeur Teradata 'n' correspond à 's' dans le système cible. Toutefois, les valeurs Teradata 'l' et 'x' n’ont pas d’équivalents correspondants.

Lorsque vous utilisez la valeur 'x', la fonctionnalité est répliquée à l’aide de la fonction REGEXP_REPLACE. Cependant, le paramètre 'l' ne peut pas être répliqué, ce qui entraîne un message d’avertissement.

Code d’entrée :

 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
Code généré :
 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

Meilleures pratiques

SSC-FDM-TD0017

Note

Cette FDM a été supprimée. Pour plus d’informations, veuillez consulter SSC-EWI-TD0076.

Description

Les tables étrangères dans Teradata vous permettent d’accéder aux données stockées dans des emplacements externes comme Amazon S3, Azure Blob storage et Google Cloud Storage. Bien que Snowflake ne prenne pas en charge pas cette syntaxe spécifique, vous pouvez obtenir une fonctionnalité similaire en utilisant :

  • Tables externes

  • Tables Iceberg

  • Tables standards

Tables étrangères

Exemple de code

Code d’entrée :
 SELECT cust_id, income, age FROM 
FOREIGN TABLE (SELECT cust_id, income, age FROM twm_customer)@hadoop1 T1;
Copy
Code de sortie :
 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

Recommandations

  • Pour remplacer les tables étrangères de Teradata, vous pouvez utiliser les tables externes de Snowflake. Ces tables vous permettent d’interroger les données stockées dans les plateformes de stockage Cloud (Amazon S3, Google Cloud Storage ou Microsoft Azure) comme si elles se trouvaient dans une base de données. Les tables externes prennent en charge tous les formats de données compatibles avec les instructions COPY INTO

  • Les tables Iceberg de Snowflake offrent une autre solution. Ces tables utilisent des formats ouverts et stockent les données dans des fichiers Parquet au sein de votre propre stockage Cloud.

  • Les tables standard de Snowflake peuvent également offrir des fonctions similaires à celles des tables étrangères de Teradata.

  • Pour toute assistance supplémentaire, veuillez nous contacter à l’adresse suivante : snowconvert-support@snowflake.com

  • SSC-FDM-TD0018

    Note

    Ce FDM n’est plus pris en charge. Pour plus d’informations, veuillez consulter SSC-EWI-TD0063.

    Description

    Cette erreur se produit lorsque SnowConvert n’est pas en mesure de traiter un chemin JSON parce que le format de la chaîne n’est pas valide ou n’est pas pris en charge par Snowflake.

    Exemple de code

    Code d’entrée :
     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
    Code généré :
     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

    Recommandations

    • Vérifiez que le chemin JSON est correctement formaté et qu’il ne contient pas de caractères non valides.

    • Pour toute assistance supplémentaire, veuillez nous contacter à l’adresse suivante : snowconvert-support@snowflake.com

    SSC-FDM-TD0019

    Description

    Teradata permet aux utilisateurs de définir des bandes de requête (balises de métadonnées) à trois niveaux différents : transaction, session et profil. Les utilisateurs peuvent récupérer les valeurs de ces bandes de requête à l’aide de fonctions telles que GetQueryBandValue.

    Snowflake utilise le paramètre query_tag au lieu des bandes de requête. Vous pouvez définir query_tag au niveau de la session, de l’utilisateur ou du compte. Notez que Snowflake ne prend pas en charge les profils.

    Ce détail de la migration des fonctions (FMD) alerte les utilisateurs sur le fait que Snowflake ne prend pas en charge les balises de requête au niveau des transactions ou des profils. En lieu et place, des balises de requête au niveau de la session seront utilisées comme alternative. Cette modification peut affecter la fonctionnalité dans certains scénarios.

    Exemple de code

    Code d’entrée :
     SELECT GETQUERYBANDVALUE(3, 'account');
    
    Copy
    Code généré
     SELECT
    --** SSC-FDM-TD0019 - TRANSACTION AND PROFILE LEVEL QUERY TAGS NOT SUPPORTED IN SNOWFLAKE, REFERENCING SESSION QUERY TAG INSTEAD **
    GETQUERYBANDVALUE_UDF('account');
    
    Copy

    Recommandations

    • Mettez à jour votre code pour mettre en œuvre les bandes de requête au niveau de la session.

    • Pour toute assistance supplémentaire, veuillez nous contacter à l’adresse suivante : snowconvert-support@snowflake.com

    SSC-FDM-TD0020

    Note

    Par souci de clarté, nous avons simplifié le code en omettant certaines sections.

    Description

    Cette erreur se produit lorsque SnowConvert tente de traiter les données JSON au cours d’une transformation, mais rencontre un contenu JSON mal formaté ou JSON non valide.

    Exemple de code

    Code d’entrée :
     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
    Code généré :
     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

    Recommandations

    • Vérifiez que votre JSON respecte le format de grammaire Teradata requis.

    • Pour toute assistance supplémentaire, contactez-nous à l’adresse suivante : snowconvert-support@snowflake.com

    SSC-FDM-TD0021

    Note

    Cet EWI a été supprimé. Veuillez vous référer à la documentation SSC-EWI-TD0046 pour obtenir des informations actualisées.

    Description

    Cette erreur se produit lors de l’exécution d’une requête qui fait référence à la table DBC.DATABASES et qui tente de sélectionner une colonne qui n’a pas de correspondance dans Snowflake.

    Exemple de code

    Entrée :
     CREATE VIEW SAMPLE_VIEW
    AS
    SELECT PROTECTIONTYPE FROM DBC.DATABASES;
    
    Copy
    Sortie :
     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

    Recommandations

    SSC-FDM-TD0022

    Description

    Dans les scripts Teradata, les variables shell servent de conteneurs de stockage temporaire pour les valeurs que vous pouvez utiliser et modifier tout au long de votre script. Pour créer une variable shell, utilisez le signe du dollar ($) suivi du nom de la variable. Vous pouvez éventuellement entourer le nom de la variable d’accolades {}. Pour attribuer une valeur à une variable de l’interpréteur de commandes, utilisez le signe égal (=).

    #!/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

    Les variables Shell ont un rôle similaire à celui de l’interpolation de chaînes. Lorsque les scripts sont convertis en Python, les variables shell conservent leur fonctionnalité en exécutant le code converti au sein d’un script shell (fichier .sh). Pour préserver cette fonctionnalité, les variables du shell dans le code converti doivent correspondre au format du code d’entrée original.

    Exemple de code

    Code d’entrée :

     SELECT $column FROM ${tablename}
    
    Copy
    Code généré
     #*** 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

    Recommandations

    • Vous devez exécuter le code converti à l’aide d’un script shell.

    • Pour toute assistance supplémentaire, veuillez nous contacter à l’adresse suivante : snowconvert-support@snowflake.com

    SSC-FDM-TD0023

    Description

    Ce message de différence de fonction (FDM) apparaît lorsque SnowConvert convertit la fonction de similitude de Teradata en Snowflake. Veuillez noter que le comportement de la fonction peut différer entre les deux plateformes.

    Exemple de code

    Prenons l’exemple des données suivantes

    .

    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

    Code d’entrée :
    -- 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
    Code généré
     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

Recommandations

SSC-FDM-TD0024

Description

Cet avertissement apparaît lorsque SnowConvert détecte une instruction CREATE TABLE avec l’option SET. Snowflake ne prenant pas en charge SET TABLE, SnowConvert supprime cette option lors de la conversion.

Exemple de code

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

Recommandations

SSC-FDM-TD0025

Description

Les fonctions temporelles de la base de données Teradata, qui comprennent les tables temporelles et les opérations basées sur le temps (DDL et DML), ne peuvent pas être répliquées directement dans Snowflake. Snowflake ne prend pas en charge actuellement les tables temporelles ou la gestion des données en fonction du temps de la même manière que Teradata. Pour plus d’informations sur les fonctions temporelles de Teradata, voir Prise en charge temporelle de la base de données Teradata.

Ces instructions sont reconnues par SnowConvert lors de l’analyse syntaxique, mais elles sont supprimées lors du processus de traduction afin d’assurer la compatibilité avec l’environnement d’exécution de Snowflake.

Lorsqu’une instruction abort est rencontrée, elle sera convertie en une commande Delete. Cela permet de conserver des fonctionnalités équivalentes en vous permettant d’annuler les opérations de transaction et de restaurer la base de données dans son état d’origine.

Exemple de code

L’exemple suivant montre comment une instruction Select de forme temporelle est convertie en une instruction Select standard.

Code d’entrée :
 SEQUENCED VALIDTIME  
   SELECT
   Policy_ID,
   Customer_ID
   FROM Policy
      WHERE Policy_Type = 'AU';
Copy
Code de sortie :
 ----** SSC-FDM-TD0025 - TEMPORAL FORMS ARE NOT SUPPORTED IN SNOWFLAKE **
--SEQUENCED VALIDTIME
SELECT
   Policy_ID,
   Customer_ID
   FROM
   Policy
      WHERE Policy_Type = 'AU';
Copy

Lorsqu’une transaction doit être annulée, la commande Abort est utilisée pour annuler toutes les modifications apportées au cours de cette transaction.

Code d’entrée :
 CREATE OR REPLACE PROCEDURE TEST.ABORT_STATS()
BEGIN
    CURRENT VALIDTIME AND NONSEQUENCED TRANSACTIONTIME ABORT 
     FROM table_1 
     WHERE table_1.x1 = 1;
END;
Copy
Code de sortie :
 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

Recommandations

  • Aucune action n’est requise de votre part.

  • Pour une assistance supplémentaire, veuillez nous contacter à l’adresse suivante : snowconvert-support@snowflake.com

SSC-FDM-TD0026

Note

Pour plus de clarté, nous avons simplifié le code en omettant certaines parties.

Description

Lorsqu’ils répliquent la fonctionnalité de l’instruction SQL IF, les développeurs combinent souvent les commandes GOTO avec les commandes IF et LABEL. Ces combinaisons peuvent être directement converties en instructions if, if-else ou if-elseif-else. Dans ce cas, vous devez supprimer les commandes GOTO pour éviter leur conversion en sections LABEL, car elles ne sont plus nécessaires.

Exemple de code

Code d’entrée :

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

Code généré

 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
Recommandations

SSC-FDM-TD0027

Note

Ce FDM n’est plus pris en charge. Pour plus d’informations, veuillez consulter SSC-EWI-TD0061.

Description

SnowConvert (SC) peut transformer la fonction TD_UNPIVOT de Teradata. Cette fonction vous permet de convertir des données de colonnes en lignes, ce qui facilite l’analyse et la manipulation de vos données.

Cette transformation a besoin d’informations sur les noms des colonnes de la ou des tables pour fonctionner correctement. Si ces informations ne sont pas disponibles, la transformation peut être incomplète, avec des colonnes manquantes dans le résultat. Dans de tels cas, un message EWI (Erreur, Avertissement, Information) est généré.

Exemple de code

Code d’entrée :
 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
Code de sortie :
 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

Recommandations

  • Vous pouvez fournir des informations sur les colonnes à l’outil de conversion en utilisant l’une des deux méthodes suivantes :

    • Incluez la spécification de la table dans le même fichier que l’appel TD_UNPIVOT

    • Listez des colonnes spécifiques dans la requête SELECT de l’expression ON au lieu d’utiliser SELECT * ou simplement le nom de la table

  • Si vous dépivotez les colonnes ALL des tables d’entrée, vous pouvez ignorer ce problème. Toutefois, si vous ne dépivotez que certaines colonnes, il en résultera des données manquantes.

  • Pour une assistance supplémentaire, veuillez nous contacter à l’adresse suivante : snowconvert-support@snowflake.com

SSC-FDM-TD0028

Note

Ce FDM n’est plus pris en charge. Pour plus d’informations, veuillez consulter SSC-EWI-TD0060.

Description

L’outil SnowConvert peut transformer la fonction JSON_TABLE, mais il doit connaître les noms des colonnes sélectionnées dans la sous-requête JSON_TABLE ON pour effectuer la transformation correctement.

Cet avertissement apparaît lorsque les noms des colonnes ne sont pas explicitement spécifiés dans une sous-requête (comme lors de l’utilisation de SELECT *) et que le système ne peut pas trouver les informations relatives à la structure de la table. Sans cette information, le système ne peut pas déterminer les noms de colonnes spécifiques auxquels il est fait référence.

Exemple de code

Code d’entrée :
 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
Code de sortie :
 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

Recommandations

  • Veillez à inclure la définition de la table lorsque vous fournissez du code à SnowConvert. Sans cela, vous devrez réexécuter le code.

  • Pour toute assistance supplémentaire, contactez-nous à l’adresse suivante : snowconvert-support@snowflake.com

SSC-FDM-TD0029

Éléments de format qui dépendent des paramètres de session

Les éléments de format Teradata suivants sont mappés à des fonctions Snowflake qui nécessitent des paramètres de session spécifiques. Pour garantir des résultats cohérents entre Teradata et Snowflake, vous devez configurer ces paramètres de session en fonction de vos paramètres Teradata :

  • D : mappé à la fonction DAYOFWEEK. Les résultats diffèrent entre Teradata et Snowflake en raison des différents paramètres par défaut. Teradata utilise le dimanche comme premier jour de la semaine, tandis que Snowflake utilise le lundi. Ceci est contrôlé par le paramètre de session WEEK_START.

  • WW : mappé à la fonction WEEK. Le comportement est contrôlé par le paramètre de session WEEK_OF_YEAR_POLICY. Le paramètre par défaut de Snowflake suit la norme ISO (la première semaine doit contenir au moins quatre jours de janvier). Teradata considère le 1er janvier comme le début de la première semaine.

Pour modifier les paramètres de session, utilisez la commande ALTER SESSION SET parameter_name = value. Pour plus de détails sur les paramètres de session disponibles, veuillez consulter cette page.

Version à paramètre unique de TO\CHAR

La fonction TO_CHAR(Datetime) avec un seul paramètre utilise les formats de date et d’heure par défaut définis dans les paramètres de votre session. Ces paramètres sont les suivants :

  • TIMESTAMP_LTZ_OUTPUT_FORMAT

  • TIMESTAMP_NTZ_OUTPUT_FORMAT

  • TIMESTAMP_TZ_OUTPUT_FORMAT

  • TIME_OUTPUT_FORMAT

Pour garantir un comportement cohérent entre Teradata et Snowflake, assurez-vous que ces paramètres correspondent à vos paramètres Teradata.

Lors de la conversion de valeurs numériques en chaînes à l’aide de TO_CHAR(numérique), Snowflake utilise automatiquement le format TM9 ou TME pour créer une représentation compacte de la chaîne. Étant donné que Teradata crée également des représentations numériques compactes par défaut, aucun formatage supplémentaire n’est nécessaire.

Exemple de code

Code d’entrée :
 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
Code de sortie :
 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

Meilleures pratiques

  • Lorsque vous travaillez avec des fonctions de format (FF), utilisez des types DateTime qui correspondent à la précision de Teradata ou spécifiez une précision dans l’élément de format pour garantir un comportement cohérent.

  • Pour le formatage des fuseaux horaires, assurez-vous que le premier paramètre est de type TIMESTAMP_TZ pour obtenir des résultats cohérents. Notez que le type de données TIME de Snowflake ne prend pas en charge les informations relatives au fuseau horaire.

  • Configurez les paramètres de session pour qu’ils correspondent aux valeurs par défaut de Teradata afin de maintenir un comportement cohérent.

  • Pour toute assistance supplémentaire, contactez-nous à l’adresse suivante : snowconvert-support@snowflake.com

SSC-FDM-TD0030

Description

Lorsque SC remplace une instruction Goto par une section Label, il ajoute automatiquement une instruction de retour à la fin de la section s’il n’y en a pas. Cela permet de s’assurer que le flux d’exécution du programme reste le même que dans le code d’origine.

Lorsqu’une commande Goto BTEQ est exécutée, toutes les instructions situées entre la commande Goto et l’étiquette correspondante sont ignorées. Pour éviter toute exécution involontaire après avoir atteint l’étiquette, vous devez inclure une instruction de retour dans la section de l’étiquette.

Il est important de noter que la commande Goto saute toutes les instructions jusqu’à ce qu’elle trouve une étiquette correspondante. L’exécution du programme se poursuit ensuite à partir de cette étiquette. Le programme n’exécutera jamais les sections de l’étiquette qui apparaissent avant la commande Goto.

Exemple de code

Code d’entrée :
 -- Additional Params: --scriptsTargetLanguage SnowScript
.LOGON dbc,dbc;
select 'STATEMENTS';
.GOTO LABEL_B
select 'IGNORED STATEMENTS';
.label LABEL_B
select 'LABEL_B STATEMENTS';
Copy
Code de sortie
 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

Recommandations

SSC-FDM-TD0031

Description

La fonction Teradata ST_SPHERICALDISTANCE utilise la formule de Haversine pour calculer la distance entre deux points sur Terre en utilisant des coordonnées sphériques. En revanche, la fonction ST_DISTANCE de Snowflake utilise une méthode différente pour mesurer la distance entre deux points géographiques.

Exemple de code

Code d’entrée :
 --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
Résultats de Teradata

location1

location2

Distance_In_Km

POINT (-73.989308 40.741895)

POINT (40.741895 34.053691)

9351139,978062356

Code de sortie
 --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
Résultats de Snowflake

LOCATION1

LOCATION2

DISTANCE_IN_KM

{ « coordinates »: [ -73.989308, 40.741895 ], « type »: « Point » }

{ « coordinates »: [ 40.741895, 34.053691 ], « type »: « Point » }

9351154,65572674

Recommandations

SSC-FDM-TD0032

Note

Par souci de clarté, nous avons simplifié certaines sections du code de sortie.

Description

Cette erreur se produit lorsqu’une expression LIKE inclut la clause [NOT] CASESPECIFIC.

Exemple de code

Code d’entrée :
 SELECT * FROM MY_TABLE
WHERE Name Like 'Marco%' (NOT CASESPECIFIC);
Copy
Code de sortie
 SELECT
* FROM
MY_TABLE
WHERE Name LIKE 'Marco%' /*** SSC-FDM-TD0032 - NOT CASESPECIFIC CLAUSE WAS REMOVED ***/;
Copy

Recommandations

  • Le comportement de la sensibilité à la casse de TERADATA est déterminé par le paramètre de configuration du système TMODE.

  • Pour toute assistance supplémentaire, veuillez nous contacter à l’adresse suivante : snowconvert-support@snowflake.com

SSC-FDM-TD0033

Description

La variable de statut ACTIVITY_COUNT indique le nombre de lignes modifiées par une instruction DML (telle que INSERT, UPDATE ou DELETE) lorsqu’elle est utilisée dans une procédure intégrée SQL ou une procédure stockée. Pour plus de détails, visitez ici.

Pour répliquer le comportement de ACTIVITY_COUNT, vous pouvez utiliser la solution de contournement décrite dans la spécification de traduction.

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

Cependant, il y a plusieurs limites à prendre en compte :

Limitations

Premier cas

Si vous appelez ACTIVITY_COUNT plusieurs fois avant d’exécuter une autre instruction DML, vous risquez d’obtenir des résultats incorrects. Veillez à exécuter une instruction DML entre chaque appel à ACTIVITY_COUNT pour obtenir des valeurs précises.

 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

Lorsque vous utilisez ACTIVITY_COUNT dans Teradata, vous pouvez l’appeler plusieurs fois après une instruction DML (comme INSERT) et il renverra systématiquement le nombre de lignes affectées de cette instruction. Cependant, dans Snowflake, le code transformé utilise LAST_QUERY_ID(), qui se comporte différemment. Le résultat de LAST_QUERY_ID() dépend de la requête la plus récente exécutée, de sorte que plusieurs requêtes peuvent ne pas renvoyer la même valeur si d’autres requêtes sont exécutées entre-temps.

La procédure stockée InsertEmployeeSalaryAndLog_1() fonctionne sans nécessiter de modifications. Vous pouvez la vérifier en examinant l’historique des requêtes dans l’ordre chronologique, de bas en haut.

Historique de la requête montrant l’exécution de InsertEmployeeSalaryAndLog_1()

  1. L’instruction INSERT est exécutée en premier et LAST_QUERY_ID() fait référence à cette opération.

  2. La première instruction SELECT avec ACTIVITY_COUNT s’exécute et paramétrant $1 sur 1. LAST_QUERY_ID() pointe maintenant vers cette instruction SELECT.

  3. La deuxième instruction SELECT avec ACTIVITY_COUNT s’exécute. Puisque l’instruction précédente a retourné 1, $1 reste 1 pour cette SELECT.

  4. La valeur 1 est stockée dans row_count1 et est ensuite insérée dans la table activity_log.

En examinant la procédure InsertEmployeeSalaryAndLog_2(), des modifications manuelles sont nécessaires. Examinons l’historique des requêtes par ordre chronologique, en commençant par les entrées les plus anciennes.

Historique des requêtes montrant les résultats de l’exécution de la procédure InsertEmployeeSalaryAndLog_2()

  1. Lorsque l’instruction INSERT est exécutée, LAST_QUERY_ID() fait référence à cette instruction spécifique.

  2. Lors de la première instruction SELECT avec ACTIVITY_COUNT, $1 équivaut à 1. Cependant, QUERY_TEXT contient + 10, ce qui modifiera le résultat final. À ce stade, LAST_QUERY_ID() pointe vers cette instruction SELECT.

  3. Lorsque la seconde instruction SELECT avec ACTIVITY_COUNT s’exécute, elle renvoie 11 (au lieu de 1) en raison de la requête précédente. Cette valeur est stockée dans $1.

  4. La variable row_count1 reçoit la valeur 11, qui est ensuite stockée dans la table activity_log.

Les valeurs suivantes sont stockées dans la table activity_log :

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

Ajustements pour le premier cas

Selon la documentation de Snowflake pour LAST_QUERY_ID, vous pouvez récupérer des requêtes spécifiques en utilisant un numéro de position. Par exemple :

  • LAST_QUERY_ID(-1) récupère la requête la plus récente

  • LAST_QUERY_ID(-2) récupère la deuxième requête la plus récente. Et ainsi de suite pour les requêtes plus anciennes.

La solution pour corriger le problème dans InsertEmployeeSalaryAndLog_2() est d’utiliser LAST_QUERY_ID(-2) dans la deuxième instruction SELECT lorsque vous récupérez ACTIVITY_COUNT. Cela permet de s’assurer que nous obtenons le nombre de lignes de l’instruction INSERT précédente.

 ...
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

Deuxième cas

Si ACTIVITY_COUNT est utilisé après l’exécution d’une instruction autre queDML (telle que SELECT), il ne renverra pas le nombre correct de lignes affectées.

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

La fonction LAST_QUERY_ID renvoie une valeur incorrecte pour row_count1 car elle fait référence à la mauvaise requête. Vous pouvez le vérifier en consultant l’historique des requêtes dans l’ordre chronologique inverse.

Historique de la requête montrant les résultats de l’exécution de InsertEmployeeSalaryAndLog_3()

  1. Tout d’abord, une instruction INSERT est exécutée. La fonction LAST_QUERY_ID() fait référence à cette opération INSERT.

  2. Ensuite, l’instruction SELECT INTO s’exécute et paramètre $1 à 101. La fonction LAST_QUERY_ID() pointe désormais vers cette opération SELECT INTO.

  3. Ensuite, une instruction SELECT est exécutée pour obtenir ACTIVITY_COUNT. Puisque la dernière requête a donné 101, $1 contient 101 au lieu de la valeur attendue de 1.

  4. Par conséquent, row_count1 enregistre 101, qui est ensuite enregistré dans la table activity_log.

Les valeurs suivantes sont enregistrées dans l’activity_log :

LOG_ID

OPERATION

ROW_COUNT

LOG_TIMESTAMP

1

EMPLOYEE INSERTED - ID: 101

101

2024-07-15 11:00:38.000

Ajustements pour le second cas

  1. Pour résoudre ce problème, utilisez LAST_QUERY_ID en indiquant le numéro de référence de la requête. Par exemple, LAST_QUERY_ID(-2) récupérera la requête spécifique dont vous avez besoin.

 ...
row_count1 := (
            SELECT
                $1
            FROM
                TABLE(RESULT_SCAN(LAST_QUERY_ID(-2)))
               ) /*** SSC-FDM-TD0033 - 'ACTIVITY_COUNT' TRANSFORMATION MIGHT REQUIRE MANUAL ADJUSTMENTS ***/;
               ...
Copy
  1. Vous pouvez également vérifier le succès de l’instruction INSERT en vérifiant l’instruction ACTIVITY_COUNT à l’aide d’une instruction SELECT juste après l’insertion.

...
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

Recommandations

  • Lorsque vous utilisez LAST_QUERY_ID, vérifiez que vous faites référence à la requête voulue.

  • Exécutez ACTIVITY_COUNT immédiatement après votre instruction DML pour garantir une évaluation précise.

  • Pour toute assistance supplémentaire, contactez-nous à l’adresse suivante : snowconvert-support@snowflake.com