SnowConvert AI – Diferenças funcionais do Teradata

SSC-FDM-TD0001

Coluna convertida do tipo de dados Blob.

Descrição

Esta mensagem é exibida quando o SnowConvert AI encontra um tipo de dados BLOB. Como BLOB não é compatível com o Snowflake, o tipo é alterado para Binary.

Exemplo de código

Código de entrada:
 CREATE TABLE TableExample
(
ColumnExample BLOB
);
Copy
Código gerado:
 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

Práticas recomendadas

SSC-FDM-TD0002

Coluna convertida do tipo de dados Clob.

Descrição

Esta mensagem é exibida quando o SnowConvert AI encontra um tipo de dados CLOB. Como CLOB não é compatível com o SnowConvert AI, o tipo é alterado para VARCHAR.

Exemplo de código

Código de entrada:
 CREATE TABLE TableExample
(
ColumnExample CLOB
)
Copy
Código gerado:
 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

Práticas recomendadas

SSC-FDM-TD0003

Variáveis Bash encontradas; o uso do SnowSQL com a substituição de variáveis ativada é necessário para executar este script.

Descrição

Quando o código-fonte de um arquivo de script migrado para o Snowflake Scripting contém espaços reservados para variáveis Bash ($variable ou ${variable}), o SnowConvert AI os transforma em variáveis SnowSQL (&variable ou &{variable}).

Este aviso é gerado para indicar que a execução do script migrado agora depende do SnowSQL para funcionar. Considere o seguinte ao executar o script no SnowSQL:

Exemplo de código

Código de entrada:
 .LOGON dbc, dbc;

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

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

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

.LOGOFF;
Copy
Código gerado:
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

Práticas recomendadas

SSC-FDM-TD0004

Os tipos de período são tratados como dois campos de dados.

Descrição

O Teradata tem um tipo de dados de período utilizado para representar um intervalo de tempo, com instâncias desse tipo tendo um limite inicial e final do mesmo tipo (hora, data ou carimbo de data/hora), juntamente com um conjunto de funções que permitem inicializar e manipular dados de período como PERIOD, BEGIN, END, OVERLAPS, etc.

Como o tipo de período não é compatível com o Snowflake, o SnowConvert AI transforma esse tipo e as funções relacionadas usando as seguintes regras:

  • Qualquer declaração de tipo de período em tabelas de colunas é migrada como duas colunas do mesmo tipo.

  • A função do construtor de valor de período é migrada para dois construtores diferentes do subtipo de período, um com o valor inicial e o outro com o final.

  • As funções compatíveis que esperam parâmetros de tipo de período também foram migradas para UDFs. Estas UDFs esperam quase dois parâmetros para o valor inicial e o final.

Exemplo de código

Código de entrada:
 -- Additional Params: --SplitPeriodDatatype
CREATE TABLE DateTable
(
	COL1 PERIOD(DATE) DEFAULT PERIOD (DATE '2005-02-03', UNTIL_CHANGED)
);
Copy
Código gerado:
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

Práticas recomendadas

SSC-FDM-TD0005

Deslocamentos de fuso horário não padrão não são compatíveis com o Snowflake; arredondados para o fuso horário válido mais próximo.

Descrição

Embora o Teradata ofereça a flexibilidade de definir qualquer deslocamento de fuso horário entre -12:59 e +14:00 usando a consulta SET TIME ZONE, o Snowflake é compatível exclusivamente com os fusos horários listados no Banco de dados de fusos horários IANA.

Se o deslocamento especificado na consulta SET TIME ZONE não estiver alinhado com um fuso horário padrão IANA, o Snowflake o arredondará automaticamente para o fuso horário padrão mais perto com o deslocamento mais próximo. Nesse caso, uma mensagem de aviso será gerada.

Exemplo de código

Código de entrada:
-- Will be rounded to Asia/Colombo (+05:30)
SET TIME ZONE '05:26';
Copy
Código gerado:
 -- 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

Práticas recomendadas

SSC-FDM-TD0006

Exibição With Check Option não é compatível.

Descrição

Esta mensagem é exibida quando o SnowConvert AI encontra uma exibição com a cláusula WITH CHECK OPTION. Essa cláusula não é compatível com o Snowflake; portanto, foi transformada em comentário no código.

Essa cláusula funciona com exibições atualizáveis que podem ser utilizadas para executar comandos INSERT e UPDATE sobre a exibição e atualizar internamente a tabela associada à exibição.

A cláusula é utilizada para restringir as linhas que serão afetadas pelo comando usando a cláusula WHERE na exibição.

Para mais detalhes, consulte a documentação sobre a funcionalidade da cláusula.

Exemplo de código

Código de entrada:
REPLACE VIEW VIEWWITHOPTIONTEST AS
LOCKING ROW FOR ACCESS
SELECT 
    *        
FROM SOMETABLE
WHERE app_id = 'SUPPLIER'
WITH CHECK OPTION;
Copy
Código gerado:
 CREATE OR REPLACE VIEW VIEWWITHOPTIONTEST
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "teradata",  "convertedOn": "07/02/2025",  "domain": "no-domain-provided" }}'
AS
SELECT
    *
FROM
    SOMETABLE
WHERE
    UPPER(RTRIM( app_id)) = UPPER(RTRIM('SUPPLIER'))
--    --** SSC-FDM-TD0006 - VIEW WITH OPTION NOT SUPPORTED IN SNOWFLAKE **
--    WITH CHECK OPTION
                     ;
Copy

Práticas recomendadas

