SnowConvert: Diferenças funcionais do Teradata

SSC-FDM-TD0001

Descrição

Essa mensagem é exibida quando o SnowConvert detecta um tipo de dados BLOB. Como o Snowflake não é compatível com BLOB, ele o converte automaticamente para o tipo de dados binário.

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

Descrição

Essa mensagem aparece quando o SnowConvert encontra um tipo de dados CLOB. Como o SnowConvert não é compatível com CLOB, ele o converte automaticamente 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

Descrição

Quando o SnowConvert migra os arquivos de script para o Snowflake Scripting, ele converte automaticamente os espaços reservados para variáveis no estilo Bash ($variable ou ${variable}) em seu formato equivalente no SnowSQL (&variable ou &{variable}).

Esse script requer SnowSQL para ser executado com êxito. Antes de executar o script migrado no SnowSQL, observe o seguinte:

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

Práticas recomendadas

SSC-FDM-TD0004

Descrição

O tipo de dados PERIOD do Teradata representa intervalos de tempo. Cada PERIOD tem um valor inicial e final do mesmo tipo (TIME, DATE, ou TIMESTAMP). O Teradata oferece funções integradas como PERIOD, BEGIN, END e OVERLAPS para criar e gerenciar esses intervalos de tempo.

Como o Snowflake não é compatível com o tipo de dados de período, o SnowConvert converte esse tipo e suas funções associadas usando regras de transformação específicas:

  • As declarações de tipo de período em tabelas de colunas são convertidas em duas colunas de tipo idêntico.

  • A função do construtor do valor do período é dividida em dois construtores separados: um para o valor inicial e outro para o valor final.

  • As funções que exigem parâmetros de tipo de período são convertidas em funções definidas pelo usuário (UDFs). Esses UDFs normalmente exigem dois parâmetros: um para o valor inicial e outro para o valor 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

Descrição

O Teradata permite que os usuários definam qualquer deslocamento de fuso horário entre -12:59 e +14:00 usando o comando SET TIME ZONE. No entanto, o Snowflake é compatível apenas com os fusos horários oficialmente listados no banco de dados de fusos horários do IANA.

Ao usar SET TIME ZONE com um deslocamento específico, o Snowflake o ajustará automaticamente para corresponder ao fuso horário padrão IANA mais próximo se o deslocamento especificado não corresponder exatamente a nenhum fuso horário padrão. Quando isso acontecer, o Snowflake exibirá uma mensagem de aviso para notificar você sobre o ajuste.

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

Descrição

Essa mensagem aparece quando o SnowConvert detecta uma visualização que contém a cláusula WITH CHECK OPTION. Como o Snowflake não oferece suporte a esse recurso, a cláusula é automaticamente comentada no código convertido.

Essa cláusula permite que você execute as operações INSERT e UPDATE em exibições atualizáveis. Quando você executa esses comandos na exibição, as alterações são automaticamente aplicadas à tabela subjacente associada a essa exibição.

A cláusula WHERE filtra quais linhas serão afetadas pelo comando na exibição.

Para obter mais informações sobre essa cláusula e sua funcionalidade, consulte a documentação oficial da Teradata.

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":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

Práticas recomendadas

SSC-FDM-TD0007

Descrição

Essa mensagem aparece quando o SnowConvert encontra uma cláusula COLLATE ao transformar o código com um tipo de dados Variant. Como os tipos de dados Variant não são compatíveis com as cláusulas COLLATE, o SnowConvert removerá a cláusula COLLATE e exibirá uma mensagem de notificação.

Exemplo de código

Código de entrada:
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 é automaticamente convertido para VARIANT. Todas as especificações NOT CASESPECIFIC são transformadas em sua cláusula COLLATE equivalente.

Práticas recomendadas

SSC-FDM-TD0008

Descrição

Ao usar delimitadores não literais que contenham espaços no Snowflake, você deve escapar do caractere de barra invertida para garantir a funcionalidade adequada.

Exemplo de código

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

Descrição

Essa mensagem aparece quando o SnowConvert detecta um DEFAULT SESSION com um tipo de dados diferente de VARCHAR. Nesses casos, o SnowConvert converte automaticamente o tipo de dados para VARCHAR e gera uma mensagem de notificação.

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

