SnowConvert: Teradata SQL para Snowflake Scripting (Procedimentos)¶
ABORT e ROLLBACK¶
Descrição ¶
As instruções ABORT
e ROLLBACK
do Teradata são substituídas por uma instrução ROLLBACK
no Snowflake Scripting.
Para obter mais informações sobre o Teradata ABORT e para ROLLBACK.
ABORT [abort_message] [FROM option] [WHERE abort_condition];
ROLLBACK [WORK] [abort_message] [FROM clause] [WHERE clause];
Amostra de padrões de origem ¶
ABORT e ROLLBACK básicos¶
Teradata ¶
REPLACE PROCEDURE procedureBasicAbort()
BEGIN
ABORT;
ROLLBACK;
END;
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE procedureBasicAbort ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
ROLLBACK;
ROLLBACK;
END;
$$;
ABORT e ROLLBACK condicionais¶
Teradata ¶
REPLACE PROCEDURE procedureWhereAbort(AnotherValueProc INTEGER)
BEGIN
ABORT WHERE AValueProc > 2;
ROLLBACK WHERE (AnotherValueProc > 2);
END;
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE procedureWhereAbort (ANOTHERVALUEPROC INTEGER)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/23/2024" }}'
EXECUTE AS CALLER
AS
$$
BEGIN
IF (AValueProc > 2) THEN
ROLLBACK;
END IF;
IF (AnotherValueProc > 2) THEN
ROLLBACK;
END IF;
END;
$$;
ABORT e ROLLBACK com referências de tabela e cláusula FROM¶
Teradata ¶
CREATE TABLE ReferenceTable
(ColumnValue INTEGER);
CREATE TABLE ReferenceTable2
(ColumnValue INTEGER);
REPLACE PROCEDURE procedureFromAbort()
BEGIN
ROLLBACK FROM ReferenceTable, ReferenceTable2
WHERE ReferenceTable.ColumnValue = ReferenceTable2.ColumnValue;
ABORT FROM ReferenceTable, ReferenceTable2
WHERE ReferenceTable.ColumnValue = ReferenceTable2.ColumnValue;
END;
Snowflake Scripting ¶
CREATE OR REPLACE TABLE ReferenceTable
(
ColumnValue INTEGER)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;
CREATE TABLE ReferenceTable2
(
ColumnValue INTEGER)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;
CREATE OR REPLACE PROCEDURE procedureFromAbort ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
LET _ROW_COUNT FLOAT;
SELECT
COUNT(*)
INTO
_ROW_COUNT
FROM
ReferenceTable,
ReferenceTable2
WHERE
ReferenceTable.ColumnValue = ReferenceTable2.ColumnValue;
IF (_ROW_COUNT > 0) THEN
ROLLBACK;
END IF;
SELECT
COUNT(*)
INTO
_ROW_COUNT
FROM
ReferenceTable,
ReferenceTable2
WHERE
ReferenceTable.ColumnValue = ReferenceTable2.ColumnValue;
IF (_ROW_COUNT > 0) THEN
ROLLBACK;
END IF;
END;
$$;
ABORT e ROLLBACK com referências de tabela sem a cláusula FROM¶
Teradata ¶
CREATE TABLE ReferenceTable
(ColumnValue INTEGER);
REPLACE PROCEDURE procedureFromTableAbort()
BEGIN
ROLLBACK WHERE ReferenceTable.ColumnValue > 2;
ABORT WHERE ReferenceTable.ColumnValue > 4;
END;
Snowflake Scripting ¶
CREATE OR REPLACE TABLE ReferenceTable
(
ColumnValue INTEGER)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;
CREATE OR REPLACE PROCEDURE procedureFromTableAbort ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
LET _ROW_COUNT FLOAT;
SELECT
COUNT(*)
INTO
_ROW_COUNT
FROM
ReferenceTable
WHERE
ReferenceTable.ColumnValue > 2;
IF (_ROW_COUNT > 0) THEN
ROLLBACK;
END IF;
SELECT
COUNT(*)
INTO
_ROW_COUNT
FROM
ReferenceTable
WHERE
ReferenceTable.ColumnValue > 4;
IF (_ROW_COUNT > 0) THEN
ROLLBACK;
END IF;
END;
$$;
Problemas conhecidos¶
1. Custom Error Message¶
Embora ROLLBACK AND ABORT seja suportado, não é possível usá-lo com uma mensagem de erro personalizada.
Teradata ¶
ABORT 'Error message for abort';
ROLLBACK 'Error message for rollback';
Snowflake Scripting ¶
ABORT 'Error message for abort';
ROLLBACK 'Error message for rollback';
2. Aggregate function¶
Não há suporte para o uso da função de agregação combinada com ABORT/ROLLBACK
Teradata ¶
ROLLBACK WHERE SUM(ATable.AValue) < 2;
ABORT WHERE SUM(ATable.AValue) < 2;
Snowflake Scripting ¶
ROLLBACK WHERE SUM(ATable.AValue) < 2;
ABORT WHERE SUM(ATable.AValue) < 2;
ACTIVITY_COUNT¶
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 incorporado SQL ou de procedimento armazenado. Para obter mais informações, veja aqui.
Não há equivalente direto no Snowflake. No entanto, há uma solução alternativa para emular o comportamento de ACTIVITY_COUNT
. Basta usar a seguinte consulta:
SELECT $1 FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()));
Essa consulta recupera e retorna a primeira coluna do conjunto de resultados da última consulta executada na sessão atual. Além disso, $1
pode ser substituído por "number of rows inserted"
, "number of rows updated"
ou "number of rows deleted"
com base no tipo de consulta.
Como esperado, essa conversão se comporta como sua contraparte do Teradata somente quando nenhuma outra consulta além da instrução SQL DML é executada antes de chamar LAST_QUERY_ID
.
Amostra de padrões da origem¶
Dados de configuração¶
Teradata¶
CREATE TABLE employees (
employee_id INT NOT NULL,
first_name VARCHAR(50),
last_name VARCHAR(50),
department_id INT,
salary DECIMAL(10,2),
PRIMARY KEY (employee_id)
);
INSERT INTO employees (employee_id, first_name, last_name, department_id, salary)
VALUES (1, 'John', 'Doe', 10, 60000.00);
INSERT INTO employees (employee_id, first_name, last_name, department_id, salary)
VALUES (2, 'Johny', 'Doey', 10, 65000.00);
INSERT INTO employees (employee_id, first_name, last_name, department_id, salary)
VALUES (3, 'Max', 'Smith', 10, 70000.00);
DROP TABLE activity_log;
CREATE TABLE activity_log (
log_id INT GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1) NOT NULL,
operation VARCHAR(200),
row_count INT,
log_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (log_id)
);
Snowflake¶
CREATE OR REPLACE TABLE employees (
employee_id INT NOT NULL,
first_name VARCHAR(50),
last_name VARCHAR(50),
department_id INT,
salary DECIMAL(10,2),
PRIMARY KEY (employee_id)
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/11/2024" }}'
;
INSERT INTO employees (employee_id, first_name, last_name, department_id, salary)
VALUES (1, 'John', 'Doe', 10, 60000.00);
INSERT INTO employees (employee_id, first_name, last_name, department_id, salary)
VALUES (2, 'Johny', 'Doey', 10, 65000.00);
INSERT INTO employees (employee_id, first_name, last_name, department_id, salary)
VALUES (3, 'Max', 'Smith', 10, 70000.00);
CREATE OR REPLACE TABLE activity_log (
log_id INT DEFAULT activity_log_log_id.NEXTVAL NOT NULL,
operation VARCHAR(200),
row_count INT,
log_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP(),
PRIMARY KEY (log_id)
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/11/2024" }}'
;
Uso suportado¶
Teradata¶
REPLACE PROCEDURE UpdateEmployeeSalaryAndLog ()
BEGIN
DECLARE row_count1 INT;
UPDATE employees
SET salary = 80000
WHERE department_id = 10;
-- Get the ACTIVITY_COUNT
SET row_count1 = ACTIVITY_COUNT;
-- Insert the ACTIVITY_COUNT into the activity_log table
INSERT INTO activity_log (operation, row_count)
VALUES ('UPDATE WHERE dept=10', row_count1);
END;
CALL UpdateEmployeeSalaryAndLog();
SELECT * FROM ACTIVITY_LOG;
LOG_ID | OPERATION | ROW_COUNT | LOG_TIMESTAMP |
-------+----------------------+-----------+----------------------------+
1 | UPDATE WHERE dept=10 | 3 | 2024-07-10 15:58:46.490000 |
Snowflake¶
CREATE OR REPLACE PROCEDURE UpdateEmployeeSalaryAndLog ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/11/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
row_count1 INT;
BEGIN
UPDATE employees
SET salary = 80000
WHERE department_id = 10;
-- 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 ***/;
-- Insert the ACTIVITY_COUNT into the activity_log table
INSERT INTO activity_log (operation, row_count)
VALUES ('UPDATE WHERE dept=10', :row_count1);
END;
$$;
CALL UpdateEmployeeSalaryAndLog();
SELECT
* FROM
ACTIVITY_LOG;
LOG_ID | OPERATION | ROW_COUNT | LOG_TIMESTAMP |
-------+----------------------+-----------+--------------------------+
102 | UPDATE WHERE dept=10 | 3 | 2024-07-11T12:42:35.280Z |
Problemas conhecidos¶
Se
ACTIVITY_COUNT
for chamado duas ou mais vezes antes da execução de uma instrução DML, a transformação poderá não retornar os valores esperados. Veja aqui.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. Veja aqui.ACTIVITY_COUNT
requer correção manual quando está dentro de uma instruçãoSELECT/SET INTO VARIABLE
e não pôde ser identificado como um nome de coluna. Veja aqui.
EWIs relacionados¶
SSC-FDM-TD0033: “ACTIVITY_COUNT” TRANSFORMATION MIGHT REQUIRE MANUAL ADJUSTMENTS.
BEGIN END¶
BEGIN END TRANSACTION¶
Descrição¶
Define o início de uma transação lógica explícita no modo de sessão do Teradata.
Para obter mais informações sobre Teradata BEGIN END Transaction, veja aqui.
[ BEGIN TRANSACTION | BT ]
statement
[ statement ]... ]
[ END TRANSACTION | ET ];
Amostra de padrão de origem ¶
Teradata ¶
REPLACE PROCEDURE BeginEndProcedure()
BEGIN
DECLARE HELLOSTRING VARCHAR(60);
BEGIN TRANSACTION
SET HELLOSTRING = 'HELLO WORLD';
END TRANSACTION;
END;
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE BeginEndProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
HELLOSTRING VARCHAR(60);
BEGIN
BEGIN TRANSACTION;
HELLOSTRING := 'HELLO WORLD';
COMMIT;
END;
$$;
BEGIN END REQUEST¶
Descrição¶
Delimita uma solicitação SQL com várias instruções
Para obter mais informações sobre o Teradata BEGIN END Request, veja aqui.
BEGIN REQUEST
statement
[ statement ]... ]
END REQUEST;
Amostra de padrão de origem ¶
Teradata ¶
REPLACE PROCEDURE BeginEndProcedure()
BEGIN
DECLARE HELLOSTRING VARCHAR(60);
BEGIN REQUEST
SET HELLOSTRING = 'HELLO WORLD';
END REQUEST;
END;
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE BeginEndProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
HELLOSTRING VARCHAR(60);
BEGIN
BEGIN
HELLOSTRING := 'HELLO WORLD';
COMMIT;
EXCEPTION
WHEN OTHER THEN
ROLLBACK;
END;
END;
$$;
BEGIN END COMPOUND¶
Descrição¶
Delimita uma instrução composta em um procedimento armazenado.
Para obter mais informações sobre o Teradata BEGIN END Compound, veja aqui.
label_name: BEGIN
statement
[ statement ]... ]
END label_name;
Amostra de padrão de origem ¶
Teradata ¶
REPLACE PROCEDURE BeginEndProcedure()
BEGIN
DECLARE HELLOSTRING VARCHAR(60);
label_name: BEGIN
SET HELLOSTRING = 'HELLO WORLD';
END label_name;
END;
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE BeginEndProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
HELLOSTRING VARCHAR(60);
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'label_name LABEL' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
label_name:
BEGIN
HELLOSTRING := 'HELLO WORLD';
END;
END;
$$;
Problemas conhecidos¶
1. Labels not supported in outer BEGIN END blocks¶
Teradata ¶
REPLACE PROCEDURE procedureLabelSingle()
label_name: BEGIN
DECLARE HELLOSTRING VARCHAR(60);
SET HELLOSTRING = 'HELLO WORLD';
END label_name;
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE procedureLabelSingle ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
!!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'label_name LABEL' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
label_name:
DECLARE
HELLOSTRING VARCHAR(60);
BEGIN
HELLOSTRING := 'HELLO WORLD';
END;
$$;
EWIs relacionados¶
SSC-EWI-0058: No momento, a funcionalidade não é compatível com o Snowflake Scripting.
CASE¶
Descrição ¶
Oferece execução condicional de instruções com base na avaliação da expressão condicional especificada ou na igualdade de dois operandos.
A instrução CASE é diferente da expressão SQL CASE _,__ que retorna o resultado de uma expressão.
Para obter mais informações sobre o Teradata CASE, veja aqui.
-- Simple CASE
CASE operant_1
[ WHEN operant_2 THEN
statement
[ statement ]... ]...
[ ELSE
statement
[ statement ]... ]
END CASE;
-- Searched CASE
CASE
[ WHEN conditional_expression THEN
statement
[ statement ]... ]...
[ ELSE
statement
[ statement ]... ]
END CASE;
Amostra de padrões de origem ¶
Exemplo de tabela auxiliar¶
CREATE TABLE case_table(col varchar(30));
CREATE OR REPLACE TABLE case_table (
col varchar(30))
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;
Caso simples¶
Teradata¶
CREATE PROCEDURE caseExample1 ( grade NUMBER )
BEGIN
CASE grade
WHEN 10 THEN INSERT INTO CASE_TABLE(COL) VALUES ('Excellent');
WHEN 9 THEN INSERT INTO CASE_TABLE(COL) VALUES ('Very Good');
WHEN 8 THEN INSERT INTO CASE_TABLE(COL) VALUES ('Good');
WHEN 7 THEN INSERT INTO CASE_TABLE(COL) VALUES ('Fair');
WHEN 6 THEN INSERT INTO CASE_TABLE(COL) VALUES ('Poor');
ELSE INSERT INTO CASE_TABLE(COL) VALUES ('No such grade');
END CASE;
END;
CALL caseExample1(6);
CALL caseExample1(4);
CALL caseExample1(10);
SELECT * FROM CASE_TABLE;
|COL |
|-------------|
|Poor |
|No such grade|
|Excellent |
Script Snowflake¶
CREATE OR REPLACE PROCEDURE caseExample1 (GRADE NUMBER(38, 18))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
CASE (grade)
WHEN 10 THEN
INSERT INTO CASE_TABLE (COL)
VALUES ('Excellent');
WHEN 9 THEN
INSERT INTO CASE_TABLE (COL)
VALUES ('Very Good');
WHEN 8 THEN
INSERT INTO CASE_TABLE (COL)
VALUES ('Good');
WHEN 7 THEN
INSERT INTO CASE_TABLE (COL)
VALUES ('Fair');
WHEN 6 THEN
INSERT INTO CASE_TABLE (COL)
VALUES ('Poor');
ELSE
INSERT INTO CASE_TABLE (COL)
VALUES ('No such grade');
END CASE;
END;
$$;
CALL caseExample1(6);
CALL caseExample1(4);
CALL caseExample1(10);
SELECT * FROM CASE_TABLE;
|COL |
|-------------|
|Poor |
|No such grade|
|Excellent |
Caso pesquisado¶
Teradata¶
CREATE PROCEDURE caseExample2 ( grade NUMBER )
BEGIN
CASE
WHEN grade = 10 THEN INSERT INTO CASE_TABLE(COL) VALUES ('Excellent');
WHEN grade = 9 THEN INSERT INTO CASE_TABLE(COL) VALUES ('Very Good');
WHEN grade = 8 THEN INSERT INTO CASE_TABLE(COL) VALUES ('Good');
WHEN grade = 7 THEN INSERT INTO CASE_TABLE(COL) VALUES ('Fair');
WHEN grade = 6 THEN INSERT INTO CASE_TABLE(COL) VALUES ('Poor');
ELSE INSERT INTO CASE_TABLE(COL) VALUES ('No such grade');
END CASE;
END;
CALL caseExample2(6);
CALL caseExample2(4);
CALL caseExample2(10);
SELECT * FROM CASE_TABLE;
|COL |
|-------------|
|Poor |
|No such grade|
|Excellent |
Script Snowflake¶
CREATE OR REPLACE PROCEDURE caseExample2 (GRADE NUMBER(38, 18))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
CASE
WHEN grade = 10 THEN
INSERT INTO CASE_TABLE (COL)
VALUES ('Excellent');
WHEN grade = 9 THEN
INSERT INTO CASE_TABLE (COL)
VALUES ('Very Good');
WHEN grade = 8 THEN
INSERT INTO CASE_TABLE (COL)
VALUES ('Good');
WHEN grade = 7 THEN
INSERT INTO CASE_TABLE (COL)
VALUES ('Fair');
WHEN grade = 6 THEN
INSERT INTO CASE_TABLE (COL)
VALUES ('Poor');
ELSE
INSERT INTO CASE_TABLE (COL)
VALUES ('No such grade');
END CASE;
END;
$$;
CALL caseExample2(6);
CALL caseExample2(4);
CALL caseExample2(10);
SELECT * FROM CASE_TABLE;
|COL |
|-------------|
|Poor |
|No such grade|
|Excellent |
Problemas conhecidos¶
Não foram encontrados problemas.
EWIs relacionados¶
Sem EWIs relacionados.
CREATE MACRO¶
Descrição ¶
O Teradata CREATE MACRO
define uma ou mais instruções que são comumente usadas ou que executam uma operação complexa, evitando assim escrever a mesma sequência de instruções várias vezes. A macro é executada quando é chamada pela instrução EXECUTE.
Para obter mais informações sobre CREATE MACRO
, clique aqui.
CREATE MACRO <macroname> [(parameter1, parameter2,...)] (
<sql_statements>
);
[ EXECUTE | EXEC ] <macroname>;
Amostra de padrões de origem ¶
Dados de configuração¶
O código a seguir é necessário para executar os padrões de amostra apresentados nesta seção.
CREATE TABLE DEPOSIT
(
ACCOUNTNO NUMBER,
ACCOUNTNAME VARCHAR(100)
);
INSERT INTO DEPOSIT VALUES (1, 'Account 1');
INSERT INTO DEPOSIT VALUES (2, 'Account 2');
INSERT INTO DEPOSIT VALUES (3, 'Account 3');
INSERT INTO DEPOSIT VALUES (4, 'Account 4');
CREATE OR REPLACE TABLE DEPOSIT
(
ACCOUNTNO NUMBER(38, 18),
ACCOUNTNAME VARCHAR(100)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;
INSERT INTO DEPOSIT
VALUES (1, 'Account 1');
INSERT INTO DEPOSIT
VALUES (2, 'Account 2');
INSERT INTO DEPOSIT
VALUES (3, 'Account 3');
INSERT INTO DEPOSIT
VALUES (4, 'Account 4');
Macro básica ¶
Como não há nenhum objeto de macro no Snowflake, a ferramenta de conversão transforma as macros do Teradata em procedimentos armazenados do Snowflake Scripting. Além disso, para replicar a funcionalidade do conjunto de resultados retornado, no Snowflake Scripting, a consulta que deve retornar um conjunto de dados de uma macro é atribuída a uma variável RESULTSET
que será então retornada.
Teradata ¶
REPLACE MACRO DEPOSITID (ID INT)
AS
(
SELECT * FROM DEPOSIT WHERE ACCOUNTNO=:ID;
);
EXECUTE DEPOSITID(2);
+--------------+--------------+
| ACCOUNTNO | ACCOUNTNAME |
|--------------+--------------|
| 2 | Account 2 |
+--------------+--------------+
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE DEPOSITID (ID FLOAT)
RETURNS TABLE ()
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
LET res RESULTSET := (SELECT * FROM DEPOSIT WHERE ACCOUNTNO=:ID);
RETURN TABLE(res);
END;
$$;
CALL DEPOSITID(2);
+--------------+--------------+
| ACCOUNTNO | ACCOUNTNAME |
|--------------+--------------|
| 2 | Account 2 |
+--------------+--------------+
Macro chama outra macro ¶
O SnowConvert suporta o cenário em que uma macro chama outra macro e, por transitividade, um conjunto de resultados é retornado obtendo-se os resultados de RESULT_SCAN(LAST_QUERY_ID())
do Snowflake.
Teradata¶
REPLACE MACRO MacroCallOtherMacro (ID INT)
AS
(
EXECUTE DEPOSITID(:ID);
);
EXECUTE MacroCallOtherMacro(2);
+--------------+--------------+
| ACCOUNTNO | ACCOUNTNAME |
|--------------+--------------|
| 2 | Account 2 |
+--------------+--------------+
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE MacroCallOtherMacro (ID FLOAT)
RETURNS TABLE (
)
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "09/09/2024" }}'
EXECUTE AS CALLER
AS
$$
BEGIN
CALL DEPOSITID(:ID);
LET res RESULTSET :=
(
SELECT
*
FROM
TABLE(RESULT_SCAN(LAST_QUERY_ID()))
);
RETURN TABLE(res);
END;
$$;
CALL MacroCallOtherMacro(2);
+--------------+--------------+
| ACCOUNTNO | ACCOUNTNAME |
|--------------+--------------|
| 2 | Account 2 |
+--------------+--------------+
Macro sem conjunto de resultados¶
Nem todas as macros têm a intenção de retornar um conjunto de resultados. O cenário mencionado também é suportado.
Teradata¶
REPLACE MACRO MacroWithoutSelect (ACCOUNTNO NUMBER, ACCOUNTNAME VARCHAR(100))
AS
(
INSERT INTO DEPOSIT VALUES (:ACCOUNTNO, :ACCOUNTNAME);
);
EXECUTE MacroWithoutSelect(5, 'Account 5');
SELECT * FROM DEPOSIT;
+--------------+--------------+
| ACCOUNTNO | ACCOUNTNAME |
|--------------+--------------|
| 1 | Account 1 |
+--------------+--------------+
| 2 | Account 2 |
+--------------+--------------+
| 3 | Account 3 |
+--------------+--------------+
| 4 | Account 4 |
+--------------+--------------+
| 5 | Account 5 |
+--------------+--------------+
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE MacroWithoutSelect (ACCOUNTNO FLOAT, ACCOUNTNAME VARCHAR(100))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
INSERT INTO DEPOSIT
VALUES (:ACCOUNTNO, :ACCOUNTNAME);
END;
$$;
CALL MacroWithoutSelect(5, 'Account 5');
SELECT * FROM DEPOSIT;
+--------------+--------------+
| ACCOUNTNO | ACCOUNTNAME |
|--------------+--------------|
| 1 | Account 1 |
+--------------+--------------+
| 2 | Account 2 |
+--------------+--------------+
| 3 | Account 3 |
+--------------+--------------+
| 4 | Account 4 |
+--------------+--------------+
| 5 | Account 5 |
+--------------+--------------+
A macro retorna vários conjuntos de resultados¶
No Teradata, as macros podem retornar mais de um conjunto de resultados de uma única macro.
Os procedimentos do Snowflake Scripting permitem que apenas um conjunto de resultados seja retornado por procedimento. Para replicar o comportamento do Teradata, quando há dois ou mais conjuntos de resultados a serem retornados, eles são armazenados em tabelas temporárias. O procedimento Snowflake Scripting retornará uma matriz contendo o nome das tabelas temporárias.
Teradata¶
REPLACE MACRO DEPOSITID (ID INT)
AS
(
SELECT * FROM DEPOSIT WHERE ACCOUNTNO=4;
SELECT * FROM DEPOSIT WHERE ACCOUNTNO=:ID;
EXECUTE DEPOSITID(:ID);
);
EXECUTE DEPOSITID(2);
+--------------+--------------+
| ACCOUNTNO | ACCOUNTNAME |
|--------------+--------------|
| 4 | Account 4 |
+--------------+--------------+
+--------------+--------------+
| ACCOUNTNO | ACCOUNTNAME |
|--------------+--------------|
| 2 | Account 2 |
+--------------+--------------+
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE DEPOSITID (ID FLOAT)
RETURNS ARRAY
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "09/09/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
return_arr ARRAY := array_construct();
tbl_nm VARCHAR;
BEGIN
tbl_nm := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:tbl_nm) AS
SELECT
* FROM
DEPOSIT
WHERE ACCOUNTNO=4;
return_arr := array_append(return_arr, :tbl_nm);
tbl_nm := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:tbl_nm) AS
SELECT
* FROM
DEPOSIT
WHERE ACCOUNTNO=:ID;
return_arr := array_append(return_arr, :tbl_nm);
CALL DEPOSITID(:ID);
tbl_nm := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:tbl_nm) AS
SELECT
*
FROM
TABLE(RESULT_SCAN(LAST_QUERY_ID()));
return_arr := array_append(return_arr, :tbl_nm);
--** SSC-FDM-0020 - MULTIPLE RESULT SETS ARE RETURNED IN TEMPORARY TABLES **
RETURN return_arr;
END;
$$;
CALL DEPOSITID(2);
+-----------------------------------------------------+
| DEPOSIDID |
|-----------------------------------------------------|
| [ |
| "RESULTSET_93D50CBB_F22C_418A_A88C_4E1DE101B500", |
| "RESULTSET_6BDE39D7_0554_406E_B52F_D9E863A3F15C" |
| ] |
+-----------------------------------------------------+
Visualize conjuntos de resultados¶
Ao executar o procedimento acima no Snowflake, será retornado uma matriz com nomes de tabelas temporárias:
[ «RESULTSET_93D50CBB_F22C_418A_A88C_4E1DE101B500», «RESULTSET_6BDE39D7_0554_406E_B52F_D9E863A3F15C»]
É necessário executar as seguintes consultas para exibir os conjuntos de resultados como no Teradata.
SELECT * FROM table('RESULTSET_93D50CBB_F22C_418A_A88C_4E1DE101B500');
SELECT * FROM table('RESULTSET_6BDE39D7_0554_406E_B52F_D9E863A3F15C');
+--------------+--------------+
| ACCOUNTNO | ACCOUNTNAME |
|--------------+--------------|
| 4 | Account 4 |
+--------------+--------------+
+--------------+--------------+
| ACCOUNTNO | ACCOUNTNAME |
|--------------+--------------|
| 2 | Account 2 |
+--------------+--------------+
Problemas conhecidos ¶
Não foram encontrados problemas.
EWIs relacionados¶
SSC-FDM-0020: Vários conjuntos de resultados são retornados em tabelas temporárias.
CREATE PROCEDURE¶
Descrição
A instrução do Teradata CREATE PROCEDURE
e REPLACE PROCEDURE
gera ou substitui uma implementação de procedimento armazenado e a compila.
Para obter mais informações sobre CREATE PROCEDURE
ou REPLACE PROCEDURE
, clique aqui.
-- Create/replace procedure syntax
{CREATE | REPLACE} PROCEDURE [database_name. | user_name.] procedure_name
([<parameter_definition>[, ...n]])
[<SQL_data_access>]
[DYNAMIC RESULT SETS number_of_sets]
[SQL SECURITY <privilege_option>]
statement;
<parameter_definition> := [IN | OUT | INOUT] parameter_name data_type
<SQL_data_access> := {CONTAINS SQL | MODIFIES SQL DATA | READS SQL DATA}
<privilege_option> := {CREATOR | DEFINER | INVOKER | OWNER}
Amostra de padrões de origem ¶
Dados de configuração¶
O código a seguir é necessário para executar os padrões de amostra apresentados nesta seção.
CREATE TABLE inventory (
product_name VARCHAR(50),
price INTEGER
);
INSERT INTO inventory VALUES ('Bread', 50);
INSERT INTO inventory VALUES ('Tuna', 150);
INSERT INTO inventory VALUES ('Gum', 20);
INSERT INTO inventory VALUES ('Milk', 80);
CREATE OR REPLACE TABLE inventory (
product_name VARCHAR(50),
price INTEGER
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;
INSERT INTO inventory
VALUES ('Bread', 50);
INSERT INTO inventory
VALUES ('Tuna', 150);
INSERT INTO inventory
VALUES ('Gum', 20);
INSERT INTO inventory
VALUES ('Milk', 80);
Procedimento básico ¶
Teradata ¶
REPLACE PROCEDURE BasicProcedure(IN counterValue INTEGER)
BEGIN
DECLARE productName VARCHAR(50);
DECLARE productPrice INTEGER DEFAULT 0;
DECLARE whileCounter INTEGER DEFAULT 0;
SET productName = 'Salt';
WHILE (whileCounter < counterValue) DO
SET productPrice = 10 + productPrice;
SET whileCounter = whileCounter + 1;
END WHILE;
INSERT INTO inventory VALUES (productName, productPrice);
END;
CALL BasicProcedure(5);
SELECT product_name, price FROM inventory WHERE product_name = 'Salt';
+--------------+--------------+
| product_name | price |
|--------------+--------------|
| Salt | 50 |
+--------------+--------------+
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE BasicProcedure (COUNTERVALUE INTEGER)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/23/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
productName VARCHAR(50);
productPrice INTEGER DEFAULT 0;
whileCounter INTEGER DEFAULT 0;
BEGIN
productName := 'Salt';
WHILE (whileCounter < counterValue) LOOP
productPrice := 10 + productPrice;
whileCounter := whileCounter + 1;
END LOOP;
INSERT INTO inventory
VALUES (:productName, :productPrice);
END;
$$;
CALL BasicProcedure(5);
SELECT
product_name,
price FROM
inventory
WHERE product_name = 'Salt';
+--------------+--------------+
| product_name | price |
|--------------+--------------|
| Salt | 50 |
+--------------+--------------+
Parâmetro isolado ¶
Teradata¶
REPLACE PROCEDURE procedureLabelSingle(OUT Message VARCHAR(100))
BEGIN
set Message = 'Assignment value. Thanks';
END;
CALL procedureLabelSingle(?);
Message |
------------------------+
Assignment value. Thanks|
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE procedureLabelSingle (
-- OUT
MESSAGE VARCHAR(100))
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/23/2024" }}'
EXECUTE AS CALLER
AS
$$
BEGIN
Message := 'Assignment value. Thanks';
RETURN Message;
END;
$$;
CALL procedureLabelSingle(?);
+───────────────────────────────+
| PROCEDURELABELSINGLE |
+───────────────────────────────+
| ""Assignment value. Thanks"" |
+───────────────────────────────+
Parâmetro de saída múltipla ¶
Teradata¶
REPLACE PROCEDURE procedureLabelMultiple(OUT Message VARCHAR(100), OUT Message2 VARCHAR(100))
BEGIN
set Message = 'Assignment value. Thanks';
set Message2 = 'Assignment value2. Thanks';
END;
CALL procedureLabelSingle(?, ?);
1 |2 |
------------------------+-------------------------+
Assignment value. Thanks|Assignment value2. Thanks|
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE procedureLabelMultiple (
-- OUT
MESSAGE VARCHAR(100),
-- OUT
MESSAGE2 VARCHAR(100))
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/23/2024" }}'
EXECUTE AS CALLER
AS
$$
BEGIN
Message := 'Assignment value. Thanks';
Message2 := 'Assignment value2. Thanks';
RETURN OBJECT_CONSTRUCT('Message', :Message, 'Message2', :Message2);
END;
$$;
CALL procedureLabelSingle(?, ?);
+─────────────────────────+────────────────────────────────+
| PROCEDURELABELMULTIPLE | |
+─────────────────────────+────────────────────────────────+
| "{ | |
| ""Message"" | ""Assignment value. Thanks"", |
| ""Message2"" | ""Assignment value2. Thanks"" |
| }" | |
+─────────────────────────+────────────────────────────────+
Nota
Dentro de um procedimento, o objeto retornado pode ser facilmente desconstruído usando as seguintes instruções logo após a execução da chamada do procedimento:\ \ LET call_results VARIANT: = (SELECT * FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())));
var1 := GET(:call_results, 'Message');
var2 := GET(:call_results, 'Message2');
\
Parâmetro de saída múltipla com conjuntos de resultados dinâmicos ¶
Teradata¶
REPLACE PROCEDURE Procedure1(out product_name VARCHAR(50), out price integer)
DYNAMIC RESULT SETS 2
BEGIN
DECLARE result_set CURSOR WITH RETURN ONLY FOR
SELECT * FROM inventory;
DECLARE result_set2 CURSOR WITH RETURN ONLY FOR
SELECT * FROM inventory;
SET price = 100;
SET product_name = 'another2';
OPEN result_set2;
OPEN result_set;
END;
REPLACE PROCEDURE Procedure2()
BEGIN
DECLARE price INTEGER;
DECLARE productName varchar(10);
CALL Procedure1(productName, price);
INSERT INTO inventory VALUES(:productName, :price);
END;
CALL Procedure2();
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE Procedure1 (out !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'OUTPUT PARAMETERS ALONG WITH DYNAMIC RESULT SET' NODE ***/!!! PRODUCT_NAME VARCHAR(50), out !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'OUTPUT PARAMETERS ALONG WITH DYNAMIC RESULT SET' NODE ***/!!! PRICE integer)
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/23/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
tbl_result_set VARCHAR;
tbl_result_set2 VARCHAR;
return_arr ARRAY := array_construct();
BEGIN
tbl_result_set := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:tbl_result_set) AS
SELECT
* FROM
inventory;
LET result_set CURSOR
FOR
SELECT
*
FROM
IDENTIFIER(?);
tbl_result_set2 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:tbl_result_set2) AS
SELECT
* FROM
inventory;
LET result_set2 CURSOR
FOR
SELECT
*
FROM
IDENTIFIER(?);
price := 100;
product_name := 'another2';
OPEN result_set2 USING (tbl_result_set2);
return_arr := array_append(return_arr, :tbl_result_set2);
OPEN result_set USING (tbl_result_set);
return_arr := array_append(return_arr, :tbl_result_set);
--** SSC-FDM-0020 - MULTIPLE RESULT SETS ARE RETURNED IN TEMPORARY TABLES **
RETURN OBJECT_CONSTRUCT('SC_RET_VALUE', :return_arr, 'product_name', :product_name, 'price', :price);
END;
$$;
CREATE OR REPLACE PROCEDURE Procedure2 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/23/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
price INTEGER;
productName varchar(10);
call_results VARIANT;
BEGIN
call_results := (
CALL Procedure1(:productName, :price)
);
productName := :call_results:product_name;
price := :call_results:price;
INSERT INTO inventory
VALUES (:productName, :price);
END;
$$;
CALL Procedure2();
(1).png)
Problemas conhecidos ¶
1. Parâmetros de saída
O Snowflake Scripting não oferece suporte aos parâmetros OUT/INOUT, portanto, esses parâmetros são retornados no final do corpo do procedimento.
2. Acesso aos dados SQL
Por padrão, os procedimentos do Snowflake suportam a execução de qualquer tipo de instrução SQL, incluindo instruções de leitura ou modificação de dados, tornando a cláusula de acesso a dados SQL irrelevante. Essa cláusula será ignorada ao converter o procedimento.
3. Objetos de nível superior no relatório de avaliação
Os elementos (tabelas temporais ou visualizações) dentro de procedimentos armazenados estão sendo contados no relatório de avaliação como objetos de nível superior. A equipe do SnowConvert está trabalhando agora em uma correção para esse cenário.
EWIs relacionados¶
SSC-EWI-0073: Revisão de equivalência funcional pendente.
SSC-FDM-0020: Vários conjuntos de resultados são retornados em tabelas temporárias.
CURSOR¶
Descrição ¶
Um cursor é uma estrutura de dados usada por procedimentos armazenados em tempo de execução para apontar para um conjunto de resultados retornado por uma consulta SQL. Para obter mais informações, veja aqui.
DECLARE cursor_name [ SCROLL | NO SCROLL ] CURSOR
[
WITHOUT RETURN
|
WITH RETURN [ ONLY ] [ TO [ CALLER | CLIENT ] ]
]
FOR
cursor_specification [ FOR [ READ ONLY | UPDATE ] ]
|
statement_name
;
FETCH [ [ NEXT | FIRST ] FROM ] cursor_name INTO
[ variable_name | parameter_name ] [ ,...n ]
;
OPEN cursor_name
[ USING [ SQL_identifier | SQL_paramenter ] [ ,...n ] ]
;
CLOSE cursor_name ;
Amostra de padrões de origem ¶
Dados de configuração¶
O código a seguir é necessário para executar os padrões de amostra apresentados nesta seção.
CREATE TABLE vEmployee(
PersonID INT,
LastName VARCHAR(255),
FirstName VARCHAR(255)
);
CREATE TABLE ResTable(
Column1 VARCHAR(255)
);
INSERT INTO vEmployee(PersonID, LastName, FirstName) VALUES (1, 'Smith', 'Christian');
INSERT INTO vEmployee(PersonID, LastName, FirstName) VALUES (2, 'Johnson', 'Jhon');
INSERT INTO vEmployee(PersonID, LastName, FirstName) VALUES (3, 'Brown', 'William');
INSERT INTO vEmployee(PersonID, LastName, FirstName) VALUES (4, 'Williams', 'Gracey');
INSERT INTO vEmployee(PersonID, LastName, FirstName) VALUES (5, 'Garcia', 'Julia');
INSERT INTO vEmployee(PersonID, LastName, FirstName) VALUES (6, 'Miller', 'Peter');
INSERT INTO vEmployee(PersonID, LastName, FirstName) VALUES (7, 'Davis', 'Jannys');
CREATE TABLE TEST_TABLE (
ColumnA NUMBER,
ColumnB VARCHAR(8),
ColumnC VARCHAR(8));
SELECT * FROM TEST_TABLE;
INSERT INTO TEST_TABLE VALUES (1, '1', '1');
INSERT INTO TEST_TABLE VALUES (2, '2', '2');
CREATE OR REPLACE TABLE vEmployee (
PersonID INT,
LastName VARCHAR(255),
FirstName VARCHAR(255)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
;
CREATE OR REPLACE TABLE ResTable (
Column1 VARCHAR(255)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
;
INSERT INTO vEmployee (PersonID, LastName, FirstName)
VALUES (1, 'Smith', 'Christian');
INSERT INTO vEmployee (PersonID, LastName, FirstName)
VALUES (2, 'Johnson', 'Jhon');
INSERT INTO vEmployee (PersonID, LastName, FirstName)
VALUES (3, 'Brown', 'William');
INSERT INTO vEmployee (PersonID, LastName, FirstName)
VALUES (4, 'Williams', 'Gracey');
INSERT INTO vEmployee (PersonID, LastName, FirstName)
VALUES (5, 'Garcia', 'Julia');
INSERT INTO vEmployee (PersonID, LastName, FirstName)
VALUES (6, 'Miller', 'Peter');
INSERT INTO vEmployee (PersonID, LastName, FirstName)
VALUES (7, 'Davis', 'Jannys');
CREATE OR REPLACE TABLE TEST_TABLE (
ColumnA NUMBER(38, 18),
ColumnB VARCHAR(8),
ColumnC VARCHAR(8))
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
;
SELECT
* FROM
TEST_TABLE;
INSERT INTO TEST_TABLE
VALUES (1, '1', '1');
INSERT INTO TEST_TABLE
VALUES (2, '2', '2');
Cursor básico¶
Teradata¶
REPLACE PROCEDURE CursorsTest()
BEGIN
DECLARE val1 VARCHAR(255);
DECLARE empcursor CURSOR FOR
SELECT LastName
FROM vEmployee
ORDER BY PersonID;
OPEN empcursor;
FETCH NEXT FROM empcursor INTO val1;
FETCH NEXT FROM empcursor INTO val1;
INSERT INTO ResTable(Column1) VALUES (val1);
CLOSE empcursor;
END;
CALL CursorsTest();
SELECT * FROM ResTable;
Johnson
Script Snowflake¶
CREATE OR REPLACE PROCEDURE CursorsTest ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "06/18/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
val1 VARCHAR(255);
BEGIN
LET empcursor CURSOR
FOR
SELECT
LastName
FROM
vEmployee
ORDER BY PersonID;
OPEN empcursor;
FETCH NEXT FROM empcursor INTO val1;
FETCH NEXT FROM empcursor INTO val1;
INSERT INTO ResTable (Column1)
VALUES (:val1);
CLOSE empcursor;
END;
$$;
CALL CursorsTest();
SELECT
* FROM
ResTable;
Johnson
Cursor único retornável¶
O procedimento a seguir deve retornar um conjunto de resultados, pois tem a propriedade DYNAMIC RESULT SETS 1
no cabeçalho, o cursor tem a propriedade WITH RETURN
e está sendo aberto no corpo.
Teradata¶
REPLACE PROCEDURE spSimple ()
DYNAMIC RESULT SETS 1
BEGIN
DECLARE result_set CURSOR WITH RETURN ONLY FOR
SELECT *
FROM vEmployee;
OPEN result_set;
END;
CALL spSimple();
PersonID|LastName|FirstName|
--------+--------+---------+
7|Davis |Jannys |
5|Garcia |Julia |
3|Brown |William |
1|Smith |Christian|
6|Miller |Peter |
4|Williams|Gracey |
2|Johnson |Jhon |
Script Snowflake¶
CREATE OR REPLACE PROCEDURE spSimple ()
RETURNS TABLE (
)
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
LET result_set CURSOR FOR
SELECT * FROM vEmployee;
OPEN result_set;
RETURN TABLE(resultset_from_cursor(result_set));
END;
$$;
CALL spSimple();
PERSONID|LASTNAME|FIRSTNAME|
--------+--------+---------+
1|Smith |Christian|
2|Johnson |Jhon |
3|Brown |William |
4|Williams|Gracey |
5|Garcia |Julia |
6|Miller |Peter |
7|Davis |Jannys |
Vários cursores retornáveis¶
O procedimento a seguir destina-se a retornar vários resultados quando a propriedade DYNAMIC RESULT SETS
no cabeçalho for maior que 1, o procedimento tiver vários cursores com a propriedade WITH RETURN
e esses mesmos cursores estiverem sendo abertos no corpo.
Teradata¶
REPLACE PROCEDURE spTwoOrMore()
DYNAMIC RESULT SETS 2
BEGIN
DECLARE result_set CURSOR WITH RETURN ONLY FOR
SELECT * FROM SampleTable2;
DECLARE result_set2 CURSOR WITH RETURN ONLY FOR
SELECT Column11 FROM SampleTable1;
OPEN result_set2;
OPEN result_set;
END;
CALL spTwoOrMore();
ColumnA|ColumnB|ColumnC|
-------+-------+-------+
2|2 |2 |
1|1 |1 |
PersonID|LastName|FirstName|
--------+--------+---------+
7|Davis |Jannys |
5|Garcia |Julia |
3|Brown |William |
1|Smith |Christian|
6|Miller |Peter |
4|Williams|Gracey |
2|Johnson |Jhon |
Script Snowflake¶
CREATE OR REPLACE PROCEDURE spTwoOrMore ()
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
tbl_result_set VARCHAR;
tbl_result_set2 VARCHAR;
return_arr ARRAY := array_construct();
BEGIN
tbl_result_set := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:tbl_result_set) AS
SELECT
* FROM
SampleTable2;
LET result_set CURSOR
FOR
SELECT
*
FROM
IDENTIFIER(?);
tbl_result_set2 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:tbl_result_set2) AS
SELECT
Column11 FROM
SampleTable1;
LET result_set2 CURSOR
FOR
SELECT
*
FROM
IDENTIFIER(?);
OPEN result_set2 USING (tbl_result_set2);
return_arr := array_append(return_arr, :tbl_result_set2);
OPEN result_set USING (tbl_result_set);
return_arr := array_append(return_arr, :tbl_result_set);
--** SSC-FDM-0020 - MULTIPLE RESULT SETS ARE RETURNED IN TEMPORARY TABLES **
RETURN OBJECT_CONSTRUCT('SC_RET_VALUE', :return_arr);
END;
$$;
CALL spTwoOrMore();
[
"RESULTSET_B5B0005D_1602_48B7_9EE4_62E1A28B000C",
"RESULTSET_1371794D_7B77_4DA9_B42E_7981F35CEA9C"
]
ColumnA|ColumnB|ColumnC|
-------+-------+-------+
2|2 |2 |
1|1 |1 |
PersonID|LastName|FirstName|
--------+--------+---------+
7|Davis |Jannys |
5|Garcia |Julia |
3|Brown |William |
1|Smith |Christian|
6|Miller |Peter |
4|Williams|Gracey |
2|Johnson |Jhon |
Cursores com variáveis de vinculação¶
O cursor a seguir usa variáveis de vinculação como condição para executar a consulta.
Teradata¶
REPLACE PROCEDURE TestProcedure (IN param1 NUMBER, param2 VARCHAR(8), param3 VARCHAR(8))
DYNAMIC RESULT SETS 1
BEGIN
DECLARE cursorExample CURSOR WITH RETURN ONLY FOR
SELECT * FROM TEST_TABLE
WHERE ColumnA = param1 AND ColumnB LIKE param2 and ColumnC LIKE param3;
OPEN cursorExample;
END;
CALL TestProcedure(2, '2', '2');
|ColumnA|ColumnB|ColumnC|
+-------+-------+-------+
| 2|2 |2 |
Script Snowflake¶
CREATE OR REPLACE PROCEDURE TestProcedure (PARAM1 NUMBER(38, 18), PARAM2 VARCHAR(8), PARAM3 VARCHAR(8))
RETURNS TABLE (
)
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/24/2024" }}'
EXECUTE AS CALLER
AS
$$
BEGIN
LET cursorExample CURSOR
FOR
SELECT
* FROM
TEST_TABLE
WHERE ColumnA = param1 AND ColumnB LIKE param2 and ColumnC LIKE param3;
OPEN cursorExample;
RETURN TABLE(resultset_from_cursor(cursorExample));
END;
$$;
CALL TestProcedure(2, '2', '2');
|ColumnA|ColumnB|ColumnC|
+-------+-------+-------+
| 2|2 |2 |
Loop Cursor For¶
É um tipo de loop que usa um cursor para buscar linhas de uma instrução SELECT e, em seguida, executa algum processamento em cada linha.
Teradata¶
REPLACE PROCEDURE TestProcedure ()
DYNAMIC RESULT SETS 1
BEGIN
FOR fUsgClass AS cUsgClass CURSOR FOR
SELECT columnA FROM TEST_TABLE
DO
INSERT INTO ResTable(Column1) VALUES (fUsgClass.columnA);
END FOR;
END;
CALL TestProcedure();
SELECT * FROM ResTable;
|Column1|
+-------+
| 1|
| 2|
Script Snowflake¶
CREATE OR REPLACE PROCEDURE TestProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
LET cUsgClass CURSOR FOR
SELECT columnA FROM TEST_TABLE;
--** SSC-PRF-0004 - THIS STATEMENT HAS USAGES OF CURSOR FOR LOOP **
FOR fUsgClass IN cUsgClass DO
INSERT INTO ResTable (Column1) VALUES (:temp_fUsgClass_columnA);
END FOR;
END;
$$;
CALL TestProcedure();
SELECT * FROM ResTable;
|Column1|
+-------+
| 1|
| 2|
Cursor Fetch dentro de um loop¶
Ele permite recuperar linhas de um conjunto de resultados, uma de cada vez, e realizar algum processamento em cada linha.
Teradata¶
REPLACE PROCEDURE teradata_fetch_inside_loop()
DYNAMIC RESULT SETS 1
BEGIN
DECLARE col_name VARCHAR(255);
DECLARE col_int INTEGER DEFAULT 1;
DECLARE cursor_var CURSOR FOR SELECT columnA FROM TEST_TABLE;
WHILE (col_int <> 0) DO
FETCH cursor_var INTO col_name;
INSERT INTO ResTable(Column1) VALUES (cursor_var.columnA);
SET col_int = 0;
END WHILE;
END;
CALL teradata_fetch_inside_loop();
SELECT * FROM ResTable;
|Column1|
+-------+
| 2|
Script Snowflake¶
CREATE OR REPLACE PROCEDURE teradata_fetch_inside_loop ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "06/18/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
col_name VARCHAR(255);
col_int INTEGER DEFAULT 1;
BEGIN
LET cursor_var CURSOR
FOR
SELECT
columnA FROM
TEST_TABLE;
WHILE (col_int <> 0) LOOP
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
FETCH cursor_var INTO col_name;
INSERT INTO ResTable (Column1)
VALUES (cursor_var.columnA);
col_int := 0;
END LOOP;
END;
$$;
CALL teradata_fetch_inside_loop();
SELECT
* FROM
ResTable;
|Column1|
+-------+
| 2|
Problemas conhecidos¶
Os parâmetros a seguir não são aplicáveis ao Snowflake Scripting.
1. Declare¶
[ SCROLL/NO SCROLL ] O Snowflake Scripting suporta apenas FETCH NEXT.
[ READ-ONLY ] Esse é o padrão no Snowflake Scripting.
[ UPDATE ].
2. Fetch¶
[ NEXT ] Esse é o comportamento padrão no Snowflake Scripting.
[ FIRST ].
EWIs relacionados¶
SSC-FDM-0020: Vários conjuntos de resultados são retornados em tabelas temporárias.
SSC-PRF-0003: A busca dentro de um loop é considerada um padrão complexo, o que pode prejudicar o desempenho do Snowflake.
SSC-PRF-0004: Essa instrução tem usos de cursor para loop.
DECLARE CONTINUE HANDLER¶
Descrição ¶
Trate condições de conclusão e condições de exceção que não sejam graves o suficiente para afetar o fluxo de controle.
Para obter mais informações sobre o manipulador do Teradata DECLARE CONTINUE, veja aqui.
DECLARE CONTINUE HANDLER FOR
{
{ sqlstate_state_spec | condition_name } [,...] |
{ SQLEXCEPTION | SQLWARNING | NOT FOUND } [,...]
} handler_action_statement ;
Amostra de padrões de origem ¶
DECLARE CONTINUE HANDLER¶
Teradata ¶
REPLACE PROCEDURE PURGING_ADD_TABLE
(
IN inDatabaseName VARCHAR(30),
IN inTableName VARCHAR(30)
)
BEGIN
DECLARE vCHAR_SQLSTATE CHAR(5);
DECLARE vSUCCESS CHAR(5);
DECLARE CONTINUE HANDLER FOR SQLSTATE 'T5628'
BEGIN
SET vCHAR_SQLSTATE = SQLCODE;
SET vSUCCESS = SQLCODE;
END;
SELECT 1;
END;
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE PURGING_ADD_TABLE
(INDATABASENAME VARCHAR(30), INTABLENAME VARCHAR(30)
)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "06/18/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
vCHAR_SQLSTATE CHAR(5);
vSUCCESS CHAR(5);
BEGIN
BEGIN
SELECT
1;
EXCEPTION
WHEN statement_error THEN
LET errcode := :sqlcode
LET sqlerrmsg := :sqlerrm
IF (errcode = '904'
AND contains(sqlerrmsg, 'invalid value')) THEN
BEGIN
vCHAR_SQLSTATE := SQLCODE;
vSUCCESS := SQLCODE;
END;
ELSE
RAISE
END IF
END
END;
$$;
Problemas conhecidos¶
DECLARE CONTINUE HANDLER FOR SQLSTATE¶
O suporte à instrução de manipuladores contínuos para alguns valores de SQLSTATE não é suportado atualmente pelo Snowflake Scripting.
Teradata ¶
CREATE PROCEDURE declareConditionExample2 ( )
BEGIN
DECLARE CONTINUE HANDLER FOR SQLSTATE 'UNSUPPORTED'
BEGIN
SET vCHAR_SQLSTATE = SQLCODE;
SET vSUCCESS = SQLCODE;
END;
END;
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE declareConditionExample2 ( )
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-TD0004 - NOT SUPPORTED SQL EXCEPTION ON CONTINUE HANDLER ***/!!!
DECLARE CONTINUE HANDLER FOR SQLSTATE 'UNSUPPORTED'
BEGIN
vCHAR_SQLSTATE := SQLCODE;
vSUCCESS := SQLCODE;
END;
END;
$$;
EWIS relacionados¶
SSC-EWI-TD0004: Exceção SQL não suportada no manipulador de continuação.
DECLARE CONDITION HANDLER¶
Descrição ¶
Atribua um nome a um código SQLSTATE ou declare uma condição definida pelo usuário.
Para obter mais informações sobre o manipulador do Teradata DECLARE CONDITION, veja aqui.
DECLARE condition_name CONDITION
[ FOR SQLSTATE [ VALUE ] sqlstate_code ] ;
Amostra de padrões de origem ¶
DECLARE CONDITION¶
Teradata ¶
CREATE PROCEDURE declareConditionExample ( )
BEGIN
DECLARE DB_ERROR CONDITION;
...
END;
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE declareConditionExample ( )
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
DB_ERROR EXCEPTION;
BEGIN
END;
$$;
Problemas conhecidos¶
DECLARE CONDITION FOR SQLSTATE¶
O suporte à declaração de condições para os valores de SQLSTATE não é suportado atualmente pelo Snowflake Scripting.
Teradata ¶
CREATE PROCEDURE declareConditionExample2 ( )
BEGIN
DECLARE ERROR_EXISTS CONDITION FOR SQLSTATE VALUE '42000';
END;
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE declareConditionExample2 ( )
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
ERROR_EXISTS EXCEPTION;
BEGIN
-- !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'SET EXCEPTION DETAILS' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
-- ERROR_EXISTS CONDITION FOR SQLSTATE VALUE '42000';
END;
$$;
EWIS relacionados¶
SSC-EWI-0058: A funcionalidade não é suportada atualmente pelo Snowflake Scripting.
DECLARE¶
Descrição ¶
Declara uma ou mais variáveis locais.
Para obter mais informações sobre o Teradata DECLARE, veja aqui.
DECLARE variable_name [, variable_name ]... DATA_TYPE [ DEFAULT default_value]
Amostra de padrões de origem ¶
Teradata ¶
CREATE PROCEDURE declareExample ( )
BEGIN
DECLARE COL_NAME, COL_TYPE VARCHAR(200) DEFAULT '' ;
DECLARE COL_COUNT, COL_LEN INTEGER;
END;
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE declareExample ( )
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "06/18/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
COL_NAME VARCHAR(200) DEFAULT '';
COL_TYPE VARCHAR(200) DEFAULT '';
COL_COUNT INTEGER;
COL_LEN INTEGER;
BEGIN
RETURN 1;
END;
$$;
Problemas conhecidos¶
Não foram encontrados problemas.
EWIs relacionados¶
Sem EWIs relacionados.
Objetos DML e DDL¶
Descrição ¶
Objetos DML e DDL são convertidos da mesma forma, independentemente de estarem ou não dentro de procedimentos armazenados. Para obter mais informações, consulte os links a seguir.
Referências de conversão¶
data-types.md: Compare os tipos de dados do Teradata e seus equivalentes no Snowflake.
ddl: Explore a conversão da linguagem de definição de dados.
dml: Explore a conversão da linguagem de manipulação de dados.
built-in-functions: Compare as funções incluídas no tempo de execução de ambas as linguagens.
EXCEPTION HANDLERS¶
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Descrição ¶
Os manipuladores de exceção únicos e múltiplos do Teradata são substituídos por manipuladores equivalentes no Snowflake Scripting.
Para obter mais informações sobre o Teradata EXCEPTION HANDLERS, acesse aqui.
DECLARE < handler_type > HANDLER
FOR < condition_value_list > < handler_action > ;
Amostra de padrões de origem ¶
SQLEXCEPTION HANDLER¶
Teradata ¶
CREATE PROCEDURE handlerSample ()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
INSERT INTO Proc_Error_Table ('procSample', 'Failed SqlException');
SELECT * FROM Proc_Error_Table;
END;
CREATE PROCEDURE handlerSample ()
BEGIN
DECLARE ConditionByUser1 CONDITION;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
INSERT INTO Proc_Error_Table ('procSample', 'Failed SqlException');
DECLARE EXIT HANDLER FOR ConditionByUser1
INSERT INTO Proc_Error_Table ('procSample', 'Failed ConditionByUser1');
SELECT * FROM Proc_Error_Table;
END;
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE handlerSample ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
SELECT
* FROM
Proc_Error_Table;
EXCEPTION
WHEN other THEN
INSERT INTO Proc_Error_Table
VALUES ('procSample', 'Failed SqlException');
END;
$$;
CREATE OR REPLACE PROCEDURE handlerSample ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
ConditionByUser1 EXCEPTION;
BEGIN
SELECT
* FROM
Proc_Error_Table;
EXCEPTION
WHEN ConditionByUser1 THEN
INSERT INTO Proc_Error_Table
VALUES ('procSample', 'Failed ConditionByUser1');
WHEN other THEN
INSERT INTO Proc_Error_Table
VALUES ('procSample', 'Failed SqlException');
END;
$$;
Manipuladores definidos pelo usuário¶
Teradata ¶
CREATE PROCEDURE handlerSample ()
BEGIN
DECLARE EXIT HANDLER FOR Custom1, Custom2, Custom3
BEGIN
SET Message1 = 'custom1 and custom2 and custom3';
END;
SELECT * FROM Proc_Error_Table;
END;
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE handlerSample ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
SELECT
* FROM
Proc_Error_Table;
EXCEPTION
WHEN Custom1 OR Custom2 OR Custom3 THEN
BEGIN
Message1 := 'custom1 and custom2 and custom3';
END;
END;
$$;
Problemas conhecidos¶
Manipulador de CONTINUE¶
Um manipulador “CONTINUE” no Teradata permite que a execução seja retomada após a execução de uma instrução com erros. Isso não é suportado pelos blocos de exceção no Snowflake Scripting. Documentação de referência do manipulador de condição do Teradata
Teradata
CREATE PROCEDURE handlerSample ()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
INSERT INTO Proc_Error_Table ('spSample4', 'Failed SqlException');
SELECT * FROM Proc_Error_Table;
END;
Snowflake Scripting
CREATE OR REPLACE PROCEDURE handlerSample ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-TD0004 - NOT SUPPORTED SQL EXCEPTION ON CONTINUE HANDLER ***/!!!
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
INSERT INTO Proc_Error_Table
VALUES ('spSample4', 'Failed SqlException');
SELECT
* FROM
Proc_Error_Table;
END;
$$;
Outros manipuladores não suportados
Os manipuladores para SQLSTATE, SQLWARNING e NOT FOUND não são compatíveis
Teradata ¶
CREATE PROCEDURE handlerSample ()
BEGIN
DECLARE EXIT HANDLER FOR SQLSTATE '42002', SQLWARNING, NOT FOUND
INSERT INTO Proc_Error_Table ('procSample', 'Failed SqlState or SqlWarning or Not Found');
SELECT * FROM Proc_Error_Table;
END;
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE handlerSample ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/04/2024" }}'
EXECUTE AS CALLER
AS
$$
BEGIN
-- !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'SQLSTATE, SQLWARNING, NOT-FOUND TYPES HANDLER' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
-- DECLARE EXIT HANDLER FOR SQLSTATE '42002', SQLWARNING, NOT FOUND
-- INSERT INTO Proc_Error_Table ('procSample', 'Failed SqlState or SqlWarning or Not Found');
SELECT
* FROM
Proc_Error_Table;
END;
$$;
EWIS relacionados¶
SSC-EWI-0058: No momento, a funcionalidade não é compatível com o Snowflake Scripting.
SSC-EWI-TD0004: Exceção SQL não suportada no manipulador de continuação.
EXECUTE/EXEC¶
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Descrição ¶
A instrução Teradata EXECUTE
permite a execução de SQL dinâmicas preparadas ou macros, enquanto o exec só permite macros.
Para obter mais informações sobre o Teradata EXECUTE/EXEC, consulte Macro Form e Dynamic SQL Form
-- EXECUTE macro syntax
{EXECUTE | EXEC } macro_identifier [ (<parameter_definition>[, ...n] ) ] [;]
<parameter_definition>:= {parameter_name = constant_expression | constant_expresion}
-- EXECUTE prepared dynamic SQL syntax
EXECUTE prepare_indentifier [<using>|<usingDescriptor>]
<using>:= USING < host_variable >[, ...n]
<host_variable>:= [:] host_variable_name [[INDICATOR] :host_indicator_name]
<usingDescriptor>:= USING DESCRIPTOR [:] descript_area
Amostra de padrões de origem ¶
Dados de configuração¶
O código a seguir é necessário para executar os padrões de amostra apresentados nesta seção.
-- Additional Params: -t JavaScript
CREATE TABLE inventory (
product_name VARCHAR(50),
price INTEGER
);
CREATE MACRO dummyMacro AS(
SELECT * FROM INVENTORY;
);
CREATE OR REPLACE TABLE inventory (
product_name VARCHAR(50),
price INTEGER
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;
CREATE OR REPLACE PROCEDURE dummyMacro ()
RETURNS STRING
LANGUAGE JAVASCRIPT
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
// SnowConvert Helpers Code section is omitted.
INSERT_TEMP(`SELECT
*
FROM
INVENTORY`,[]);
return tablelist;
$$;
Executar instrução preparada¶
Teradata¶
CREATE PROCEDURE InsertProductInInventory(IN productName VARCHAR(50), IN price INTEGER)
BEGIN
DECLARE dynamicSql CHAR(200);
SET dynamicSql = 'INSERT INTO INVENTORY VALUES( ?, ?)';
PREPARE preparedSql FROM dynamicSql;
EXECUTE preparedSql USING productName, price;
END;
CALL InsertProductInInventory('''Chocolate''', 75);
CALL InsertProductInInventory('''Sugar''', 65);
CALL InsertProductInInventory('''Rice''', 100);
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE InsertProductInInventory (PRODUCTNAME VARCHAR(50), PRICE INTEGER)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/24/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
dynamicSql CHAR(200);
BEGIN
dynamicSql := 'INSERT INTO INVENTORY
VALUES (?, ?)';
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'PREPARE STATEMENT' NODE ***/!!!
PREPARE preparedSql FROM dynamicSql;
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE dynamicSql;
END;
$$;
CALL InsertProductInInventory('''Chocolate''', 75);
CALL InsertProductInInventory('''Sugar''', 65);
CALL InsertProductInInventory('''Rice''', 100);
Executar instrução de macro¶
Teradata¶
EXECUTE dummyMacro;
+---------------+-------+
| product_name | price |
+---------------+-------+
| 'Chocolate' | 75 |
+---------------+-------+
| 'Sugar' | 65 |
+---------------+-------+
| 'Rice' | 100 |
+---------------+-------+
Snowflake Scripting ¶
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE dummyMacro;
EWIs relacionados¶
SSC-EWI-0030: A instrução abaixo tem usos de SQL dinâmico.
SSC-EWI-0073: Revisão de equivalência funcional pendente.
EXECUTE IMMEDIATE¶
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Descrição ¶
A instrução Teradata EXECUTE IMMEDIATE
permite a execução de SQL dinâmico contido em variáveis ou literais de cadeia de caracteres.
Para obter mais informações sobre EXECUTE IMMEDIATE
, clique aqui.
-- EXECUTE IMMEDIATE syntax
EXECUTE IMMEDIATE <dynamic_statement>
<dynamic_statement> := {string_literal | string_variable}
Amostra de padrões de origem ¶
Dados de configuração¶
O código a seguir é necessário para executar os padrões de amostra apresentados nesta seção.
CREATE TABLE inventory (
product_name VARCHAR(50),
price INTEGER
);
CREATE OR REPLACE TABLE inventory (
product_name VARCHAR(50),
price INTEGER
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;
Exemplo de Execute ¶
Teradata ¶
REPLACE PROCEDURE InsertProductInInventory(IN productName VARCHAR(50), IN price INTEGER)
BEGIN
DECLARE insertStatement VARCHAR(100);
SET insertStatement = 'INSERT INTO INVENTORY VALUES(' || productName || ', ' || price || ')';
EXECUTE IMMEDIATE insertStatement;
END;
CALL InsertProductInInventory('''Chocolate''', 75);
CALL InsertProductInInventory('''Sugar''', 65);
CALL InsertProductInInventory('''Rice''', 100);
SELECT product_name, price FROM inventory;
+--------------+-------+
| product_name | price |
+--------------+-------+
| Chocolate | 75 |
+--------------+-------+
| Sugar | 65 |
+--------------+-------+
| Rice | 100 |
+--------------+-------+
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE InsertProductInInventory (PRODUCTNAME VARCHAR(50), PRICE INTEGER)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/24/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
insertStatement VARCHAR(100);
BEGIN
insertStatement := 'INSERT INTO INVENTORY
VALUES (' || productName || ', ' || price || ')';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE insertStatement;
END;
$$;
CALL InsertProductInInventory('''Chocolate''', 75);
CALL InsertProductInInventory('''Sugar''', 65);
CALL InsertProductInInventory('''Rice''', 100);
SELECT
product_name,
price FROM
inventory;
+--------------+-------+
| PRODUCT_NAME | PRICE |
+--------------+-------+
| Chocolate | 75 |
+--------------+-------+
| Sugar | 65 |
+--------------+-------+
| Rice | 100 |
+--------------+-------+
column1|column2 |column3|
-------+-------------------------+-------+
3|Mundo3 | 3.3|
EWIS relacionados¶
SSC-EWI-0030: A instrução abaixo tem usos de SQL dinâmico.
FUNCTION OPTIONS OR DATA ACCESS¶
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Nota
Instrução não relevante.
Aviso
Observe que essa instrução é removida da migração porque é uma sintaxe não relevante. Isso significa que não é necessária no Snowflake.
Descrição¶
As opções de funções ou opções de acesso a dados são instruções usadas em funções na parte da instrução para especificar determinadas características. Esses podem ser:
CONTAINS SQL
SQL SECURITY DEFINER
COLLATION INVOKER
SPECIFIC FUNCTION_NAME
Amostra de padrões da origem¶
Opções de função¶
Observe que, neste exemplo, as opções de função foram removidas porque não são necessárias no Snowflake.
CREATE FUNCTION sumValues(A INTEGER, B INTEGER)
RETURNS INTEGER
LANGUAGE SQL
CONTAINS SQL
SQL SECURITY DEFINER
SPECIFIC sumTwoValues
COLLATION INVOKER
INLINE TYPE 1
RETURN A + B;
CREATE OR REPLACE FUNCTION sumValues (A INTEGER, B INTEGER)
RETURNS INTEGER
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
AS
$$
A + B
$$;
Problemas conhecidos ¶
Não foram encontrados problemas.
EWIs Relacionados ¶
Sem EWIs relacionados.
GET DIAGNOSTICS EXCEPTION¶
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
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 > ]...
}
Amostra de padrões de origem ¶
Teradata ¶
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,
V_CODE = RETURNED_SQLSTATE;
END;
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE getDiagnosticsSample ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "06/18/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
V_MESSAGE VARCHAR(200);
V_CODE VARCHAR(200);
V_Result INTEGER;
BEGIN
SELECT
c1 INTO
:V_Result
FROM
tab1;
V_MESSAGE := SQLERRM;
V_CODE := SQLSTATE;
END;
$$;
Problemas conhecidos¶
CLASS_ORIGIN, CONDITION_NUMBER¶
O uso de GET DIAGNOSTICS para CLASS_ORIGIN, CONDITION_NUMBER não é compatível
Teradata
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 5
V_CLASS = CLASS_ORIGIN,
V_COND = CONDITION_NUMBER;
END;
Snowflake Scripting
CREATE OR REPLACE PROCEDURE getDiagnosticsSample ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "06/18/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
V_MESSAGE VARCHAR(200);
V_CODE VARCHAR(200);
V_Result INTEGER;
BEGIN
SELECT
c1 INTO
:V_Result
FROM
tab1;
-- V_CLASS = CLASS_ORIGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'GET DIAGNOSTICS DETAIL FOR CLASS_ORIGIN' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
-- V_COND = CONDITION_NUMBER
!!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'GET DIAGNOSTICS DETAIL FOR CONDITION_NUMBER' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!
END;
$$;
Related EWIS
SSC-EWI-0058: No momento, a funcionalidade não é compatível com o Snowflake Scripting.
IF
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Descrição ¶
Oferece execução condicional com base no valor verdadeiro de uma condição.
Para obter mais informações sobre o Teradata IF, veja aqui.
IF conditional_expression THEN
statement
[ statement ]...
[ ELSEIF conditional_expression THEN
statement
[ statement ]... ]...
[ ELSE
statement
[ statement ]... ]
END IF;
Amostra de padrões de origem ¶
Exemplo de tabela auxiliar¶
CREATE TABLE if_table(col1 varchar(30));
CREATE OR REPLACE TABLE if_table (
col1 varchar(30))
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;
Possíveis variações de IF¶
Teradata ¶
CREATE PROCEDURE ifExample1 ( flag NUMBER )
BEGIN
IF flag = 1 THEN
INSERT INTO if_table(col1) VALUES ('one');
END IF;
END;
CALL ifExample1(1);
SELECT * FROM if_table;
CREATE PROCEDURE ifExample2 ( flag NUMBER )
BEGIN
IF flag = 1 THEN
INSERT INTO if_table(col1) VALUES ('one');
ELSE
INSERT INTO if_table(col1) VALUES ('Unexpected input.');
END IF;
END;
CALL ifExample2(2);
SELECT * FROM if_table;
CREATE PROCEDURE ifExample3 ( flag NUMBER )
BEGIN
IF flag = 1 THEN
INSERT INTO if_table(col1) VALUES ('one');
ELSEIF flag = 2 THEN
INSERT INTO if_table(col1) VALUES ('two');
ELSEIF flag = 3 THEN
INSERT INTO if_table(col1) VALUES ('three');
END IF;
END;
CALL ifExample3(3);
SELECT * FROM if_table;
CREATE PROCEDURE ifExample4 ( flag NUMBER )
BEGIN
IF flag = 1 THEN
INSERT INTO if_table(col1) VALUES ('one');
ELSEIF flag = 2 THEN
INSERT INTO if_table(col1) VALUES ('two');
ELSEIF flag = 3 THEN
INSERT INTO if_table(col1) VALUES ('three');
ELSE
INSERT INTO if_table(col1) VALUES ('Unexpected input.');
END IF;
END;
CALL ifExample4(4);
SELECT * FROM if_table;
|COL1|
|----|
|one |
|COL1 |
|-----------------|
|Unexpected input.|
|COL1 |
|-----|
|three|
|COL1 |
|-----------------|
|Unexpected input.|
Script Snowflake¶
CREATE OR REPLACE PROCEDURE ifExample1 (FLAG NUMBER(38, 18))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
IF (flag = 1) THEN
INSERT INTO if_table (col1)
VALUES ('one');
END IF;
END;
$$;
CALL ifExample1(1);
SELECT
* FROM
if_table;
CREATE OR REPLACE PROCEDURE ifExample2 (FLAG NUMBER(38, 18))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
IF (flag = 1) THEN
INSERT INTO if_table (col1)
VALUES ('one');
ELSE
INSERT INTO if_table (col1)
VALUES ('Unexpected input.');
END IF;
END;
$$;
CALL ifExample2(2);
SELECT
* FROM
if_table;
CREATE OR REPLACE PROCEDURE ifExample3 (FLAG NUMBER(38, 18))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
IF (flag = 1) THEN
INSERT INTO if_table (col1)
VALUES ('one');
ELSEIF (flag = 2) THEN
INSERT INTO if_table (col1)
VALUES ('two');
ELSEIF (flag = 3) THEN
INSERT INTO if_table (col1)
VALUES ('three');
END IF;
END;
$$;
CALL ifExample3(3);
SELECT
* FROM
if_table;
CREATE OR REPLACE PROCEDURE ifExample4 (FLAG NUMBER(38, 18))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
IF (flag = 1) THEN
INSERT INTO if_table (col1)
VALUES ('one');
ELSEIF (flag = 2) THEN
INSERT INTO if_table (col1)
VALUES ('two');
ELSEIF (flag = 3) THEN
INSERT INTO if_table (col1)
VALUES ('three');
ELSE
INSERT INTO if_table (col1)
VALUES ('Unexpected input.');
END IF;
END;
$$;
CALL ifExample4(4);
SELECT
* FROM
if_table;
|COL1|
|----|
|one |
|COL1 |
|-----------------|
|Unexpected input.|
|COL1 |
|-----|
|three|
|COL1 |
|-----------------|
|Unexpected input.|
Problemas conhecidos ¶
Não foram encontrados problemas.
EWIs Relacionados ¶
Sem EWIs relacionados.
LOCKING FOR ACCESS¶
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Nota
Instrução não relevante.
Aviso
Observe que essa instrução é removida da migração porque é uma sintaxe não relevante. Isso significa que não é necessária no Snowflake.
Descrição¶
A funcionalidade de bloqueio de uma linha no Teradata está relacionada ao acesso e aos privilégios. Consulte a documentação a seguir para saber mais.
Amostra de padrões da origem¶
Bloqueio de linha¶
Observe que, neste exemplo, LOCKING ROW FOR ACCESS
foi excluído. Isso ocorre porque o Snowflake trata os acessos com funções e privilégios. A instrução não é obrigatória.
REPLACE VIEW SCHEMA2.VIEW1
AS
LOCKING ROW FOR ACCESS
SELECT * FROM SCHEMA1.TABLE1;
--** SSC-FDM-0007 - MISSING DEPENDENT OBJECT "SCHEMA1.TABLE1" **
CREATE OR REPLACE VIEW SCHEMA2.VIEW1
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
AS
--** SSC-FDM-0001 - VIEWS SELECTING ALL COLUMNS FROM A SINGLE TABLE ARE NOT REQUIRED IN SNOWFLAKE AND MAY IMPACT PERFORMANCE. **
SELECT
* FROM
SCHEMA1.TABLE1;
Problemas conhecidos ¶
Não foram encontrados problemas.
EWIs relacionados¶
SSC-FDM-0001: As visualizações que selecionam todas as colunas de uma única tabela não são necessárias no Snowflake.
SSC-FDM-0007: Elemento com dependências ausentes.
LOOP¶
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Descrição ¶
A instrução LOOP
do Teradata é convertida para a sintaxe do Snowflake Scripting LOOP
.
Para obter mais informações sobre o Teradata Loop, veja aqui.
[label_name:] LOOP
{ sql_statement }
END LOOP [label_name];
Amostra de padrões de origem ¶
Teradata ¶
CREATE PROCEDURE loopProcedure(OUT resultCounter INTEGER)
BEGIN
DECLARE counter INTEGER DEFAULT 0;
customeLabel: LOOP
SET counter = counter + 1;
IF counter = 10 THEN
LEAVE customeLabel;
END IF;
END LOOP customeLabel;
SET resultCounter = counter;
END;
CALL loopProcedure(:?);
|resultCounter|
|-------------|
|10 |
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE loopProcedure (
-- OUT
RESULTCOUNTER INTEGER)
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/24/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
counter INTEGER DEFAULT 0;
BEGIN
LOOP
counter := counter + 1;
IF (counter = 10) THEN
BREAK CUSTOMELABEL;
END IF;
END LOOP CUSTOMELABEL;
resultCounter := counter;
RETURN resultCounter;
END;
$$;
CALL loopProcedure(:?);
|LOOPPROCEDURE|
|-------------|
|10 |
Problemas conhecidos ¶
Não foram encontrados problemas.
EWIs Relacionados ¶
Sem EWIs relacionados.
OUTPUT PARAMETERS¶
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Descrição¶
Um parâmetro de saída é um parâmetro cujo valor é passado para fora do procedimento armazenado, de volta para a instrução de chamada. Como os parâmetros de saída não são compatíveis com o Snowflake Scripting, foi implementada uma solução para emular sua funcionalidade.
Amostra de padrões da origem¶
Tabela auxiliar de amostra¶
CREATE TABLE table20 ( col1 NUMBER, col2 NUMBER );
CREATE OR REPLACE TABLE table20 (
col1 NUMBER(38, 18),
col2 NUMBER(38, 18)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;
Na declaração, as palavras-chave OUT
ou IN OUT
são removidas. A atribuição está sendo emitida da mesma forma que a entrada, mas para emular a funcionalidade do parâmetro de saída, algumas instruções estão sendo adicionadas.
Quando um procedimento com parâmetros de saída é chamado em outro, algumas instruções são adicionadas para obter e atribuir o(s) valor(es) ao(s) respectivo(s) argumento(s).
Parâmetro de saída único¶
CREATE PROCEDURE demo.proc_with_single_output_parameters(OUT param1 NUMBER)
BEGIN
SET param1 = 100;
END;
REPLACE PROCEDURE demo.proc_calling_proc_with_single_output_parameters ()
BEGIN
DECLARE mytestvar NUMBER;
CALL demo.proc_with_single_output_parameters(mytestvar);
INSERT INTO demo.TABLE20 VALUES(mytestvar,432);
END;
CREATE OR REPLACE PROCEDURE demo.proc_with_single_output_parameters (
-- OUT
PARAM1 NUMBER(38, 18))
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/24/2024" }}'
EXECUTE AS CALLER
AS
$$
BEGIN
param1 := 100;
RETURN null;
END;
$$;
CREATE OR REPLACE PROCEDURE demo.proc_calling_proc_with_single_output_parameters ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/24/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
mytestvar NUMBER(38, 18);
BEGIN
CALL demo.proc_with_single_output_parameters(:mytestvar);
INSERT INTO demo.TABLE20
VALUES (:mytestvar,432);
END;
$$;
Parâmetro de saída múltipla¶
CREATE PROCEDURE demo.proc_with_multiple_output_parameters(OUT param1 NUMBER, INOUT param2 NUMBER)
BEGIN
SET param1 = param2;
SET param2 = 32;
END;
CREATE PROCEDURE demo.proc_calling_proc_with_multiple_output_parameters ()
BEGIN
DECLARE var1 NUMBER;
DECLARE var2 NUMBER;
SET var2 = 34;
CALL demo.proc_with_multiple_output_parameters(var1, var2);
INSERT INTO demo.TABLE20 VALUES(var1,var2);
END;
CREATE OR REPLACE PROCEDURE demo.proc_with_multiple_output_parameters (
-- OUT
PARAM1 NUMBER(38, 18),
-- INOUT
PARAM2 NUMBER(38, 18))
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/24/2024" }}'
EXECUTE AS CALLER
AS
$$
BEGIN
param1 := param2;
param2 := 32;
RETURN null;
END;
$$;
CREATE OR REPLACE PROCEDURE demo.proc_calling_proc_with_multiple_output_parameters ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/24/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
var1 NUMBER(38, 18);
var2 NUMBER(38, 18);
BEGIN
var2 := 34;
CALL demo.proc_with_multiple_output_parameters(:var1, :var2);
INSERT INTO demo.TABLE20
VALUES (:var1, :var2);
END;
$$;
Parâmetros de OUT para tipos de dados do cliente¶
Quando o parâmetro de saída é um tipo de cliente, o processo é semelhante ao de um tipo de dados normal.
CREATE OR REPLACE PROCEDURE GetEmployeeInfo (
OUT EmpInfo EmployeeType
)
BEGIN
SET EmpInfo.EmployeeID = 1001;
SET EmpInfo.FirstName = 'John';
END;
CREATE OR REPLACE PROCEDURE GetEmployeeInfo (
-- OUT
EMPINFO EmployeeType
)
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
EmpInfo.EmployeeID := 1001;
EmpInfo.FirstName := 'John';
RETURN EmpInfo;
END;
$$;
Problemas conhecidos¶
1. Some data types may not work properly¶
Como visto na transformação, ao recuperar o valor dos procedimentos chamados, é realizada uma conversão implícita de VARIANT para o tipo especificado pela variável. Como há muitos tipos de dados possíveis, algumas conversões podem falhar ou conter dados diferentes.
EWIs Relacionados ¶
Sem EWIs relacionados.
PREPARE¶
Descrição ¶
Prepara a instrução dinâmica DECLARE CURSOR para permitir a criação de diferentes conjuntos de resultados. Permite marcadores de parâmetros dinâmicos.
Para obter mais informações, consulte a documentação a seguir.
Sintaxe do Teradata:
PREPARE statement_name FROM { 'statement_string' | statement_string_variable } ;
Onde:
statement_name é o mesmo identificador que
statement_name
em uma instrução DECLARE CURSOR.statement_string é o texto SQL que deve ser executado dinamicamente.
statement_string_variable é o nome de uma variável local SQL, um parâmetro SQL ou uma variável de cadeia de caracteres que contém a cadeia de texto SQL a ser executada dinamicamente.
Nota
Informações importantes
Para essa transformação, os cursores são renomeados, pois não podem ser atualizados dinamicamente.
Amostra de padrões de origem ¶
Configuração de dados para exemplos¶
Para este exemplo, use as seguintes consultas complementares no caso de você desejar executar cada caso.
CREATE TABLE MyTemporaryTable(
Col1 INTEGER
);
INSERT INTO MyTemporaryTable(col1) VALUES (1);
SELECT * FROM databaseTest.MyTemporaryTable;
CREATE TABLE MyStatusTable (
Col1 VARCHAR(2)
);
SELECT * FROM MyStatusTable;
CREATE TABLE MyTemporaryTable (
Col1 INTEGER
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
;
INSERT INTO MyTemporaryTable (col1) VALUES (1);
SELECT * FROM MyTemporaryTable;
CREATE TABLE MyStatusTable (
Col1 VARCHAR(2)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
;
SELECT * FROM MyStatusTable;
Cenário simples¶
Este exemplo analisa a funcionalidade para os casos em que um único cursor está sendo usado uma única vez.
Teradata ¶
REPLACE PROCEDURE simple_scenario()
BEGIN
--Variables for the example's procedure_results
DECLARE SQL_string_sel VARCHAR(200) DEFAULT 'SELECT * FROM MyTemporaryTable';
DECLARE procedure_result INTEGER DEFAULT 0;
-- Actual Cursor usage
DECLARE C1 CURSOR FOR S1;
PREPARE S1 FROM SQL_string_sel;
OPEN C1;
FETCH C1 INTO procedure_result;
INSERT INTO databaseTest.MyStatusTable(Col1) VALUES (procedure_result);
CLOSE C1;
END;
CALL databaseTest.simple_scenario();
SELECT * FROM MyStatusTable;
Col1 |
---|
1 |
Snowflake Scripting ¶
Nota
Os usos para cursores devem ser renomeados e declarados novamente.
CREATE OR REPLACE PROCEDURE simple_scenario ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ ""origin"": ""sf_sc"", ""name"": ""snowconvert"", ""version"": { ""major"": 0, ""minor"": 0, ""patch"": ""0"" }, ""attributes"": { ""component"": ""none"", ""convertedOn"": ""01/01/0001"" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
--Variables for the example's procedure_results
SQL_string_sel VARCHAR(200) DEFAULT 'SELECT
* FROM
MyTemporaryTable';
procedure_result INTEGER DEFAULT 0;
S1 RESULTSET;
prepareQuery_aux_sql VARCHAR;
BEGIN
-- Actual Cursor usage
prepareQuery_aux_sql := SQL_string_sel;
S1 := (
EXECUTE IMMEDIATE prepareQuery_aux_sql
);
LET CURSOR_S1_INSTANCE_V0 CURSOR
FOR
S1;
OPEN CURSOR_S1_INSTANCE_V0;
FETCH
CURSOR_S1_INSTANCE_V0
INTO
procedure_result;
INSERT INTO databaseTest.MyStatusTable (Col1)
VALUES (procedure_result);
CLOSE CURSOR_S1_INSTANCE_V0;
END;
$$;
CALL databaseTest.simple_scenario();
SELECT * FROM MyStatusTable;
Col1 |
---|
1 |
Cenário simples com RETURN ONLY¶
Teradata ¶
REPLACE PROCEDURE simple_scenario()
DYNAMIC RESULT SETS 1
BEGIN
DECLARE SQL_string_sel VARCHAR(200) DEFAULT 'SELECT * FROM MyTemporaryTable';
DECLARE procedure_result VARCHAR(100);
DECLARE C1 CURSOR WITH RETURN ONLY FOR S1;
SET procedure_result = '';
PREPARE S1 FROM SQL_string_sel;
OPEN C1;
END;
CALL databaseTest.simple_scenario();
SELECT * FROM MyStatusTable;
Col1 |
---|
1 |
Snowflake Scripting ¶
Nota
Os usos para cursores devem ser renomeados e declarados novamente.
CREATE OR REPLACE PROCEDURE simple_scenario ()
RETURNS TABLE (
)
LANGUAGE SQL
COMMENT = '{ ""origin"": ""sf_sc"", ""name"": ""snowconvert"", ""version"": { ""major"": 0, ""minor"": 0, ""patch"": ""0"" }, ""attributes"": { ""component"": ""none"", ""convertedOn"": ""01/01/0001"" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
SQL_string_sel VARCHAR(200) DEFAULT 'SELECT
* FROM
MyTemporaryTable';
procedure_result VARCHAR(100);
S1 RESULTSET;
prepareQuery_aux_sql VARCHAR;
BEGIN
procedure_result := '';
prepareQuery_aux_sql := SQL_string_sel;
S1 := (
EXECUTE IMMEDIATE prepareQuery_aux_sql
);
LET CURSOR_S1_INSTANCE_V0 CURSOR
FOR
S1;
OPEN CURSOR_S1_INSTANCE_V0;
RETURN TABLE(resultset_from_cursor(CURSOR_S1_INSTANCE_V0));
END;
$$;
CALL databaseTest.simple_scenario();
SELECT * FROM MyStatusTable;
Col1 |
---|
1 |
Caixa de cursor reutilizada¶
Teradata ¶
CREATE PROCEDURE fetch_simple_reused_cursor(OUT procedure_result INTEGER)
BEGIN
DECLARE SQL_string_sel VARCHAR(200) DEFAULT 'SELECT col1 FROM MyTemporaryTable WHERE col1 = 1';
DECLARE C1 CURSOR FOR S1;
PREPARE S1 FROM SQL_string_sel;
OPEN C1;
FETCH C1 INTO procedure_result;
CLOSE C1;
PREPARE S1 FROM SQL_string_sel;
OPEN C1;
FETCH C1 INTO procedure_result;
CLOSE C1;
END;
No returning information.
Snowflake Scripting ¶
Nota
Os usos para cursores devem ser renomeados e declarados novamente.
CREATE OR REPLACE PROCEDURE fetch_simple_reused_cursor (
-- OUT
PROCEDURE_RESULT INTEGER)
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/24/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
SQL_string_sel VARCHAR(200) DEFAULT 'SELECT
col1 FROM
MyTemporaryTable
WHERE col1 = 1';
S1 RESULTSET;
prepareQuery_aux_sql VARCHAR;
BEGIN
prepareQuery_aux_sql := SQL_string_sel;
S1 := (
EXECUTE IMMEDIATE prepareQuery_aux_sql
);
LET CURSOR_S1_INSTANCE_V0 CURSOR
FOR
S1;
OPEN CURSOR_S1_INSTANCE_V0;
FETCH
CURSOR_S1_INSTANCE_V0
INTO procedure_result;
CLOSE CURSOR_S1_INSTANCE_V0;
prepareQuery_aux_sql := SQL_string_sel;
S1 := (
EXECUTE IMMEDIATE prepareQuery_aux_sql
);
LET CURSOR_S1_INSTANCE_V1 CURSOR
FOR
S1;
OPEN CURSOR_S1_INSTANCE_V1;
FETCH
CURSOR_S1_INSTANCE_V1
INTO procedure_result;
CLOSE CURSOR_S1_INSTANCE_V1;
RETURN procedure_result;
END;
$$;
No returning information.
Consulta modificada antes do uso¶
Teradata ¶
REPLACE PROCEDURE fetch_modified_query_cursor()
BEGIN
--Variables for the example's procedure_results
DECLARE SQL_string_sel VARCHAR(200) DEFAULT 'SELECT col1 FROM MyTemporaryTable WHERE col1 = 1';
DECLARE procedure_result INTEGER DEFAULT 0;
-- Actual Cursor usages
DECLARE C1 CURSOR FOR S1;
PREPARE S1 FROM SQL_string_sel;
-- This modification does not take effect since S1 is already staged for the Cursor
SET SQL_string_sel = 'SELECT col1 FROM MyTemporaryTable WHERE col1 = 0';
OPEN C1;
FETCH C1 INTO procedure_result;
INSERT INTO databaseTest.MyStatusTable(Col1) VALUES (procedure_result);
CLOSE C1;
END;
CALL databaseTest.simple_scenario();
SELECT * FROM MyStatusTable;
Col1 |
---|
1 |
Snowflake Scripting ¶
Nota
Os usos para cursores devem ser renomeados e declarados novamente.
CREATE OR REPLACE PROCEDURE fetch_modified_query_cursor ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ ""origin"": ""sf_sc"", ""name"": ""snowconvert"", ""version"": { ""major"": 0, ""minor"": 0, ""patch"": ""0"" }, ""attributes"": { ""component"": ""none"", ""convertedOn"": ""01/01/0001"" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
--Variables for the example's procedure_results
SQL_string_sel VARCHAR(200) DEFAULT 'SELECT
col1 FROM
MyTemporaryTable
WHERE col1 = 1';
procedure_result INTEGER DEFAULT 0;
S1 RESULTSET;
prepareQuery_aux_sql VARCHAR;
BEGIN
-- Actual Cursor usages
prepareQuery_aux_sql := SQL_string_sel;
S1 := (
EXECUTE IMMEDIATE prepareQuery_aux_sql
);
LET CURSOR_S1_INSTANCE_V0 CURSOR
FOR
S1;
-- This modification does not take effect since S1 is already staged for the Cursor
SQL_string_sel := 'SELECT
col1 FROM
MyTemporaryTable
WHERE col1 = 0';
OPEN CURSOR_S1_INSTANCE_V0;
FETCH
CURSOR_S1_INSTANCE_V0
INTO
procedure_result;
INSERT INTO databaseTest.MyStatusTable (Col1)
VALUES (procedure_result);
CLOSE CURSOR_S1_INSTANCE_V0;
END;
$$;
CALL databaseTest.simple_scenario();
SELECT * FROM MyStatusTable;
Col1 |
---|
1 |
Cursor simples combinado sem padrão PREPARE¶
Teradata ¶
REPLACE PROCEDURE fetch_cursor_ignored_query_cursor()
BEGIN
--Variables for the example's procedure_results
DECLARE SQL_string_sel VARCHAR(200) DEFAULT 'SELECT * FROM MyTemporaryTable WHERE col1 = 1';
DECLARE intermediate_result INTEGER;
DECLARE procedure_result INTEGER DEFAULT 0;
DECLARE C2 CURSOR FOR SELECT col1 FROM MyTemporaryTable WHERE col1 = 1;
-- Actual Cursor usage
DECLARE C1 CURSOR FOR S1;
PREPARE S1 FROM SQL_string_sel;
OPEN C1;
FETCH C1 INTO intermediate_result;
CLOSE C1;
SET procedure_result = intermediate_result;
INSERT INTO databaseTest.MyStatusTable(Col1) VALUES (procedure_result);
OPEN C2;
FETCH C2 INTO intermediate_result;
CLOSE C2;
SET procedure_result = procedure_result + intermediate_result;
END;
CALL databaseTest.simple_scenario();
SELECT * FROM MyStatusTable;
Col1 |
---|
1 |
Snowflake Scripting ¶
Nota
Os usos para cursores devem ser renomeados e declarados novamente.
CREATE OR REPLACE PROCEDURE fetch_cursor_ignored_query_cursor ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ ""origin"": ""sf_sc"", ""name"": ""snowconvert"", ""version"": { ""major"": 0, ""minor"": 0, ""patch"": ""0"" }, ""attributes"": { ""component"": ""none"", ""convertedOn"": ""01/01/0001"" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
--Variables for the example's procedure_results
SQL_string_sel VARCHAR(200) DEFAULT 'SELECT
* FROM
MyTemporaryTable
WHERE col1 = 1';
intermediate_result INTEGER;
procedure_result INTEGER DEFAULT 0;
S1 RESULTSET;
prepareQuery_aux_sql VARCHAR;
BEGIN
-- Actual Cursor usage
LET C2 CURSOR
FOR
SELECT
col1
FROM
MyTemporaryTable
WHERE
col1 = 1;
prepareQuery_aux_sql := SQL_string_sel;
S1 := (
EXECUTE IMMEDIATE prepareQuery_aux_sql
);
LET CURSOR_S1_INSTANCE_V0 CURSOR
FOR
S1;
OPEN CURSOR_S1_INSTANCE_V0;
FETCH
CURSOR_S1_INSTANCE_V0
INTO
intermediate_result;
CLOSE CURSOR_S1_INSTANCE_V0;
procedure_result := intermediate_result;
INSERT INTO databaseTest.MyStatusTable (Col1)
VALUES (procedure_result);
OPEN C2;
FETCH
C2
INTO
intermediate_result;
CLOSE C2;
procedure_result := procedure_result + intermediate_result;
END;
$$;
CALL databaseTest.simple_scenario();
SELECT * FROM MyStatusTable;
Col1 |
---|
1 |
Prepare combinado com cursores aninhados¶
Teradata ¶
REPLACE PROCEDURE fetch_nested_cursor()
BEGIN
--Variables for the example's procedure_results
DECLARE SQL_string_sel VARCHAR(200) DEFAULT 'SELECT col1 FROM MyTemporaryTable WHERE col1 = 1';
DECLARE intermediate_result INTEGER;
DECLARE C2 CURSOR FOR SELECT col1 FROM MyTemporaryTable WHERE col1 = 1;
-- Actual Cursor usage
DECLARE C1 CURSOR FOR S1;
PREPARE S1 FROM SQL_string_sel;
OPEN C1;
OPEN C2;
FETCH C2 INTO intermediate_result;
CLOSE C2;
FETCH C1 INTO intermediate_result;
CLOSE C1;
END;
No returning information.
Snowflake Scripting ¶
Nota
Os usos para cursores devem ser renomeados e declarados novamente.
CREATE OR REPLACE PROCEDURE fetch_nested_cursor ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ ""origin"": ""sf_sc"", ""name"": ""snowconvert"", ""version"": { ""major"": 0, ""minor"": 0, ""patch"": ""0"" }, ""attributes"": { ""component"": ""none"", ""convertedOn"": ""01/01/0001"" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
--Variables for the example's procedure_results
SQL_string_sel VARCHAR(200) DEFAULT 'SELECT
col1 FROM
MyTemporaryTable
WHERE col1 = 1';
intermediate_result INTEGER;
S1 RESULTSET;
prepareQuery_aux_sql VARCHAR;
BEGIN
-- Actual Cursor usage
LET C2 CURSOR
FOR
SELECT
col1
FROM
MyTemporaryTable
WHERE
col1 = 1;
prepareQuery_aux_sql := SQL_string_sel;
S1 := (
EXECUTE IMMEDIATE prepareQuery_aux_sql
);
LET CURSOR_S1_INSTANCE_V0 CURSOR
FOR
S1;
OPEN CURSOR_S1_INSTANCE_V0;
OPEN C2;
FETCH
C2
INTO
intermediate_result;
CLOSE C2;
FETCH
CURSOR_S1_INSTANCE_V0
INTO
intermediate_result;
CLOSE CURSOR_S1_INSTANCE_V0;
END;
$$;
No returning information.
Marcadores de variáveis sem reordenação de variáveis¶
Aviso
Esse caso ainda não é suportado.
Teradata ¶
CREATE PROCEDURE PREPARE_ST_TEST()
BEGIN
DECLARE ctry_list VARCHAR(100);
DECLARE SQL_string_sel VARCHAR(255);
DECLARE col_value NUMBER;
DECLARE C1 CURSOR FOR S1;
SET ctry_list = '';
SET col_value = 1;
SET SQL_string_sel = 'SELECT * FROM databaseTest.MyTemporaryTable where Col1 = ?';
PREPARE S1 FROM SQL_string_sel;
OPEN C1 USING col_value;
FETCH C1 INTO ctry_list;
IF (ctry_list <> '') THEN
INSERT INTO databaseTest.MyStatusTable(col1) VALUES ('ok');
END IF;
CLOSE C1;
END;
CALL PREPARE_ST_TEST();
SELECT * FROM MyStatusTable;
Col1 |
---|
ok |
Snowflake Scripting ¶
Nota
Os usos para cursores devem ser renomeados e declarados novamente.
CREATE OR REPLACE PROCEDURE PREPARE_ST_TEST_MARKERS ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
p1 RESULTSET;
p1_sql VARCHAR DEFAULT '';
BEGIN
LET ctry_list VARCHAR(100);
LET SQL_string_sel VARCHAR(255);
LET col_value NUMBER(38, 18);
LET S1 RESULTSET;
ctry_list := '';
col_value := 1;
SQL_string_sel := 'SELECT * FROM MyTemporaryTable WHERE Col1 = ?';
p1_sql := SQL_string_sel;
S1 := (
EXECUTE IMMEDIATE p1_sql USING (col_value)
);
LET C1 CURSOR FOR S1;
OPEN C1;
FETCH C1 INTO ctry_list;
IF (RTRIM(ctry_list) <> '') THEN
INSERT INTO MyStatusTable (col1)
VALUES ('ok');
END IF;
CLOSE C1;
END;
$$;
Col1 |
---|
ok |
Marcadores variáveis com reordenação de variáveis¶
Aviso
Esse caso ainda não é suportado.
Nota
Quando há variáveis que definem o valor em outros diferentes entre a instrução PREPARE
e o cursor OPEN
no Teradata, é necessário mover essa variável antes de EXECUTE IMMEDIATE
no Snowflake. Portanto, as informações da variável dinâmica são atualizadas no momento da execução da consulta dinâmica.
Teradata ¶
CREATE PROCEDURE PREPARE_ST_TEST()
BEGIN
DECLARE ctry_list VARCHAR(100);
DECLARE SQL_string_sel VARCHAR(255);
DECLARE col_name NUMBER;
DECLARE C1 CURSOR FOR S1;
SET ctry_list = '';
SET col_name = 1;
SET SQL_string_sel = 'SELECT * FROM databaseTest.MyTemporaryTable where Col1 = ?';
PREPARE S1 FROM SQL_string_sel;
SET col_name = 2; // change value before open cursor
OPEN C1 USING col_name;
FETCH C1 INTO ctry_list;
IF (ctry_list <> '') THEN
INSERT INTO databaseTest.MyStatusTable(col1) VALUES ('ok');
END IF;
CLOSE C1;
END;
CALL PREPARE_ST_TEST();
SELECT * FROM MyStatusTable;
"MyStatusTable" should be empty.
Snowflake Scripting ¶
Nota
Os usos para cursores devem ser renomeados e declarados novamente.
CREATE OR REPLACE PROCEDURE PREPARE_ST_TEST_MARKERS ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
p1 RESULTSET;
p1_sql VARCHAR DEFAULT '';
BEGIN
LET ctry_list VARCHAR(100);
LET SQL_string_sel VARCHAR(255);
LET col_value NUMBER(38, 18);
LET S1 RESULTSET;
ctry_list := '';
col_value := 1;
SQL_string_sel := 'SELECT * FROM MyTemporaryTable WHERE Col1 = ?';
p1_sql := SQL_string_sel;
col_value:= 2; // Move variable setting before the EXECUTE IMMEDIATE
S1 := (
EXECUTE IMMEDIATE p1_sql USING (col_value)
);
LET C1 CURSOR FOR S1;
OPEN C1;
FETCH C1 INTO ctry_list;
IF (RTRIM(ctry_list) <> '') THEN
INSERT INTO MyStatusTable (col1)
VALUES ('ok');
END IF;
CLOSE C1;
END;
$$;
CALL PREPARE_ST_TEST();
SELECT * FROM MyStatusTable;
"MyStatusTable" should be empty.
Blocos anônimos - Declaração fora do bloco¶
Aviso
Esse caso ainda não é suportado.
Teradata ¶
REPLACE PROCEDURE anonymous_blocks_case(OUT procedure_result INTEGER)
BEGIN
--Variables for the example's procedure_results
DECLARE SQL_string_sel VARCHAR(200) DEFAULT 'SELECT col1 FROM MyTemporaryTable WHERE col1 = 1';
-- Actual Cursor usage
DECLARE C1 CURSOR FOR S1;
DECLARE C2 CURSOR FOR S2;
PREPARE S1 FROM SQL_string_sel;
OPEN C1;
FETCH C1 INTO procedure_result;
CLOSE C1;
BEGIN
PREPARE S2 FROM SQL_string_sel;
OPEN C2;
FETCH C2 INTO procedure_result;
CLOSE C2;
END;
OPEN C1;
CLOSE C1;
END;
No returning information.
CREATE OR REPLACE PROCEDURE anonymous_blocks_case (
-- OUT
PROCEDURE_RESULT INTEGER)
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "none", "convertedOn": "01/01/0001" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
--Variables for the example's procedure_results
SQL_string_sel VARCHAR(200) DEFAULT 'SELECT
col1 FROM
MyTemporaryTable
WHERE col1 = 1';
S1 RESULTSET;
prepareQuery_aux_sql VARCHAR;
S2 RESULTSET;
BEGIN
-- Actual Cursor usage
prepareQuery_aux_sql := SQL_string_sel
S1 := (
EXECUTE IMMEDIATE prepareQuery_aux_sql
);
LET CURSOR_S1_INSTANCE_V0 CURSOR
FOR
S1;
OPEN CURSOR_S1_INSTANCE_V0;
FETCH
CURSOR_S1_INSTANCE_V0
INTO
procedure_result;
CLOSE CURSOR_S1_INSTANCE_V0;
BEGIN
prepareQuery_aux_sql := SQL_string_sel
S2 := (
EXECUTE IMMEDIATE prepareQuery_aux_sql
);
LET CURSOR_S2_INSTANCE_V# CURSOR
FOR
S1;
OPEN CURSOR_S2_INSTANCE_V#;
FETCH
CURSOR_S2_INSTANCE_V#
INTO
procedure_result;
CLOSE CURSOR_S2_INSTANCE_V#;
END;
OPEN CURSOR_S1_INSTANCE_V0; -- NAME REMAINS AS NEEDED IN LOGIC
CLOSE CURSOR_S1_INSTANCE_V0;
RETURN null;
END;
$$;
No returning information.
Problemas conhecidos¶
Analise cuidadosamente os cursores e condicionais aninhados, se esse for o caso.
EWIs Relacionados ¶
Sem EWIs relacionados.
REPEAT¶
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Descrição ¶
A instrução REPEAT
do Teradata é convertida para a sintaxe do Snowflake Scripting REPEAT
.
Para obter mais informações sobre o Teradata Repeat, veja aqui.
[label_name:] REPEAT
{ sql_statement }
UNTIL conditional_expression
END REPEAT [label_name];
Amostra de padrões de origem ¶
Teradata ¶
CREATE PROCEDURE repeatProcedure(OUT resultCounter INTEGER)
BEGIN
DECLARE counter INTEGER DEFAULT 0;
customeLabel: REPEAT
SET counter = counter + 1;
UNTIL 10 < counter
END REPEAT customeLabel;
SET resultCounter = counter;
END;
CALL repeatProcedure(:?);
|resultCounter|
|-------------|
|11 |
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE repeatProcedure (
-- OUT
RESULTCOUNTER INTEGER)
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/24/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
counter INTEGER DEFAULT 0;
BEGIN
REPEAT
counter := counter + 1;
UNTIL (10 < counter)
END REPEAT CUSTOMELABEL;
resultCounter := counter;
RETURN resultCounter;
END;
$$;
CALL repeatProcedure(:?);
|REPEATPROCEDURE|
|---------------|
|1 |
Problemas conhecidos ¶
Não foram encontrados problemas.
EWIs Relacionados ¶
Sem EWIs relacionados.
SET¶
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Descrição ¶
Atribui um valor a uma variável local ou parâmetro em um procedimento armazenado.
Para obter mais informações sobre o Teradata SET, veja aqui.
SET assigment_target = assigment_source ;
Amostra de padrões de origem ¶
Teradata ¶
CREATE PROCEDURE setExample ( OUT PARAM1 INTEGER )
BEGIN
DECLARE COL_COUNT INTEGER;
SET COL_COUNT = 3;
SET PARAM1 = COL_COUNT + 1;
END;
|PARAM1 |
|-------|
|4 |
Script Snowflake¶
CREATE OR REPLACE PROCEDURE setExample (
-- OUT
PARAM1 INTEGER )
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/24/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
COL_COUNT INTEGER;
BEGIN
COL_COUNT := 3;
PARAM1 := COL_COUNT + 1;
RETURN PARAM1;
END;
$$;
|PARAM1 |
|-------|
|4 |
Problemas conhecidos ¶
Não foram encontrados problemas.
EWIs Relacionados ¶
Sem EWIs relacionados.
SYSTEM_DEFINED¶
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Nota
Instrução não relevante.
Aviso
Observe que essa instrução é removida da migração porque é uma sintaxe não relevante. Isso significa que não é necessária no Snowflake.
Descrição¶
Propriedade no Teradata que pode estar depois de uma instrução CREATE
em casos como JOIN INDEX
.
Amostra de padrões da origem¶
Observe que SYSTEM_DEFINED foi removido do código-fonte porque é uma sintaxe não relevante no Snowflake.
CREATE SYSTEM_DEFINED JOIN INDEX MY_TESTS.MYPARTS_TJI004 ,FALLBACK ,CHECKSUM = DEFAULT, MAP = TD_MAP1 AS
CURRENT TRANSACTIONTIME
SELECT
MY_TESTS.myParts.ROWID,
MY_TESTS.myParts.part_id,
MY_TESTS.part_duration
FROM MY_TESTS.myParts
UNIQUE PRIMARY INDEX (part_id);
--** SSC-FDM-0007 - MISSING DEPENDENT OBJECT "MY_TESTS.myParts" **
CREATE OR REPLACE DYNAMIC TABLE MY_TESTS.MYPARTS_TJI004
--** SSC-FDM-0031 - DYNAMIC TABLE REQUIRED PARAMETERS SET BY DEFAULT **
TARGET_LAG='1 day'
WAREHOUSE=UPDATE_DUMMY_WAREHOUSE
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/01/2024" }}'
AS
-- --** SSC-FDM-TD0025 - TEMPORAL FORMS ARE NOT SUPPORTED IN SNOWFLAKE **
-- CURRENT TRANSACTIONTIME
SELECT
MY_TESTS.myParts.ROWID,
MY_TESTS.myParts.part_id,
MY_TESTS.part_duration
FROM
MY_TESTS.myParts;
Problemas conhecidos ¶
Não foram encontrados problemas.
EWIs relacionados¶
SSC-FDM-0007: Elemento com dependências ausentes.
SSC-FDM-TD0025: A tabela temporal do banco de dados Teradata não é compatível com o Snowflake.
SSC-FDM-0031: Parâmetros necessários da tabela dinâmica definidos por padrão
WHILE¶
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Descrição ¶
A instrução WHILE
do Teradata é convertida para a sintaxe do Snowflake ScriptingWHILE
.
Para obter mais informações sobre o Teradata While, veja aqui.
[label_name:] WHILE conditional_expression DO
{ sql_statement }
END WHILE [label_name];
Amostra de padrões da origem¶
Teradata¶
REPLACE PROCEDURE whileProcedure(OUT resultCounter INTEGER)
BEGIN
DECLARE counter INTEGER DEFAULT 0;
customeLabel: WHILE counter < 10 DO
SET counter = counter + 1;
END WHILE customeLabel;
SET resultCounter = counter;
END;
CALL whileProcedure(:?);
|resultCounter|
|-------------|
|10 |
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE whileProcedure (
-- OUT
RESULTCOUNTER INTEGER)
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "07/24/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
counter INTEGER DEFAULT 0;
BEGIN
WHILE ( counter < 10) LOOP
counter := counter + 1;
END LOOP CUSTOMELABEL;
resultCounter := counter;
RETURN resultCounter;
END;
$$;
CALL whileProcedure(:?);
|WHILEPROCEDURE|
|--------------|
|10 |
Problemas conhecidos ¶
Não foram encontrados problemas.
EWIs Relacionados ¶
Sem EWIs relacionados.