SSC-FDM-TD0007

A coluna Variant não é compatível com agrupamento.

Descrição

Esta mensagem é exibida quando o SnowConvert AI utiliza um tipo de dados Variant na transformação de um código que tem uma cláusula COLLATE. Como COLLATE não é compatível com o tipo de dados VARIANT, ele será removido e uma mensagem será adicionada.

Exemplo de código

Código de entrada:
-- Additional Params: --useCollateForCaseSpecification
CREATE TABLE TableExample
(
ColumnExample JSON(2500) NOT CASESPECIFIC
)
Copy
Código gerado:
 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

O tipo de dados JSON é convertido para VARIANT, enquanto NOT CASESPECIFIC é convertido para uma cláusula COLLATE.

Práticas recomendadas

SSC-FDM-TD0008

Quando o quarto parâmetro NVP_UDF não é literal e contém uma barra invertida, essa barra precisa ter um caractere de escape.

Descrição

Delimitadores não literais com espaços precisam que as barras invertidas tenham um caractere de escape no Snowflake.

Exemplo de código

Código de entrada
SELECT NVP('store = whole foods&&store: ?Bristol farms','store', '&&', valueDelimiter, 2);
Copy
Código gerado
 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

Práticas recomendadas

SSC-FDM-TD0009

Convertido de inteiro para varchar para o padrão da sessão atual.

Descrição

Esta mensagem é exibida quando o SnowConvert AI encontra um DEFAULT SESSION e o tipo de dados é NOT ou VARCHAR. Nesse caso, o tipo de dados é alterado para VARCHAR e uma mensagem é adicionada.

Exemplo de código

Código de entrada:
 CREATE TABLE TableExample
(
ColumnExample INTEGER DEFAULT SESSION,
ColumnExample2 VARCHAR DEFAULT SESSION
)
Copy
Código gerado:
 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

Vejamos o exemplo. Observe que ColumnExample tem um tipo de dados INTEGER com DEFAULT SESSION. Como o tipo de dados não é VARCHAR, na saída ele é transformado em VARCHAR.

O tipo de dados de ColumnExample2 não foi alterado, pois já é VARCHAR.

Práticas recomendadas

SSC-FDM-TD0010

Colunas da tabela entre as tabelas (Teradata) DBC.COLUMNSV e INFORMATION_SCHEMA.COLUMNS (SnowFlake). Mas algumas colunas podem não ter uma correspondência exata no Snowflake.

Descrição

Os usos da tabela DBC.COLUMNSV no Teradata são convertidos para INFORMATION_SCHEMA.COLUMNS, mas algumas colunas podem não ter uma correspondência exata no SnowFlake. Isso significa que existem algumas colunas no Teradata para as quais não há equivalente no SnowFlake, e existem outras que têm uma coluna correspondente, mas o conteúdo não é exatamente o mesmo.

An example of the contents of DBC.COLUMNSV table in Teradata

An example of the contents of INFORMATION_SCHEMA.COLUMNS table in SnowFlake

Observe, por exemplo, que não há coluna equivalente para «ColumnFormat» no SnowFlake e observe também que «DATA_TYPE» parece ser a correspondência para a coluna «ColumnType» no Teradata, mas os conteúdos são muito diferentes.

Exemplo de código

Código de entrada:
 SELECT columnname FROM dbc.columnsV WHERE tablename = 'TableN';
Copy
Código gerado:
 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
UPPER(RTRIM(TABLE_NAME)) = UPPER(RTRIM('TableN'));
Copy

Práticas recomendadas

  • Revise quais colunas foram utilizadas no Teradata e verifique se o conteúdo disponível no SnowFlake atende às suas necessidades.

  • Se precisar de mais suporte, envie um e-mail para snowconvert-support@snowflake.com

SSC-FDM-TD0011

O escape Unicode BMP não é compatível.

Descrição

O Snowflake não é compatível com Unicode BMP; portanto, esta mensagem é exibida quando o SnowConvert AI transforma um literal de caractere delimitado Unicode do Teradata com escape Unicode BMP no Snowflake.

Exemplo de código

Código de entrada:
 SELECT U&'hola #+005132 mundo' UESCAPE '#';
Copy
Código gerado:
 SELECT
--** SSC-FDM-TD0011 - UNICODE BMP IS NOT SUPPORTED IN SNOWFLAKE **
'hola \u+005132 mundo';
Copy

Práticas recomendadas

SSC-FDM-TD0012

Valor padrão inválido.

Nota

Esta FDM está obsoleta. Consulte a documentação SSC-EWI-TD0006.

Descrição

As especificações de coluna DEFAULT TIME / DEFAULT DATE / DEFAULT CURREN_DATE / DEFAULT DEFAULT CURRENT_TIME / DEFAULT CURRENT_TIMESTAMP não são compatíveis com o tipo de dados FLOAT.

Exemplo de código

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

Práticas recomendadas

SSC-FDM-TD0013

O código de erro do Snowflake não corresponde ao código de erro original do Teradata.

Descrição

Esta mensagem é exibida porque o código de erro salvo na variável interna BTEQ ERRORCODE não pode ser o mesmo no Snowflake Scripting.

Exemplo de código

Código de entrada:
SELECT * FROM table1;
 
.IF ERRORCODE<>0 THEN .EXIT 1

.QUIT 0
Copy
Código gerado:
 -- 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

Práticas recomendadas

SSC-FDM-TD0014

Inconsistência na execução de arquivos

Descrição