Vamos examinar esse exemplo. A coluna chamada «ColumnExample» é definida com um tipo de dados INTEGER e tem uma configuração DEFAULT SESSION. Como o tipo de dados é INTEGER e não VARCHAR, o sistema o converte automaticamente para VARCHAR na saída.

O tipo de dados de ColumnExample2 permanece inalterado porque já está definido como VARCHAR.

Práticas recomendadas

SSC-FDM-TD0010

Descrição

A tabela do Teradata DBC.COLUMNSV é mapeada para a tabela do Snowflake INFORMATION_SCHEMA.COLUMNS. No entanto, observe que:

  1. Algumas colunas do Teradata não têm colunas correspondentes no Snowflake

  2. Quando as colunas coincidem entre os sistemas, o conteúdo dos dados pode ser diferente

Uma visualização de amostra da estrutura da tabela DBC.COLUMNSV no Teradata

Uma visualização de amostra da tabela INFORMATION_SCHEMA.COLUMNS no Snowflake

Observe que o Snowflake não tem uma coluna equivalente para «ColumnFormat». Além disso, embora a coluna «DATA_TYPE» pareça corresponder à coluna «ColumnType» do Teradata, seu conteúdo é significativamente diferente.

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
TABLE_NAME = 'TableN';
Copy

Práticas recomendadas

  • Compare as colunas usadas no Teradata com as disponíveis no Snowflake para garantir que elas atendam às suas necessidades.

  • Para obter assistência adicional, entre em contato conosco pelo e-mail snowconvert-support@snowflake.com

SSC-FDM-TD0011

Descrição

O Snowflake não é compatível com os caracteres Unicode Basic Multilingual Plane (BMP). Essa mensagem aparece quando o SnowConvert converte o Teradata Literal de caractere delimitado do Unicode contendo sequências de escape Unicode BMP para o formato 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

  • Verifique se há um caractere Unicode que corresponda às suas necessidades.

  • Para obter assistência adicional, entre em contato conosco pelo e-mail snowconvert-support@snowflake.com

SSC-FDM-TD0012

Nota

Este FDM foi descontinuado. Para obter mais informações, consulte SSC-EWI-TD0006.

Descrição

O tipo de dados FLOAT não oferece suporte a valores padrão usando as especificações DEFAULT TIME, DEFAULT DATE, DEFAULT CURRENT_DATE, DEFAULT CURRENT_TIME ou DEFAULT CURRENT_TIMESTAMP.

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

Práticas recomendadas

SSC-FDM-TD0013

Descrição

Essa mensagem é exibida porque o código de erro armazenado na variável interna BTEQ ERRORCODE não pode ser mapeado diretamente para um código equivalente 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 de saída:
 -- 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

Descrição

Esse aviso aparece ao migrar o código BTEQ que executa instruções SQL de um arquivo de ambiente (por exemplo, $(<$INPUT_SQL_FILE)). Há uma diferença comportamental importante a ser observada: enquanto BTEQ continua executando as instruções restantes mesmo que uma delas falhe, o código gerado pelo Python interromperá a execução quando encontrar algum 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 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

Nota

Este FDM não é mais suportado. Para obter mais informações, consulte SSC-EWI-0009.

Descrição

Atualmente, o Snowflake suporta apenas a sintaxe de expressão regular básica do POSIX. Os recursos avançados de expressão regular não estão disponíveis.

Esse aviso aparece sempre que uma chamada de função para REGEX_SUBSTR, REGEX_REPLACE ou REGEX_INSTR é convertida em Snowflake. Ele alerta os usuários de que alguns recursos de expressão regular podem não ser compatíveis com o Snowflake. Os recursos importantes sem suporte incluem lookahead, lookbehind e non-capturing groups.

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

  • Revise cada padrão de expressão regular para determinar se são necessárias alterações manuais. Para obter mais detalhes sobre os recursos de regex do SnowFlakee as opções alternativas, veja aqui.

  • Para obter assistência adicional, entre em contato conosco pelo e-mail snowconvert-support@snowflake.com

SSC-FDM-TD0016

Descrição

