SnowConvert AI – Teradata – SQL para JavaScript (Procedimentos)

GET DIAGNOSTICS EXCEPTION

Referência de tradução para converter a instrução Teradata GET DIAGNOSTICS EXCEPTION para o Snowflake Scripting.

Descrição

GET DIAGNOSTICS recupera informações sobre condições de sucesso, exceção ou conclusão da área de diagnóstico.

Para obter mais informações sobre o Teradata GET DIAGNOSTICS, acesse aqui.

 GET DIAGNOSTICS
{
  [ EXCEPTION < condition_number >
    [ < parameter_name | variable_name > = < information_item > ]...
  ] 
  |
  [ < parameter_name | variable_name > = < information_item > ]...
}
Copy

Nota

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

Amostra de padrões de origem

Teradata

Consulta
 -- Additional Params: -t JavaScript
CREATE PROCEDURE getDiagnosticsSample ()
BEGIN
    DECLARE V_MESSAGE, V_CODE VARCHAR(200);
    DECLARE V_Result INTEGER;
    SELECT c1 INTO V_Result FROM tab1;
    GET DIAGNOSTICS EXCEPTION 1 V_MESSAGE = MESSAGE_TEXT;
END;
Copy
Snowflake
Javascript
 CREATE OR REPLACE PROCEDURE getDiagnosticsSample ()
RETURNS STRING
LANGUAGE JAVASCRIPT
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
    // SnowConvert AI Helpers Code section is omitted.

    var V_MESSAGE;
    var V_CODE;
    var V_RESULT;
    EXEC(`SELECT c1 FROM tab1`,[]);
    [V_RESULT] = INTO();
    V_MESSAGE = MESSAGE_TEXT;
$$;
Copy

Problemas conhecidos

  1. Instruções de atributos de condição sem suporte

    1. CLASS_ORIGIN

    2. CONDITION_IDENTIFIER

    3. CONDITION_NUMBER

    4. MESSAGE_LENGTH

    5. RETURNED_SQLSTATE

    6. SUBCLASS_ORIGIN

If

A transformação para a instrução IF é:

Teradata

 IF value = 2 THEN
Copy

Snowflake

 if(value == 2){
}
Copy

Case

A transformação para a instrução Case é:

Teradata

 case value
when 0 then
  select * from table1
else
  update table1 set name = "SpecificValue" where id = value;
end case
Copy

Snowflake

 switch(value) {
    case 0:EXEC(`SELECT * FROM PUBLIC.table1`,[]);
        break;
    default:EXEC(`UPDATE PUBLIC.table1 set name = "SpecificValue" where id = value`,[]);
        break;
}
Copy

Cursor Declare, OPEN, FETCH e CLOSE

A transformação para instruções de cursor é a seguinte:

Teradata

Cursor

 -- Additional Params: -t JavaScript
CREATE PROCEDURE procedure1()               
DYNAMIC RESULT SETS 2
BEGIN

    -------- Local variables --------
    DECLARE sql_cmd VARCHAR(20000) DEFAULT ' '; 
    DECLARE num_cols INTEGER;
    
    ------- Declare cursor with return only-------
    DECLARE resultset CURSOR WITH RETURN ONLY FOR firststatement;

    ------- Declare cursor -------
    DECLARE cur2 CURSOR FOR SELECT COUNT(columnname) FROM table1;
    
    -------- Set --------
    SET sql_cmd='sel * from table1';
    
    -------- Prepare cursor --------
    PREPARE firststatement FROM sql_cmd; 
    
    -------- Open cursors --------
    OPEN resultset;		
    OPEN cur1;

    -------- Fetch -------------
    FETCH cur1 INTO val1, val2;
    
    -------- Close cursor --------
    CLOSE cur1;
END;
Copy

Snowflake

Cursor JavaScript

 CREATE OR REPLACE PROCEDURE procedure1 ()
RETURNS STRING
LANGUAGE JAVASCRIPT
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
    // SnowConvert AI Helpers Code section is omitted.

    //------ Local variables --------
    var SQL_CMD = ` `;
    var NUM_COLS;
    var RESULTSET = new CURSOR(() => FIRSTSTATEMENT,[],true);
    //----- Declare cursor -------
    var CUR2 = new CURSOR(`SELECT COUNT(columnname) FROM table1`,[],false);
    //------ Set --------
    SQL_CMD = `SELECT * from table1`;
    //------ Prepare cursor --------
    var FIRSTSTATEMENT = SQL_CMD;
    //------ Open cursors --------
    RESULTSET.OPEN();
    CUR1.OPEN();
    //------ Fetch -------------
    CUR1.FETCH() && ([val1,val2] = CUR1.INTO());
    //------ Close cursor --------
    CUR1.CLOSE();
    return PROCRESULTS();