Este EWI aparece quando o código migrado é uma sentença BTEQ que executa um arquivo de ambiente com instruções SQL. Por exemplo, $(<$INPUT_SQL_FILE). A diferença entre a execução BTEQ e o código gerado pelo Python é que BTEQ continua com as outras instruções no arquivo quando uma delas falha, mas a execução do Python é interrompida sempre que ocorre um erro.

Exemplo de código

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

Práticas recomendadas

SSC-FDM-TD0015

A função Regexp_Substr só é compatível com expressões regulares POSIX.

Nota

Esta FDM está obsoleta. Consulte a documentação SSC-EWI-0009.

Descrição

Atualmente, o Snowflake não é compatível com expressões regulares estendidas além da sintaxe básica de expressões regulares POSIX.

Este EWI é adicionado toda vez que uma chamada de função para REGEX_SUBSTR, REGEX_REPLACE ou REGEX_INSTR é transformada no SnowFlake para alertar o usuário sobre possíveis expressões regulares incompatíveis. Alguns dos recursos incompatíveis são lookahead, lookbehind e grupos sem captura.

Exemplo de código

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

Práticas recomendadas

  • Verifique a expressão regular utilizada em cada caso para determinar se ela precisa de intervenção manual. Mais informações sobre o suporte expandido a expressões regulares e alternativas no SnowFlake podem ser encontradas aqui.

  • Se precisar de mais suporte, envie um e-mail para snowconvert-support@snowflake.com

SSC-FDM-TD0016

O valor «l» para o parâmetro «match_arg» não é compatível com o Snowflake.

Descrição

Em funções Teradata como REGEX_SUBSTR, REGEX_REPLACE ou REGEX_INSTR, existe um parâmetro chamado «match_arg», um argumento de caractere com os seguintes valores válidos:

  • 'i': correspondência sem distinção entre maiúsculas e minúsculas.

  • 'c': correspondência com distinção entre maiúsculas e minúsculas.

  • 'n': o caractere de ponto (corresponde a qualquer caractere) pode corresponder ao caractere de nova linha.

  • 'm': a cadeia de caracteres de origem é tratada como várias linhas em vez de uma única linha.

  • 'l': se source_string exceder o tamanho máximo permitido atual (atualmente 16 MB), NULL será retornado em vez de um erro.

  • 'x': ignora espaços em branco (afeta apenas a cadeia de caracteres do padrão).

O argumento pode conter mais de um caractere.

No Snowflake, o argumento equivalente para essas funções é _regexp_parameters._Uma cadeia de um ou mais caracteres que especifica os parâmetros da expressão regular utilizados para buscar correspondências. Os valores aceitos são:

  • c: diferencia maiúsculas de minúsculas.

  • i: não diferencia maiúsculas de minúsculas.

  • m: modo multilinhas.

  • e: extrair subcorrespondências.

  • s: o caractere curinga “.” também corresponde ao caractere de nova linha.

Conforme mostrado, os valores 'i', 'c', 'm' são os mesmos em ambos os idiomas, e o valor 'n' no Teradata é mapeado para 's'. No entanto, os valores 'l', 'x' não têm contraparte equivalente.

Para o valor 'x', a funcionalidade é replicada com a geração de uma chamada para a função REGEXP_REPLACE. No entanto, o parâmetro 'l' não pode ser replicado; portanto, este aviso é gerado para esses casos.

Código de entrada:

 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
Código gerado:
 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

Práticas recomendadas

SSC-FDM-TD0017

O uso de tabelas estrangeiras não é compatível com o Snowflake.

Nota

Esta FDM está obsoleta. Consulte a documentação SSC-EWI-TD0076.

Descrição

Tabelas estrangeiras permitem o acesso a dados em armazenamento de objetos externo, como dados semiestruturados e não estruturados no Amazon S3, Azure Blob Storage e Google Cloud Storage. Essa sintaxe não é compatível com o Snowflake. No entanto, existem outras alternativas no Snowflake que podem ser utilizadas, como tabelas externas, tabelas Iceberg e tabelas padrão.

Exemplo de código

Código de entrada:
 SELECT cust_id, income, age FROM 
FOREIGN TABLE (SELECT cust_id, income, age FROM twm_customer)@hadoop1 T1;
Copy
Código gerado:
 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

Práticas recomendadas

  • Em vez das tabelas estrangeiras no Teradata, você pode usar tabelas externas do Snowflake. Tabelas externas fazem referência a arquivos de dados localizados em um data lake de armazenamento em nuvem (Amazon S3, Google Cloud Storage ou Microsoft Azure). Isso permite consultar dados armazenados em arquivos em um data lake como se estivessem dentro de um banco de dados. Tabelas externas podem acessar dados armazenados em qualquer formato compatível com instruções COPY INTO <table>.

  • Outra alternativa são as tabelas Iceberg do Snowflake. Portanto, você pode pensar nas tabelas Iceberg como tabelas que usam formatos abertos e armazenamento em nuvem fornecido pelo cliente. Esses dados são armazenados em arquivos Parquet.

  • Por fim, existem as tabelas padrão do Snowflake, que podem ser uma opção para cobrir a funcionalidade de tabelas estrangeiras no Teradata.

  • Se precisar de mais suporte, envie um e-mail para snowconvert-support@snowflake.com

SSC-FDM-TD0018

O caminho JSON não foi reconhecido.

Nota

Esta FDM está obsoleta. Consulte a documentação SSC-EWI-TD0063.

Descrição