No Teradata, as funções de expressão regular (REGEX_SUBSTR, _REGEX_REPLACE e REGEX_INSTR) incluem um parâmetro chamado «match_arg». Esse parâmetro é um argumento de caractere que aceita valores específicos.

  • 'i': Corresponde a caracteres independentemente de suas letras (maiúsculas ou minúsculas).

  • 'c': Corresponde aos caracteres exatamente como eles aparecem, considerando as maiúsculas e minúsculas.

  • 'n': Permite que o ponto (.) corresponda a caracteres de nova linha.

  • 'm': Trata a cadeia de caracteres de entrada como várias linhas separadas em vez de uma linha contínua.

  • 'l': Retorna NULL quando a cadeia de caracteres de entrada é maior que 16 MB, em vez de gerar um erro.

  • 'x': Ignora espaços e caracteres de espaço em branco no padrão.

A função aceita vários caracteres como entrada.

No Snowflake, essas funções usam _ regexp_parameters_ como seu argumento equivalente. Esse argumento é uma cadeia de caracteres que contém um ou mais caracteres que definem como a correspondência de padrão de expressão regular deve se comportar. Os valores aceitos são:

  • c: Torna a correspondência de padrões sensível a maiúsculas e minúsculas

  • i: Torna a correspondência de padrões insensível a maiúsculas e minúsculas

  • m: Permite a correspondência entre várias linhas

  • e: Permite a extração de subpadrões da correspondência

  • s: Permite que o curinga ponto (.) corresponda a caracteres de nova linha

Conforme mostrado, os indicadores de tipo de dados 'i', 'c', 'm' são idênticos em ambas as linguagens. O valor do Teradata 'n' corresponde a 's' no sistema de destino. No entanto, os valores do Teradata 'l' e 'x' não têm equivalentes correspondentes.

Ao usar o valor 'x', a funcionalidade é replicada usando a função REGEXP_REPLACE. No entanto, o parâmetro 'l' não pode ser replicado, o que resulta em uma mensagem de aviso.

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

Nota

Este FDM foi descontinuado. Para obter mais informações, consulte SSC-EWI-TD0076.

Descrição

As tabelas estrangeiras no Teradata permitem que você acesse dados armazenados em locais externos, como Amazon S3, Azure Blob Storage e Google Cloud Storage. Embora o Snowflake não ofereça suporte a essa sintaxe específica, você pode obter uma funcionalidade semelhante usando:

  • Tabelas externas

  • Tabelas Iceberg

  • Tabelas padrão

Tabelas estrangeiras

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 de saída:
 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

Recomendações

  • Para substituir as tabelas externas do Teradata, você pode usar as tabelas externas do Snowflake. Essas tabelas permitem que você consulte os dados armazenados em plataformas de armazenamento em nuvem (Amazon S3, Google Cloud Storage ou Microsoft Azure) como se estivessem em um banco de dados. As tabelas externas suportam todos os formatos de dados compatíveis com instruções COPY INTO .

  • As tabelas Iceberg do Snowflake oferecem outra solução. Essas tabelas usam formatos abertos e armazenam dados em arquivos Parquet em seu próprio armazenamento em nuvem.

  • As tabelas padrão do Snowflake também podem oferecer funcionalidade semelhante às tabelas externas do Teradata.

  • Para obter assistência adicional, entre em contato conosco pelo e-mail snowconvert-support@snowflake.com

SSC-FDM-TD0018

Nota

Este FDM não é mais suportado. Para obter mais informações, consulte SSC-EWI-TD0063.

Descrição

Esse erro ocorre quando o SnowConvert não consegue processar um caminho JSON porque o formato da cadeia de caracteres é inválido 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

Recomendações

  • Verifique se o caminho JSON está formatado corretamente e não contém caracteres inválidos.

  • Para obter assistência adicional, entre em contato conosco pelo e-mail snowconvert-support@snowflake.com

SSC-FDM-TD0019

Descrição

O Teradata permite que os usuários definam faixas de consulta (tags de metadados) em três níveis diferentes: transação, sessão e perfil. Os usuários podem recuperar esses valores de banda de consulta usando funções como GetQueryBandValue.

O Snowflake usa o parâmetro query_tag em vez de bandas de consulta. Você pode definir query_tag no nível da sessão, do usuário ou da conta. Observe que o Snowflake não oferece suporte a perfis.

Este Detalhe da Migração de Recursos (FMD) alerta os usuários de que o Snowflake não suporta tags de consulta em nível de transação ou de perfil. Em vez disso, as tags de consulta em nível de sessão serão usadas como alternativa. Essa alteração pode afetar a funcionalidade em determinados cenários.

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