$$;
Copy

While

A transformação para a instrução while é:

Teradata

While

 while (counter < 10) do
    set counter = counter + 1;
Copy

Snowflake

While

 while ( counter < 10) {
    counter = counter + 1;
}
Copy

Security

A transformação para instruções de segurança é:

Teradata

Snowflake

SQL SECURITY CREATOR

EXECUTE AS OWNER

SQL SECURITY INVOKER

EXECUTE AS CALLER

SQL SECURITY DEFINER

EXECUTE AS OWNER

FOR-CURSOR-FOR loop

A transformação para loop FOR-CURSOR-FOR é a seguinte:

Teradata

For-Cursor-For-Loop

-- Additional Params: -t JavaScript
REPLACE PROCEDURE Database1.Proc1()
BEGIN
    DECLARE lNumber INTEGER DEFAULT 1;
    FOR class1 AS class2 CURSOR FOR 
      SELECT COL0,
      TRIM(COL1) AS COL1ALIAS,
      TRIM(COL2),
      COL3
      FROM someDb.prefixCol
    DO
      INSERT INTO TempDB.Table1 (:lgNumber, :lNumber, (',' || :class1.ClassCD || '_Ind CHAR(1) NOT NULL'));
      SET lNumber = lNumber + 1;
    END FOR;
END;
Copy

Snowflake

For-Cursor-For-Loop JavaScript

 CREATE OR REPLACE PROCEDURE Database1.Proc1 ()
RETURNS STRING
LANGUAGE JAVASCRIPT
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
    // SnowConvert AI Helpers Code section is omitted.

    var LNUMBER = 1;
    /*** SSC-EWI-0023 - PERFORMANCE REVIEW - THIS LOOP CONTAINS AN INSERT, DELETE OR UPDATE STATEMENT ***/
    for(var CLASS2 = new CURSOR(`SELECT
   COL0,
   TRIM(COL1) AS COL1ALIAS,
   TRIM(COL2),
   COL3
FROM
   someDb.prefixCol`,[],false).OPEN();CLASS2.NEXT();) {
        let CLASS1 = CLASS2.CURRENT;
        EXEC(`INSERT INTO TempDB.Table1
VALUES (:lgNumber, :1, (',' || :
!!!RESOLVE EWI!!! /*** SSC-EWI-0026 - THE  VARIABLE class1.ClassCD MAY REQUIRE A CAST TO DATE, TIME OR TIMESTAMP ***/!!!
:2 || '_Ind CHAR(1) NOT NULL'))`,[LNUMBER,CLASS1.CLASSCD]);
        LNUMBER = LNUMBER + 1;
    }
    CLASS2.CLOSE();
$$;
Copy

Nota: O loop FOR presente no procedimento Teradata é transformado em um bloco FOR em javascript que emula sua funcionalidade.

Parâmetros e variáveis de procedimento referenciados dentro de instruções

A transformação para os parâmetros e variáveis do procedimento que são referenciados dentro das instruções do procedimento é:

Teradata

Parâmetros e variáveis

 -- Additional Params: -t JavaScript
REPLACE PROCEDURE PROC1 (param1 INTEGER, param2 VARCHAR(30))
BEGIN
    DECLARE var1          VARCHAR(1024); 
    DECLARE var2          SMALLINT;
    DECLARE weekstart date;                                 
    set weekstart= '2019-03-03';
    set var1 = 'something';
    set var2 = 123;

    SELECT * FROM TABLE1 WHERE SOMETHING = :param1;
    SELECT * FROM TABLE1 WHERE var1 = var1 AND date1 = weekstart AND param2 = :param2;
    INSERT INTO TABLE2 (col1, col2, col3, col4, col5) VALUES (:param1, :param2, var1, var2, weekstart);
END;
Copy

Snowflake

Parâmetros e variáveis JavaScript

 CREATE OR REPLACE PROCEDURE PROC1 (PARAM1 FLOAT, PARAM2 STRING)