Esta mensagem é exibida quando o SnowConvert AI não consegue desserializar um caminho JSON, porque a cadeia de caracteres não tem o formato esperado ou não é compatível com o Snowflake.

Exemplo de código

Código de entrada:
 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
Código gerado:
 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

Práticas recomendadas

  • Verifique se o caminho JSON contém um caractere inesperado ou não tem o formato correto.

  • Se precisar de mais suporte, envie um e-mail para snowconvert-support@snowflake.com

SSC-FDM-TD0019

Tags de consulta de nível de transação e perfil não são compatíveis com o Snowflake. Em vez disso, é feita referência à tag de consulta de sessão.

Descrição

O Teradata permite que os usuários definam bandas de consulta em níveis de transação, sessão e perfil, além de consultá-las com funções como GetQueryBandValue.

O equivalente no Snowflake para bandas de consulta é o parâmetro query_tag, que pode ser definido para sessão, usuário ou conta. Além disso, o Snowflake não tem perfis.

Devido a essas diferenças, este FMD é adicionado para alertar o usuário de que as tags de consulta em nível de transação ou perfil não podem ser definidas nem consultadas no Snowflake e que as tags de consulta em nível de sessão serão utilizadas como substitutas, o que pode causar diferenças funcionais em alguns casos.

Exemplo de código

Código de entrada:
 SELECT GETQUERYBANDVALUE(3, 'account');
Copy
Código gerado
 SELECT
--** SSC-FDM-TD0019 - TRANSACTION AND PROFILE LEVEL QUERY TAGS NOT SUPPORTED IN SNOWFLAKE, REFERENCING SESSION QUERY TAG INSTEAD **
GETQUERYBANDVALUE_UDF('account');
Copy

Práticas recomendadas

  • Modifique a lógica do seu código para usar bandas de consulta no nível da sessão.

  • Se precisar de mais suporte, envie um e-mail para snowconvert-support@snowflake.com

SSC-FDM-TD0020

O valor JSON não foi reconhecido devido a um formato inválido.

Nota

Algumas partes do código de saída foram omitidas por motivos de clareza.

Descrição

Esta mensagem é exibida quando o SnowConvert AI precisa desserializar dados JSON para um contexto de transformação, mas o valor JSON não tem o formato esperado ou não é um JSON válido.

Exemplo de código

Código de entrada:
 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
Código gerado:
 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

Práticas recomendadas

  • Certifique-se de que o JSON tenha o formato esperado de acordo com a gramática do Teradata.

  • Se precisar de mais suporte, envie um e-mail para snowconvert-support@snowflake.com

SSC-FDM-TD0021

A referência integrada a {0} não é compatível com o Snowflake.

Nota

Este EWI está obsoleto. Consulte a documentação SSC-EWI-TD0046.

Descrição

Este erro ocorre quando uma consulta que referencia a tabela DBC.DATABASES é executada e a coluna selecionada não tem equivalente no Snowflake.

Exemplo de código

Entrada:
 CREATE VIEW SAMPLE_VIEW
AS
SELECT PROTECTIONTYPE FROM DBC.DATABASES;
Copy
Saída:
 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

Práticas recomendadas

SSC-FDM-TD0022

Variáveis de shell encontradas, é necessário executar este código em um script do shell.

Descrição

Em scripts do Teradata, as variáveis de shell são utilizadas para armazenar valores temporários que podem ser acessados e manipulados em todo o script. As variáveis de shell são definidas com o cifrão ($) seguido por um nome (que pode ser delimitado por chaves), e os valores podem ser definidos com o uso do operador de atribuição (=).

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

Você pode pensar nas variáveis de shell como tendo a mesma função ou uma função semelhante à interpolação de cadeias de caracteres. Portanto, é importante manter essa funcionalidade após a transformação.\ \ Ao converter scripts para Python, as variáveis de shell mantêm a funcionalidade executando o código convertido em um script de shell (arquivo .sh). Por esse motivo, essas variáveis de shell devem manter o mesmo formato do código de entrada.

Exemplo de código

Código de entrada:

 SELECT $column FROM ${tablename}
Copy
Código gerado
 #*** Generated code is based on the SnowConvert AI 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

Práticas recomendadas

SSC-FDM-TD0023

A similaridade de cadeias de caracteres pode ter um comportamento diferente.

Descrição

Esta FDM é mostrada quando o SnowConvert AI transforma a função de similaridade do Teradata para o Snowflake. Isso indica que os resultados podem ter um comportamento diferente.

Exemplo de código

Considere os seguintes dados como exemplo:

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

Código de entrada:
Consulta
-- 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
Resultado
Idsim_fn
10
20.565079365
31
40.959047619
50
60.611111111
70.7777777777777777
80
90
Código gerado
Consulta
 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
Resultado

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

Práticas recomendadas

SSC-FDM-TD0024

A funcionalidade de tabela definida não é compatível.

Descrição

Este EWI é mostrado quando o SnowConvert AI encontra uma criação de tabela com a opção SET. Como SET TABLE não é compatível com o Snowflake, isso foi removido.

Exemplo de código

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

Práticas recomendadas

SSC-FDM-TD0025

A tabela temporal do banco de dados do Teradata não é compatível com o Snowflake.

Descrição

O Suporte temporal do banco de dados do Teradata envolve a criação de tabelas temporais e objetos DDL e DML temporais. O suporte para tabelas e dados temporais (com reconhecimento de tempo) não é compatível com o Snowflake, pois não existe um equivalente absoluto.