Recomendações

  • Atualize seu código para implementar faixas de consulta no nível da sessão.

  • Para obter assistência adicional, entre em contato conosco pelo e-mail snowconvert-support@snowflake.com

SSC-FDM-TD0020

Nota

Para maior clareza, simplificamos o código omitindo algumas seções.

Descrição

Esse erro ocorre quando o SnowConvert tenta processar os dados JSON durante uma transformação, mas encontra JSON formatado incorretamente ou conteúdo JSON invá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

Recomendações

  • Verifique se o JSON segue o formato gramatical exigido pelo Teradata.

  • Para obter assistência adicional, entre em contato conosco pelo e-mail snowconvert-support@snowflake.com

SSC-FDM-TD0021

Nota

Este EWI foi descontinuado. Para obter informações atualizadas, consulte a documentação SSC-EWI-TD0046.

Descrição

Esse erro ocorre ao executar uma consulta que faz referência à tabela DBC.DATABASES e tenta selecionar uma coluna que não tem uma correspondência 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

Recomendações

SSC-FDM-TD0022

Descrição

Nos scripts do Teradata, as variáveis de shell servem como contêineres de armazenamento temporário para valores que você pode usar e modificar em todo o script. Para criar uma variável de shell, use um cifrão ($) seguido do nome da variável. Opcionalmente, você pode colocar o nome da variável entre chaves {}. Para atribuir um valor a uma variável do shell, use o sinal de igual (=).

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

As variáveis de shell têm uma finalidade semelhante à interpolação de cadeia de caracteres. Quando os scripts são convertidos em Python, as variáveis de shell mantêm sua funcionalidade executando o código convertido em um script de shell (arquivo .sh). Para preservar essa funcionalidade, as variáveis do shell no código convertido devem corresponder ao formato do código de entrada original.

Exemplo de código

Código de entrada:

 SELECT $column FROM ${tablename}
Copy
Código gerado
 #*** 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

Recomendações

  • Você deve executar o código convertido usando um script de shell.

  • Para obter assistência adicional, entre em contato conosco pelo e-mail snowconvert-support@snowflake.com

SSC-FDM-TD0023

Descrição

Essa mensagem de diferença de recurso (FDM) aparece quando o SnowConvert converte a função de similaridade do Teradata para o Snowflake. Observe que o comportamento da função pode ser diferente entre as duas plataformas.

Exemplo de código

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

Recomendações

SSC-FDM-TD0024

Descrição

Esse aviso aparece quando o SnowConvert detecta uma instrução CREATE TABLE com a opção SET. Como o Snowflake não é compatível com SET TABLE, o SnowConvert remove essa opção durante a conversão.

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

Recomendações

SSC-FDM-TD0025

Descrição

Os recursos temporais do banco de dados Teradata, que incluem tabelas temporais e operações baseadas em tempo (DDL e DML), não podem ser replicados diretamente no Snowflake. Atualmente, o Snowflake não oferece suporte a tabelas temporais ou gerenciamento de dados com reconhecimento de tempo da mesma forma que o Teradata. Para obter mais informações sobre os recursos temporais do Teradata, consulte Suporte temporal do banco de dados Teradata.

Essas instruções são reconhecidas pelo SnowConvert durante a análise, mas são removidas durante o processo de conversão para garantir a compatibilidade com o ambiente de execução do Snowflake.

Quando um comando abort for encontrado, ele será convertido em um comando Delete. Isso mantém a funcionalidade equivalente, permitindo que você reverta as operações de transação e restaure o banco de dados ao seu estado original.

Exemplo de código

O exemplo a seguir demonstra como um comando Temporal-form Select é convertido em um comando Select padrão.

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

Quando uma transação precisa ser revertida, o comando Abort é usado para cancelar todas as alterações feitas durante essa 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 de saída:
 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

Recomendações

SSC-FDM-TD0026

Nota

Para maior clareza, simplificamos o código omitindo algumas partes.

Descrição

Ao replicar a funcionalidade da instrução SQL IF, os desenvolvedores geralmente combinam os comandos GOTO com os comandos IF e LABEL. Essas combinações podem ser convertidas diretamente em declarações if, if-else ou if-elseif-else. Nesses casos, você deve remover os comandos GOTO para evitar sua conversão em seções LABEL, pois eles não são mais necessários.

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 gerado

 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
Recomendações

SSC-FDM-TD0027

