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 > ]...
}
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;
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;
$$;
Problemas conhecidos¶
Instruções de atributos de condição sem suporte
CLASS_ORIGIN
CONDITION_IDENTIFIER
CONDITION_NUMBER
MESSAGE_LENGTH
RETURNED_SQLSTATE
SUBCLASS_ORIGIN
If¶
A transformação para a instrução IF é:
Teradata
IF value = 2 THEN
Snowflake
if(value == 2){
}
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
Snowflake
switch(value) {
case 0:EXEC(`SELECT * FROM PUBLIC.table1`,[]);
break;
default:EXEC(`UPDATE PUBLIC.table1 set name = "SpecificValue" where id = value`,[]);
break;
}
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;
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();
$$;
While¶
A transformação para a instrução while é:
Teradata
While¶
while (counter < 10) do
set counter = counter + 1;
Snowflake¶
While¶
while ( counter < 10) {
counter = counter + 1;
}
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;
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();
$$;
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;
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]);
$$;
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;
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`,[]);
}
}
$$;
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;
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);
$$;
Nesse SQL convertido, há várias conversões que ocorrem:
A definição
DYNAMIC RESULT SETS 2é convertida em uma variávelDYNAMIC_RESULTS.
var DYNAMIC_RESULTS = 2;
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ável
DYNAMIC_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 RETURNcomPREPAREé convertida para:
var RESULTSET = new CURSOR(() => FIRSTSTATEMENT,[],true);
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);
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;
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]);
$$;
O valor do argumento
P1deProcedure1é 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¶
SSC-EWI-0022: Um ou mais identificadores nessa instrução foram considerados parâmetros por padrão.
SSC-EWI-0023: Análise de desempenho - Um loop contém uma instrução de inserção, exclusão ou atualização.
SSC-EWI-0026: A variável pode exigir uma conversão para data, hora ou carimbo de data/hora.
SSC-FDM-TD0001: Esta mensagem é exibida quando o SnowConvert AI encontra um tipo de dados BLOB.