Todas essas instruções são reconhecidas (analisadas) pelo SnowConvert AI, mas, para executar as consultas no Snowflake, esses elementos são removidos no processo de tradução.

Vale ressaltar que, nos casos em que uma instrução abort é encontrada, ela é transformada em um comando Delete para manter a funcionalidade de equivalência. Isso permite desfazer operações realizadas durante uma transação e restaurar o banco de dados ao estado em que se encontrava no início.

Exemplo de código

O exemplo a seguir mostra uma Select em formato temporal sendo traduzida para uma Select comum.

Código de entrada:
 SEQUENCED VALIDTIME  
   SELECT
   Policy_ID,
   Customer_ID
   FROM Policy
      WHERE Policy_Type = 'AU';
Copy
Código gerado:
 ----** SSC-FDM-TD0025 - TEMPORAL FORMS ARE NOT SUPPORTED IN SNOWFLAKE **
--SEQUENCED VALIDTIME
SELECT
   Policy_ID,
   Customer_ID
   FROM
   Policy
      WHERE
   UPPER(RTRIM( Policy_Type)) = UPPER(RTRIM('AU'));
Copy

Caso em que o comando Abort é utilizado no contexto de uma transação.

Código de entrada:
 CREATE OR REPLACE PROCEDURE TEST.ABORT_STATS()
BEGIN
    CURRENT VALIDTIME AND NONSEQUENCED TRANSACTIONTIME ABORT 
     FROM table_1 
     WHERE table_1.x1 = 1;
END;
Copy
Código gerado:
 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

Práticas recomendadas

SSC-FDM-TD0026

A instrução GOTO foi removida devido à inversão da instrução if.

Nota

Algumas partes do código de saída foram omitidas por motivos de clareza.

Descrição

É comum usar o comando GOTO com os comandos IF e LABEL para replicar a funcionalidade de uma instrução SQL if. Quando utilizados dessa forma, é possível transformá-los diretamente em uma instrução if, if-else ou até mesmo if-elseif-else. No entanto, nesses casos, os comandos GOTO tornam-se desnecessários e devem ser removidos para evitar que sejam substituídos por uma seção LABEL.

Código de exemplo

Código de entrada:

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

Código de saída

 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
Práticas recomendadas

SSC-FDM-TD0027

A transformação TD_UNPIVOT requer informações de coluna que não puderam ser encontradas, resultando em colunas ausentes no resultado.

Nota

Esta FDM está obsoleta. Consulte a documentação SSC-EWI-TD0061.

Descrição

O SnowConvert AI suporta e transforma a função TD_UNPIVOT, que pode ser utilizada para representar colunas de uma tabela como linhas.

Entretanto, essa transformação requer informações sobre as colunas da tabela/tabelas para funcionar, mais especificamente os nomes das colunas. Quando essas informações não estão presentes, a transformação pode ficar incompleta, com colunas ausentes no resultado. Este EWI é gerado nesses casos.

Exemplo de código

Código de entrada:
 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
Código gerado:
 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

Práticas recomendadas

  • Existem duas maneiras de fornecer informações sobre as colunas para a ferramenta de conversão: colocar a especificação da tabela no mesmo arquivo que a chamada TD_UNPIVOT ou especificar uma lista de colunas na consulta SELECT da expressão ON em vez de SELECT * ou o nome da tabela.

  • Esse problema poderá ser ignorado com segurança se ALL as colunas da tabela/tabelas de entrada forem desempilhadas; caso contrário, o resultado terá colunas ausentes.

  • Se precisar de mais suporte, envie um e-mail para snowconvert-support@snowflake.com

SSC-FDM-TD0028

JSON_TABLE não transformado, os nomes das colunas não puderam ser recuperados das informações semânticas.

Nota

Esta FDM está obsoleta; consulte a documentação SSC-EWI-TD0060.

Descrição

A função JSON_TABLE pode ser transformada pelo SnowConvert AI; no entanto, essa transformação requer o conhecimento do nome das colunas que estão sendo selecionadas na subconsulta JSON_TABLE ON.

Esta mensagem é gerada para alertar o usuário de que os nomes das colunas não foram explicitamente inseridos na subconsulta (por exemplo, foi utilizado SELECT *) e as informações semânticas das tabelas referenciadas não foram encontradas, o que significa que os nomes das colunas não puderam ser extraídos.

Exemplo de código

Código de entrada:
 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
Código gerado:
 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

Práticas recomendadas

  • Verifique se o código fornecido para o SnowConvert AI está completo. Se você não forneceu a definição da tabela, execute o código novamente com a definição da tabela presente.

  • Se precisar de mais suporte, envie um e-mail para snowconvert-support@snowflake.com

SSC-FDM-TD0029

Os formatos compatíveis com o Snowflake para TO_CHAR diferem do Teradata e podem falhar ou apresentar comportamento diferente.

Elementos de formato que dependem dos parâmetros da sessão

Alguns elementos de formato do Teradata são mapeados para funções do Snowflake que dependem do valor dos parâmetros de sessão. Para evitar diferenças funcionais nos resultados, você deve definir esses parâmetros de sessão com os mesmos valores que eles têm no Teradata. Os elementos de formato identificados que são mapeados para esse tipo de função são:

  • D: mapeado para a função DAYOFWEEK, os resultados dessa função dependem do parâmetro de sessão WEEK_START. Por padrão, o Teradata considera o domingo como o primeiro dia da semana, enquanto no Snowflake o primeiro dia é a segunda-feira.

  • WW: mapeado para a função WEEK, essa função depende do parâmetro de sessão WEEK_OF_YEAR_POLICY, que por padrão está configurado para usar o padrão ISO (a primeira semana do ano é a primeira a conter pelo menos quatro dias de janeiro), mas, no Teradata, isso está configurado para considerar o primeiro dia de janeiro como o início da primeira semana.