Nota

Este FDM não é mais suportado. Para obter mais informações, consulte SSC-EWI-TD0061.

Descrição

O SnowConvert (SC) pode transformar a função TD_UNPIVOT do Teradata. Essa função permite que você converta dados de coluna em linhas, facilitando a análise e a manipulação dos dados.

Essa transformação precisa de informações sobre os nomes das colunas na(s) tabela(s) para funcionar corretamente. Se essas informações não estiverem disponíveis, a transformação poderá ser incompleta, com colunas ausentes no resultado. Nesses casos, é gerada uma mensagem EWI (Error, Warning, Information).

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 de saída:
 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

Recomendações

  • Você pode fornecer informações de coluna para a ferramenta de conversão usando um dos dois métodos:

    • Inclua a especificação da tabela no mesmo arquivo que a chamada TD_UNPIVOT

    • Liste colunas específicas na consulta SELECT da expressão ON em vez de usar SELECT * ou apenas o nome da tabela

  • Se você estiver desvinculando as colunas ALL das tabelas de entrada, poderá ignorar esse problema. No entanto, se você estiver desvinculando apenas algumas colunas, o resultado será a falta de dados.

  • Para obter suporte adicional, entre em contato conosco pelo e-mail snowconvert-support@snowflake.com

SSC-FDM-TD0028

Nota

Este FDM não é mais suportado. Para obter mais informações, consulte SSC-EWI-TD0060.

Descrição

A ferramenta SnowConvert pode transformar a função JSON_TABLE, mas precisa saber os nomes específicos das colunas que estão sendo selecionadas na subconsulta JSON_TABLE ON para realizar a transformação corretamente.

Esse aviso aparece quando os nomes das colunas não são explicitamente especificados em uma subconsulta (por exemplo, ao usar SELECT *) e o sistema não consegue encontrar as informações de estrutura da tabela. Sem essas informações, o sistema não pode determinar os nomes específicos das colunas que estão sendo referenciadas.

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 de saída:
 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

Recomendações

  • Certifique-se de que você inclua a definição da tabela ao fornecer o código para o SnowConvert. Sem isso, você precisará executar o código novamente.

  • Para obter assistência adicional, entre em contato conosco pelo e-mail snowconvert-support@snowflake.com

SSC-FDM-TD0029

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

Os seguintes elementos de formato do Teradata são mapeados para funções do Snowflake que exigem configurações específicas de parâmetros de sessão. Para garantir resultados consistentes entre o Teradata e o Snowflake, você deve configurar esses parâmetros de sessão para corresponder às configurações do Teradata:

  • D: Mapeado para a função DAYOFWEEK. Os resultados diferem entre o Teradata e o Snowflake devido às diferentes configurações padrão. A Teradata usa o domingo como o primeiro dia da semana, enquanto o Snowflake usa a segunda-feira. Isso é controlado pelo parâmetro de sessão WEEK_START.

  • WW: Mapeado para a função WEEK. O comportamento é controlado pelo parâmetro de sessão WEEK_OF_YEAR_POLICY. A configuração padrão do Snowflake segue o padrão ISO (a primeira semana deve conter pelo menos quatro dias de janeiro). A Teradata considera o dia 1º de janeiro como o início da primeira semana.

Para alterar os parâmetros da sessão, use o comando ALTER SESSION SET parameter_name = value. Para obter mais detalhes sobre os parâmetros de sessão disponíveis, visite esta página.

Versão de parâmetro único de TO_CHAR

A função TO_CHAR(Datetime) com um único parâmetro usa formatos padrão de data e hora definidos nos parâmetros da sessão. Esses parâmetros incluem:

  • TIMESTAMP_LTZ_OUTPUT_FORMAT

  • TIMESTAMP_NTZ_OUTPUT_FORMAT

  • TIMESTAMP_TZ_OUTPUT_FORMAT

  • TIME_OUTPUT_FORMAT

Para garantir um comportamento consistente entre o Teradata e o Snowflake, certifique-se de que esses parâmetros correspondam às configurações do Teradata.