RETURNS STRING
LANGUAGE JAVASCRIPT
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
    // SnowConvert AI Helpers Code section is omitted.

    var VAR1;
    var VAR2;
    var WEEKSTART;
    WEEKSTART = `2019-03-03`;
    VAR1 = `something`;
    VAR2 = 123;
    // ** SSC-EWI-0022 - ONE OR MORE IDENTIFIERS IN THIS STATEMENT WERE CONSIDERED PARAMETERS BY DEFAULT. REFERENCED TABLE NOT FOUND. **
    EXEC(`SELECT * FROM TABLE1 WHERE SOMETHING = :1`,[PARAM1]);
    // ** SSC-EWI-0022 - ONE OR MORE IDENTIFIERS IN THIS STATEMENT WERE CONSIDERED PARAMETERS BY DEFAULT. REFERENCED TABLE NOT FOUND. **
    EXEC(`SELECT * FROM TABLE1 WHERE :1 = :1 AND date1 = :2 AND param2 = :3`,[VAR1,WEEKSTART,PARAM2]);
    // ** SSC-EWI-0022 - ONE OR MORE IDENTIFIERS IN THIS STATEMENT WERE CONSIDERED PARAMETERS BY DEFAULT. REFERENCED TABLE NOT FOUND. **
    EXEC(`INSERT INTO TABLE2 (col1, col2, col3, col4, col5) VALUES (:1, :2, :3, :4, :5)`,[PARAM1,PARAM2,VAR1,VAR2,WEEKSTART]);
$$;
Copy

Nota: Sempre que um parâmetro de procedimento ou uma variável declarada dentro do procedimento for referenciada dentro de uma instrução do Teradata que precisa ser convertida, essa referência é escapada do texto resultante para preservar a funcionalidade da referência original.

Leave

Em Javascript, é possível usar break com um parâmetro adicional, emulando assim o comportamento de um salto do Teradata LEAVE.

Os rótulos também podem ser emulados com o uso de instruções rotuladas em Javascript.

A transformação para a instruçãoLEAVE é:

Teradata

Leave

-- Additional Params: -t JavaScript
REPLACE PROCEDURE  PROC1 ()
BEGIN
  DECLARE v_propval            VARCHAR(1024);
 
 DECLARE Cur1 cursor for 
   Select 
      propID
   from viewName.viewCol
   where propval is not null;

LABEL_WHILE:
  WHILE (SQLCODE = 0)
  DO
      IF (SQLSTATE = '02000' ) 
       THEN LEAVE LABEL_WHILE;
      END IF;
      LABEL_INNER_WHILE:
      WHILE (SQLCODE = 0)
      DO
        IF (SQLSTATE = '02000' ) 
          THEN LEAVE LABEL_INNER_WHILE;
        END IF;
      END WHILE LABEL_INNER_WHILE;
      SELECT * FROM TABLE1;
  END WHILE L1;
END;
Copy

Snowflake

Leave JavaScript

 CREATE OR REPLACE PROCEDURE PROC1 ()
RETURNS STRING
LANGUAGE JAVASCRIPT
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
 // SnowConvert AI Helpers Code section is omitted.

 var V_PROPVAL;
 var CUR1 = new CURSOR(`SELECT propID from viewName.viewCol
  where
  propval is not null`,[],false);
  LABEL_WHILE: {
  while ( SQLCODE == 0 ) {
   if (SQLSTATE == `02000`) {
    break LABEL_WHILE;
   }
   LABEL_INNER_WHILE: {
    while ( SQLCODE == 0 ) {
     if (SQLSTATE == `02000`) {
      break LABEL_INNER_WHILE;
     }
    }
   }
   EXEC(`SELECT * FROM TABLE1`,[]);
  }
 }
$$;
Copy

Obtendo resultados dos procedimentos

Descrição da conversão

No Teradata, há duas maneiras de retornar dados de um procedimento. O primeiro é por meio de parâmetros de saída e o segundo por meio de Conjuntos de resultados dinâmicos e Cursores. Ambos são mostrados no exemplo a seguir. Cada ponto importante é explicado a seguir.

Exemplo de retorno de dados de um procedimento armazenado

Teradata

Parâmetro Out