Para modificar os parâmetros de sessão, use ALTER SESSION SET parameter_name = value. Para obter mais informações sobre parâmetros de sessão, visite esta página.

Versão de parâmetro único de TO_CHAR

A versão com um único parâmetro de TO_CHAR(Datetime) utiliza os formatos padrão especificados nos parâmetros de sessão TIMESTAMP_LTZ_OUTPUT_FORMAT, TIMESTAMP_NTZ_OUTPUT_FORMAT, TIMESTAMP_TZ_OUTPUT_FORMAT e TIME_OUTPUT_FORMAT. Para evitar diferenças de comportamento, defina-os com os mesmos valores utilizados no Teradata.

Para TO_CHAR(Numeric), o Snowflake gera a representação varchar usando os formatos TM9 ou TME para obter uma representação compacta do número. O Teradata também gera representações compactas dos números; portanto, nenhuma ação é necessária.

Exemplo de código

Código de entrada:
 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
Código gerado:
 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

Práticas recomendadas

  • Ao usar FF, tente usar tipos DateTime com a mesma precisão que você usa no Teradata ou adicione uma precisão ao elemento de formato para evitar comportamentos diferentes.

  • Ao usar elementos de formato relacionados a fusos horários, use o primeiro parâmetro do tipo TIMESTAMP_TZ para evitar comportamentos diferentes. Lembre-se também de que o tipo TIME não pode conter informações de fuso horário no Snowflake.

  • Defina os parâmetros de sessão necessários com os valores padrão do Teradata para evitar comportamentos diferentes.

  • Se precisar de mais suporte, envie um e-mail para snowconvert-support@snowflake.com

SSC-FDM-TD0030

Uma instrução de retorno foi adicionada no fim da seção do rótulo para garantir o mesmo fluxo de execução

Descrição

Quando uma instrução Goto é substituída por uma seção de rótulo e não contém uma instrução de retorno, uma é adicionada no fim da seção para garantir o mesmo fluxo de execução.

BTEQ após a execução de um comando Goto, as instruções entre o comando goto e o comando de rótulo com o mesmo nome são ignoradas. Portanto, para evitar que essas instruções sejam executadas, a seção de rótulo deve conter uma instrução de retorno.

Além disso, vale a pena mencionar que o comando Goto ignora todas as outras instruções, exceto o rótulo com o mesmo nome, que é quando a execução é retomada. Portanto, a execução nunca será retomada em uma seção de rótulo definida antes do comando Goto.

Exemplo de código

Código de entrada:
 -- Additional Params: --scriptsTargetLanguage SnowScript
.LOGON dbc,dbc;
select 'STATEMENTS';
.GOTO LABEL_B
select 'IGNORED STATEMENTS';
.label LABEL_B
select 'LABEL_B STATEMENTS';
Copy
Código gerado
 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

Práticas recomendadas

SSC-FDM-TD0031

Os resultados de ST_DISTANCE são ligeiramente diferentes dos de ST_SPHERICALDISTANCE

Descrição

A função ST_SPHERICALDISTANCE do Teradata calcula a distância entre duas coordenadas esféricas no planeta usando a fórmula de Haversine, enquanto a função ST_DISTANCE do Snowflake não utiliza a fórmula de Haversine para calcular a distância mínima entre dois pontos geográficos.

Exemplo de código

Código de entrada:
 --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
Saída do Teradata

location1

location2

Distance_In_Km

POINT (-73.989308 40.741895)

POINT (40.741895 34.053691)

9351139,978062356

Código gerado
 --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
Saída do Snowflake

LOCATION1

LOCATION2

DISTANCE_IN_KM

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

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

9351154,65572674

Práticas recomendadas

SSC-FDM-TD0032

A cláusula CASESPECIFIC foi removida da expressão LIKE

Nota

Algumas partes do código de saída foram omitidas por motivos de clareza.

Descrição

Este erro ocorre quando a expressão LIKE é acompanhada pela cláusula [NOT] CASESPECIFIC.

Exemplo de código

Código de entrada:
 SELECT * FROM MY_TABLE
WHERE Name Like 'Marco%' (NOT CASESPECIFIC);
Copy
Código gerado
 SELECT
    * FROM
    MY_TABLE
WHERE Name ILIKE 'Marco%' /*** SSC-FDM-TD0032 - NOT CASESPECIFIC CLAUSE WAS REMOVED ***/;
Copy

Práticas recomendadas

  • O comportamento por caso de TERADATA depende da configuração do sistema TMODE.

  • Se precisar de mais suporte, envie um e-mail para snowconvert-support@snowflake.com

SSC-FDM-TD0033

A transformação ACTIVITY_COUNT pode exigir ajustes manuais.

Descrição

A variável de status ACTIVITY_COUNT retorna o número de linhas afetadas por uma instrução SQL DML em um aplicativo SQL incorporado ou de procedimento armazenado. Para mais informações, consulte aqui.

Conforme explicado em sua especificação de tradução, existe uma solução alternativa para emular o comportamento de ACTIVITY_COUNT através de:

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

No entanto, isso apresenta algumas limitações listadas abaixo.

Limitações

Primeiro caso