Ao converter valores numéricos em cadeias de caracteres usando TO_CHAR(Numeric), o Snowflake usa automaticamente o formato TM9 ou TME para criar uma representação de string compacta. Como o Teradata também cria representações de números compactos por padrão, nenhuma formatação adicional é 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 de saída:
 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 trabalhar com as Funções de formato (FF), use os tipos DateTime que correspondem à precisão do Teradata ou especifique uma precisão no elemento de formato para garantir um comportamento consistente.

  • Para a formatação do fuso horário, certifique-se de que o primeiro parâmetro seja do tipo TIMESTAMP_TZ para obter resultados consistentes. Observe que o tipo de dados TIME do Snowflake não oferece suporte a informações de fuso horário.

  • Configure os parâmetros de sessão para corresponder aos valores padrão do Teradata para manter um comportamento consistente.

  • Para obter assistência adicional, entre em contato conosco pelo e-mail snowconvert-support@snowflake.com

SSC-FDM-TD0030

Descrição

Quando o SC substitui uma instrução Goto por uma seção Label, ele adiciona automaticamente uma instrução return no final da seção, se não houver nenhuma. Isso garante que o fluxo de execução do programa permaneça o mesmo que no código original.

Quando um comando Goto BTEQ é executado, todas as instruções entre o comando Goto e o rótulo correspondente são ignoradas. Para evitar qualquer execução não intencional após atingir o rótulo, você deve incluir uma instrução de retorno na seção do rótulo.

É importante observar que, ao usar o comando Goto, ele pula todos os comandos até encontrar um rótulo correspondente. A execução do programa continua a partir desse rótulo. O programa nunca executará nenhuma seção do Label que apareça 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 de saída
 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

Recomendações

SSC-FDM-TD0031

Descrição

A função do Teradata ST_SPHERICALDISTANCE usa a fórmula de Haversine para calcular a distância entre dois pontos na Terra usando coordenadas esféricas. Em contrapartida, a função ST_DISTANCE do Snowflake usa um método diferente para medir a distância 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
Resultados do Teradata

location1

location2

Distance_In_Km

POINT (-73.989308 40.741895)

POINT (40.741895 34.053691)

9351139,978062356

Código de saída
 --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
Resultados do Snowflake

LOCATION1

LOCATION2

DISTANCE_IN_KM

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

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

9351154,65572674

Recomendações

SSC-FDM-TD0032

Nota

Para maior clareza, simplificamos algumas seções do código de saída.

Descrição

Esse erro ocorre quando uma expressão LIKE inclui a 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 de saída
 SELECT
* FROM
MY_TABLE
WHERE Name LIKE 'Marco%' /*** SSC-FDM-TD0032 - NOT CASESPECIFIC CLAUSE WAS REMOVED ***/;
Copy

Recomendações

  • O comportamento de sensibilidade a maiúsculas e minúsculas do TERADATA é determinado pela definição de configuração do sistema TMODE.

  • Para obter assistência adicional, entre em contato conosco pelo e-mail snowconvert-support@snowflake.com

SSC-FDM-TD0033

Descrição

A variável de status ACTIVITY_COUNT mostra quantas linhas foram modificadas por uma instrução DML (como INSERT, UPDATE ou DELETE) quando usada em procedimentos incorporados SQL ou armazenados. Para obter mais detalhes, acesse [aqui] (https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Stored-Procedures-and-Embedded-SQL/Result-Code-Variables/ACTIVITY_COUNT).

Para reproduzir o comportamento de ACTIVITY_COUNT, você pode usar a solução alternativa descrita na especificação da conversão.

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

No entanto, há várias limitações a serem consideradas:

Limitações

Primeiro caso

Se você chamar ACTIVITY_COUNT várias vezes antes de executar outra instrução DML, poderá receber resultados incorretos. Certifique-se de executar uma instrução DML entre cada chamada ACTIVITY_COUNT para obter valores precisos.

 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

Ao usar ACTIVITY_COUNT no Teradata, você pode chamá-lo várias vezes após uma instrução DML (como INSERT), e ele retornará consistentemente o número de linhas afetadas dessa instrução. No entanto, no Snowflake, o código transformado usa LAST_QUERY_ID(), que tem um comportamento diferente. O resultado de LAST_QUERY_ID() depende da consulta mais recente executada, portanto, várias chamadas podem não retornar o mesmo valor se outras consultas forem executadas nesse intervalo.

O procedimento armazenado InsertEmployeeSalaryAndLog_1() funciona sem exigir nenhuma modificação. Você pode verificar isso revisando o histórico de consultas em ordem cronológica, de baixo para cima.