-- Additional Params: -t JavaScript
REPLACE PROCEDURE Procedure1(OUT P1 INTEGER)               
    DYNAMIC RESULT SETS 2
    BEGIN
        DECLARE SQL_CMD,SQL_CMD_1  VARCHAR(20000) DEFAULT ' ';
        DECLARE RESULTSET CURSOR WITH RETURN ONLY FOR FIRSTSTATEMENT;
        SET SQL_CMD = 'SEL * FROM EMPLOYEE';
        PREPARE FIRSTSTATEMENT FROM SQL_CMD; 
        OPEN RESULTSET;
        SET P1 = (SEL CAST(AVG(AGE) AS INTEGER) FROM EMPLOYEE);
    END;
Copy

Snowflake

Parâmetro Out JavaScript
 CREATE OR REPLACE PROCEDURE Procedure1 (P1 FLOAT)
RETURNS STRING
LANGUAGE JAVASCRIPT
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
    // SnowConvert AI Helpers Code section is omitted.

    var SQL_CMD = ` `;
    var SQL_CMD_1 = ` `;
    var RESULTSET = new CURSOR(() => FIRSTSTATEMENT,[],true);
    SQL_CMD = `SELECT * FROM EMPLOYEE`;
    var FIRSTSTATEMENT = SQL_CMD;
    RESULTSET.OPEN();
    EXEC(`(
   SELECT
      CAST(AVG(AGE) AS INTEGER)
   FROM
      EMPLOYEE
)`,[]);
    var subQueryVariable0;
    [subQueryVariable0] = INTO();
    P1 = subQueryVariable0;
    return PROCRESULTS(P1);
$$;
Copy

Nesse SQL convertido, há várias conversões que ocorrem:

  • A definição DYNAMIC RESULT SETS 2 é convertida em uma variável DYNAMIC_RESULTS.

     var DYNAMIC_RESULTS = 2;
    
Copy
  • Quando um cursor com um atributo WITH RETURN é aberto (e, portanto, uma consulta é executada), sua ID de consulta é armazenada na coleção_ OUTQUERIESpara ser retornada posteriormente. O ID da consulta é obtido pela funçãogetQueryId()fornecida na API JavaScript para procedimentos armazenados do Snowflake.

  • Somente as primeiras k-query-IDs são armazenadas na coleção, em que k é o valor da variávelDYNAMIC_RESULTS. Isso é feito para imitar o comportamento do Teradata, que retorna apenas os primeiros k-opened-cursors, mesmo que mais sejam abertos no procedimento armazenado.

  • A combinação de DECLARE CURSOR WITH RETURN com PREPARE é convertida para:

     var RESULTSET = new CURSOR(() => FIRSTSTATEMENT,[],true);
    
Copy
  • Os parâmetros de saída são suportados por meio da instrução de retorno do procedimento. É criada uma matriz que contém o valor de cada parâmetro de saída e a coleção_OUTQUERIES. A funçãoPROCRESULTStrata da criação e do preenchimento dessa matriz. Consulte PROCRESULTS() helper para obter mais informações.

     return PROCRESULTS(P1);
    
Copy

Exemplo de obtenção de dados de um procedimento armazenado

Se os parâmetros de saída e IDs de consulta forem retornados de um procedimento, um segundo procedimento poderá chamar o primeiro para obter esses valores, conforme mostrado abaixo:

Teradata

Procedimento de chamada

 -- Additional Params: -t JavaScript
CREATE PROCEDURE Procedure2()
BEGIN
    DECLARE x INTEGER;
    CALL Procedure1(x);
END;
Copy

Snowflake

Procedimento de chamada JavaScript
 CREATE OR REPLACE PROCEDURE Procedure2 ()
RETURNS STRING
LANGUAGE JAVASCRIPT
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
    // SnowConvert AI Helpers Code section is omitted.

    var X;
    EXEC(`CALL Procedure1(:1)`,[X]);
$$;
Copy
  • O valor do argumentoP1deProcedure1é retornado e armazenado na variávelX.

  • O_OUTQUERIESretornado doProcedure1é armazenado na variávelresultset.

Nota

Esse comportamento também se aplica aos parâmetros de INOUT.

Problemas conhecidos

Não foram encontrados problemas.

EWIs relacionados

  1. SSC-EWI-0022: Um ou mais identificadores nessa instrução foram considerados parâmetros por padrão.

  2. SSC-EWI-0023: Análise de desempenho - Um loop contém uma instrução de inserção, exclusão ou atualização.

  3. SSC-EWI-0026: A variável pode exigir uma conversão para data, hora ou carimbo de data/hora.

  4. SSC-FDM-TD0001: Esta mensagem é exibida quando o SnowConvert AI encontra um tipo de dados BLOB.