Se ACTIVITY_COUNT for chamada duas ou mais vezes antes da execução de outra instrução DML, a transformação poderá não retornar os valores esperados.

Teradata
 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
Snowflake
 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

Em ambos os procedimentos, ACTIVITY_COUNT é chamada duas vezes antes de outra instrução DML ser chamada. No Teradata, ACTIVITY_COUNT retornará o número de linhas na instrução INSERT acima, mesmo quando chamada duas vezes. No entanto, como a transformação Snowflake usa LAST_QUERY_ID(), o resultado depende do conjunto de resultados mantido por LAST_QUERY_ID().

InsertEmployeeSalaryAndLog_1() não requer ajustes manuais. Verifique o histórico de consultas (de baixo para cima):

Query History when calling InsertEmployeeSalaryAndLog_1()

  1. A instrução INSERT é executada. LAST_QUERY_ID() apontará para essa instrução.

  2. SELECT (primeiro ACTIVITY_COUNT) é executado e $1 será 1. LAST_QUERY_ID() apontará para essa instrução.

  3. SELECT (segundo ACTIVITY_COUNT) é executado; como o resultado da última instrução foi 1, $1 também será 1 para este SELECT.

  4. Por fim, row_count1 contém o valor 1, que é inserido em activity_log.

Por outro lado, InsertEmployeeSalaryAndLog_2() requer ajustes manuais. Verifique o histórico de consultas (de baixo para cima):

Query History when calling InsertEmployeeSalaryAndLog_2()

  1. A instrução INSERT é executada. LAST_QUERY_ID() apontará para essa instrução.

  2. SELECT (primeiro ACTIVITY_COUNT) é executado, e $1 será 1. No entanto, observe como QUERY_TEXT tem + 10; isso afetará o resultado que será verificado. LAST_QUERY_ID() apontará para essa instrução.

  3. SELECT (segundo ACTIVITY_COUNT) é executado. O resultado da última consulta é 11; portanto, $1 conterá 11 em vez do esperado 1.

  4. Por fim, row_count1 contém o valor 11, que é inserido em activity_log.

Estes são os valores inseridos em 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

Ajustes para o primeiro caso

Conforme a documentação do Snowflake para LAST_QUERY_ID, você pode especificar a consulta a ser retornada, com base na posição da consulta. LAST_QUERY_ID(-1) retorna a consulta mais recente, (-2) a penúltima consulta e assim por diante.

A solução para o problema no InsertEmployeeSalaryAndLog_2() será simplesmente especificar LAST_QUERY_ID(-2) no segundo uso de ACTIVITY_COUNT (segundo SELECT) para que obtenha os resultados da instrução INSERT:

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

Segundo caso

Se ACTIVITY_COUNT for chamado após a execução de uma instrução que não seja DML, a transformação não retornará os valores esperados.

Teradata
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
Snowflake
 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

Semelhante ao caso anterior, LAST_QUERY_ID não aponta para a consulta correta e, portanto, retorna um valor incorreto, que é atribuído a row_count1. Verifique o histórico de consultas (de baixo para cima):

Query History when calling InsertEmployeeSalaryAndLog_3()

  1. A instrução INSERT é executada. LAST_QUERY_ID() apontará para essa instrução.

  2. SELECT INTO é executado, e $1 será 101. LAST_QUERY_ID() apontará para essa instrução.

  3. SELECT (ACTIVITY_COUNT) é executado. O resultado da última consulta é 101; assim, $1 conterá 101 em vez do esperado 1.

  4. Por fim, row_count1 contém o valor 101, que é inserido em activity_log.

Estes são os valores inseridos em activity_log:

LOG_ID

OPERATION

ROW_COUNT

LOG_TIMESTAMP

1

EMPLOYEE INSERTED - ID: 101

101

2024-07-15 11:00:38.000

Ajustes para o segundo caso

  1. Uma possível solução é especificar a consulta correta a ser retornada por LAST_QUERY_ID. Por exemplo, aqui, LAST_QUERY_ID(-2) será a consulta correta para a qual apontar.

 ...
row_count1 := (
            SELECT
                $1
            FROM
                TABLE(RESULT_SCAN(LAST_QUERY_ID(-2)))
               ) /*** SSC-FDM-TD0033 - 'ACTIVITY_COUNT' TRANSFORMATION MIGHT REQUIRE MANUAL ADJUSTMENTS ***/;
               ...
Copy
  1. Outra possível solução é usar ACTIVITY_COUNT (SELECT) imediatamente após executar a instrução INSERT.

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

Práticas recomendadas

  • Certifique-se de apontar para a consulta correta ao usar LAST_QUERY_ID.

  • Certifique-se de que ACTIVITY_COUNT seja utilizado imediatamente após a instrução DML para avaliação.

  • Se precisar de mais suporte, envie um e-mail para snowconvert-support@snowflake.com

SSC-FDM-TD0034

Period contains transformada para uma função definida pelo usuário.

Descrição

A expressão CONTAINS do Teradata realiza uma validação indicando se o elemento à direita está contido no elemento à esquerda, que deve ser do tipo PERIOD. CONTAINS aplica-se apenas a DATE, TIME, TIMESTAMP ou PERIOD. Como PERIOD não é compatível com o Snowflake, uma função definida pelo usuário emulará a lógica do comportamento nativo de CONTAINS.

Exemplo de código

Código de entrada:
  UPDATE TABLE1
  SET COL1 = CURRENT_TIMESTAMP
  WHERE COL3 CONTAINS CURRENT_TIMESTAMP;