Histórico de consultas mostrando a execução de InsertEmployeeSalaryAndLog_1()

  1. A instrução INSERT é executada primeiro e LAST_QUERY_ID() faz referência a essa operação.

  2. A primeira instrução SELECT com ACTIVITY_COUNT é executada, definindo $1 para 1. LAST_QUERY_ID() agora aponta para essa instrução SELECT.

  3. A segunda instrução SELECT com ACTIVITY_COUNT é executada. Como a instrução anterior retornou 1, $1 permanece 1 para este SELECT.

  4. O valor 1 é armazenado em row_count1 e, em seguida, é inserido na tabela activity_log.

Observando o procedimento InsertEmployeeSalaryAndLog_2(), são necessárias modificações manuais. Vamos examinar o histórico de consultas em ordem cronológica, começando pelas entradas mais antigas.

Histórico de consultas mostrando os resultados da execução do procedimento InsertEmployeeSalaryAndLog_2()

  1. Quando a instrução INSERT é executada, LAST_QUERY_ID() faz referência a essa instrução específica.

  2. Durante o primeiro SELECT com ACTIVITY_COUNT, $1 é igual a 1. No entanto, QUERY_TEXT contém + 10, o que modificará o resultado final. Nesse momento, LAST_QUERY_ID() aponta para essa instrução SELECT.

  3. Quando o segundo SELECT com ACTIVITY_COUNT é executado, ele retorna 11 (em vez de 1) por causa da consulta anterior. Esse valor é armazenado em $1.

  4. A variável row_count1 recebe o valor 11, que é então armazenado na tabela activity_log.

Os valores a seguir são armazenados na tabela 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

De acordo com a documentação do Snowflake para LAST_QUERY_ID, você pode recuperar consultas específicas usando um número de posição. Por exemplo:

  • LAST_QUERY_ID(-1) recupera a consulta mais recente

  • LAST_QUERY_ID(-2) recupera a segunda consulta mais recente e assim por diante para consultas mais antigas.

A solução para corrigir o problema em InsertEmployeeSalaryAndLog_2() é usar LAST_QUERY_ID(-2) na segunda instrução SELECT ao recuperar ACTIVITY_COUNT. Isso garante que obtenhamos a contagem de linhas da instrução INSERT anterior.

 ...
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 usado após a execução de uma instrução que não sejaDML (como SELECT), ele não retornará a contagem correta das linhas afetadas.

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

A função LAST_QUERY_ID retorna um valor incorreto para row_count1 porque faz referência à consulta errada. Você pode verificar isso revisando o histórico de consultas em ordem cronológica inversa.

Histórico de consultas mostrando os resultados da execução de InsertEmployeeSalaryAndLog_3()

  1. Primeiro, uma instrução INSERT é executada. A função LAST_QUERY_ID() faz referência a essa operação INSERT.

  2. Em seguida, uma instrução SELECT INTO é executada, definindo $1 como 101. A função LAST_QUERY_ID() agora aponta para essa operação SELECT INTO.

  3. Em seguida, uma instrução SELECT é executada para obter ACTIVITY_COUNT. Como a última consulta retornou 101, $1 contém 101 em vez do valor esperado de 1.

  4. Como resultado, row_count1 armazena 101, que é então registrado na tabela activity_log.

Os seguintes valores são registrados no 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. Para resolver esse problema, use LAST_QUERY_ID com o número de referência de consulta correto. Por exemplo, LAST_QUERY_ID(-2) recuperará a consulta específica de que você precisa.

 ...
row_count1 := (
            SELECT
                $1
            FROM
                TABLE(RESULT_SCAN(LAST_QUERY_ID(-2)))
               ) /*** SSC-FDM-TD0033 - 'ACTIVITY_COUNT' TRANSFORMATION MIGHT REQUIRE MANUAL ADJUSTMENTS ***/;
               ...
Copy
  1. Você também pode verificar o sucesso da instrução INSERT verificando o ACTIVITY_COUNT usando uma instrução SELECT logo após a inserção.

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

Recomendações

  • Ao usar LAST_QUERY_ID, verifique se você está fazendo referência à consulta pretendida.

  • Execute ACTIVITY_COUNT imediatamente após sua instrução DML para garantir uma avaliação precisa.

  • Para obter assistência adicional, entre em contato conosco pelo e-mail snowconvert-support@snowflake.com