Copy
Código gerado
  UPDATE TABLE1
  SET
    COL1 = CURRENT_TIMESTAMP()
  WHERE
    PUBLIC.PERIOD_CONTAINS_UDF(COL3, CURRENT_TIMESTAMP()) /*** SSC-FDM-TD0034 - PERIOD CONTAINS EXPRESSION TRANSFORMED TO USER DEFINED FUNCTION. ***/
Copy

Práticas recomendadas

  • O VARCHAR utilizado em vez de PERIOD pressupõe o formato <PERIOD_BEGIN>*<PERIOD_END> em todos os valores. Se os valores forem divididos por um token diferente de *, você poderá alterar o valor retornado pela UDF PUBLIC.GET_PERIOD_SEPARATOR fornecida pelo SnowConvert AI. Observe que a estrutura deve ter um token que marque o início e o fim de um PERIOD; portanto, as duas datas, horários ou carimbos de data/hora devem ser sempre separados com o mesmo token.

  • Se precisar de mais suporte, envie um e-mail para snowconvert-support@snowflake.com

SSC-FDM-TD0035

A função de estatísticas não é necessária no Snowflake.

Nota

Esta FDM está obsoleta; consulte a documentação SSC-EWI-0037.

Descrição

As estatísticas DROP, COLLECT ou HELP não são necessárias no Snowflake. O Snowflake já coleta estatísticas utilizadas para otimização automática de consultas, e é por isso que essas instruções de estatísticas são usadas no Teradata.

Exemplo de código

Código de entrada:
  HELP STATISTICS TestName;
Copy
Código gerado
  ----** SSC-FDM-TD0035 - HELP STATISTICS NOT NEEDED. SNOWFLAKE AUTOMATICALLY COLLECTS STATISTICS. **
  --HELP STATISTICS TestName
Copy

Práticas recomendadas

SSC-FDM-TD0036

O Snowflake não é compatível com o tipo de dados de período; todos os períodos são tratados como varchar.

Nota

Algumas partes do código de saída foram omitidas por motivos de clareza.

Precisão das representações varchar geradas

PERIOD_UDF gera a representação varchar de um período usando os formatos padrão para carimbos de data/hora e tempo especificados no Snowflake. Isso significa que os carimbos de data/hora terão três dígitos de precisão e as variáveis de tempo terão zero. Por causa disso, você pode notar que os resultados têm uma precisão maior ou menor do que a esperada. Existem duas opções para modificar quantos dígitos de precisão são incluídos na cadeia de caracteres resultante:

  • Use a versão de três parâmetros de PERIOD_UDF: Essa sobrecarga da função usa o parâmetro PRECISIONDIGITS, um número inteiro entre 0 e 9, para controlar quantos dígitos da parte fracionária do tempo serão incluídos no resultado. Observe que, mesmo que o Snowflake seja compatível com até nove dígitos de precisão, o máximo no Teradata é seis. Exemplo:

Chamada

Resultado

PUBLIC.PERIOD_UDF(time '13:30:45.870556', time '15:35:20.344891', 0)

'13:30:45*15:35:20'

PUBLIC.PERIOD_UDF(time '13:30:45.870556', time '15:35:20.344891', 2)

'13:30:45.87*15:35:20.34'

PUBLIC.PERIOD_UDF(time '13:30:45.870556', time '15:35:20.344891', 5)

'13:30:45.87055*15:35:20.34489'

  • Altere os parâmetros de sessão TIMESTAMP_NTZ_OUTPUT_FORMAT e TIME_OUTPUT_FORMAT: Os comandos ALTER SESSION SET TIMESTAMP_NTZ_OUTPUT_FORMAT = <format> e ALTER SESSION SET TIME_OUTPUT_FORMAT = <format>

    podem ser utilizados para modificar os formatos que o Snowflake usa por padrão para a sessão atual. Modificá-los para incluir o número desejado de dígitos de precisão altera o resultado de execuções futuras de PERIOD_UDF para a sessão atual.

Exemplo de código

Código de entrada:
 create table vacations (
    employeeName varchar(50),
    duration period(date)
);

insert into vacations values ('Richard', period(date '2021-05-15', date '2021-06-15'));

select end(duration) from vacations;
Copy
Código gerado:
 CREATE OR REPLACE TABLE vacations (
    employeeName varchar(50),
    duration VARCHAR(24) /*** SSC-FDM-TD0036 - SNOWFLAKE DOES NOT SUPPORT THE PERIOD DATATYPE, ALL PERIODS ARE HANDLED AS VARCHAR INSTEAD ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
;

INSERT INTO vacations
VALUES ('Richard', PUBLIC.PERIOD_UDF(date '2021-05-15', date '2021-06-15') /*** SSC-FDM-TD0036 - SNOWFLAKE DOES NOT SUPPORT THE PERIOD DATATYPE, ALL PERIODS ARE HANDLED AS VARCHAR INSTEAD ***/);

SELECT
    PUBLIC.PERIOD_END_UDF(duration) /*** SSC-FDM-TD0036 - SNOWFLAKE DOES NOT SUPPORT THE PERIOD DATATYPE, ALL PERIODS ARE HANDLED AS VARCHAR INSTEAD ***/ from
    vacations;
Copy

Práticas recomendadas

  • Como o comportamento de PERIOD e as funções relacionadas são emulados usando varchar, recomendamos revisar os resultados obtidos para garantir que tudo esteja correto.

  • Se precisar de mais suporte, envie um e-mail para snowconvert-support@snowflake.com