SnowConvert: Snowflake Scripting¶
Transação BEGIN e COMMIT¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Descrição¶
Snowflake SQL, uma transação pode ser iniciada explicitamente com a execução de uma instrução BEGIN. O Snowflake oferece suporte aos sinônimos BEGINWORK
e BEGINTRANSACTION
. O Snowflake recomenda usar BEGINTRANSACTION
.
Uma transação pode ser encerrada explicitamente com a execução de COMMIT. Leia mais sobre as transações do Snowflake aqui.
Amostra de padrões de origem ¶
Os exemplos a seguir detalham as instruções de transação BEGIN e COMMIT.
Transact-SQL ¶
CREATE PROCEDURE TestTransaction
AS
BEGIN
DROP TABLE IF EXISTS NEWTABLE;
CREATE TABLE NEWTABLE(COL1 INT, COL2 VARCHAR);
BEGIN TRANSACTION;
INSERT INTO NEWTABLE VALUES (1, 'MICHAEL');
INSERT INTO NEWTABLE VALUES(2, 'JACKSON');
COMMIT TRANSACTION;
END
CREATE PROCEDURE TestTransaction
AS
BEGIN
DROP TABLE IF EXISTS NEWTABLE;
CREATE TABLE NEWTABLE(COL1 INT, COL2 VARCHAR);
BEGIN TRANSACTION LabelA;
INSERT INTO NEWTABLE VALUES (1, 'MICHAEL');
INSERT INTO NEWTABLE VALUES(2, 'JACKSON');
COMMIT TRANSACTION LabelA;
END
Snowflake SQL ¶
CREATE OR REPLACE PROCEDURE TestTransaction ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
DROP TABLE IF EXISTS NEWTABLE;
CREATE OR REPLACE TABLE NEWTABLE (
COL1 INT,
COL2 VARCHAR
);
BEGIN TRANSACTION;
INSERT INTO NEWTABLE VALUES (1, 'MICHAEL');
INSERT INTO NEWTABLE VALUES(2, 'JACKSON');
COMMIT;
END;
$$;
CREATE OR REPLACE PROCEDURE TestTransaction ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
DROP TABLE IF EXISTS NEWTABLE;
CREATE OR REPLACE TABLE NEWTABLE (
COL1 INT,
COL2 VARCHAR
);
BEGIN TRANSACTION
!!!RESOLVE EWI!!! /*** SSC-EWI-0101 - COMMENTED OUT TRANSACTION LABEL NAME BECAUSE IS NOT APPLICABLE IN SNOWFLAKE ***/!!!
LabelA;
INSERT INTO NEWTABLE VALUES (1, 'MICHAEL');
INSERT INTO NEWTABLE VALUES(2, 'JACKSON');
COMMIT;
END;
$$;
Problemas conhecidos¶
As transações aninhadas não são compatíveis com o Snowflake. Consulte a documentação a seguir para obter mais informações: https://docs.snowflake.com/en/sql-reference/transactions
CALL¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Descrição ¶
A instrução CALL Snowflake Scripting, pois faz parte da API ODBC e não uma instrução SQL. Portanto, essa instrução não é convertida.
CASE¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Descrição¶
O Transact-SQL tem dois formatos possíveis da expressão Case, ambos com a finalidade de avaliar expressões e obter resultados condicionalmente. O primeiro refere-se a uma expressão Case simples que será avaliada se uma expressão input_expression corresponder a uma ou mais expressões when_expression. O segundo avaliará cada expressão booliana de forma independente. A cláusula else é suportada em ambos os formatos.
De acordo com a documentação oficial de Transact-SQL Case:
CASE pode ser usado em qualquer instrução ou cláusula que permita uma expressão válida. Por exemplo, você pode usar CASE em instruções como SELECT, UPDATE, DELETE e SET, e em cláusulas como select_list, IN, WHERE, ORDER BY e HAVING.
Para obter mais informações sobre Transact-SQL Case, veja aqui.
-- Simple CASE expression:
CASE input_expression
WHEN when_expression THEN result_expression [ ...n ]
[ ELSE else_result_expression ]
END
-- Searched CASE expression:
CASE
WHEN boolean_expression THEN result_expression [ ...n ]
[ ELSE else_result_expression ]
END
Observação: o Transact-SQL permite encapsular opcionalmente a expressão input_expression e a expressão boolean_expression entre parênteses; o Snowflake Scripting também.
Amostra de padrões de origem ¶
Os exemplos a seguir detalham dois cenários em que a expressão Case pode ser usada e suas diferenças em relação ao Snowflake Scripting.
Select usando Case¶
Transact-SQL¶
CREATE OR ALTER PROCEDURE SelectCaseDemoProcedure
AS
SELECT TOP 10
LOGINID,
CASE (MARITALSTATUS)
WHEN 'S' THEN 'SINGLE'
WHEN 'M' THEN 'MARIED'
ELSE 'OTHER'
END AS status
FROM HUMANRESOURCES.EMPLOYEE;
GO
EXEC SelectCaseDemoProcedure;
CREATE OR ALTER PROCEDURE SelectCaseDemoProcedure
AS
SELECT TOP 10
LOGINID,
CASE
WHEN MARITALSTATUS = 'S' THEN 'SINGLE'
WHEN MARITALSTATUS = 'M' THEN 'MARIED'
ELSE 'OTHER'
END AS status
FROM HUMANRESOURCES.EMPLOYEE;
GO
EXEC SelectCaseDemoProcedure;
sqlLOGINID |status|
------------------------+------+
adventure-works\ken0 |SINGLE|
adventure-works\terri0 |SINGLE|
adventure-works\roberto0|MARIED|
adventure-works\rob0 |SINGLE|
adventure-works\gail0 |MARIED|
adventure-works\jossef0 |MARIED|
adventure-works\dylan0 |MARIED|
adventure-works\diane1 |SINGLE|
adventure-works\gigi0 |MARIED|
adventure-works\michael6|MARIED|
Snowflake Scripting ¶
Observe que, nesse cenário, não há diferenças em relação à expressão Case em si.
Aviso
A declaração e a atribuição da variável res
servem para demonstrar a equivalência funcional entre as duas linguagens. Ela não aparece na saída real.
CREATE OR REPLACE PROCEDURE SelectCaseDemoProcedure ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
ProcedureResultSet RESULTSET;
BEGIN
ProcedureResultSet := (
SELECT TOP 10
LOGINID,
CASE (MARITALSTATUS)
WHEN 'S' THEN 'SINGLE'
WHEN 'M' THEN 'MARIED'
ELSE 'OTHER'
END AS status
FROM
HUMANRESOURCES.EMPLOYEE);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL SelectCaseDemoProcedure();
CREATE OR REPLACE PROCEDURE SelectCaseDemoProcedure ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
ProcedureResultSet RESULTSET;
BEGIN
ProcedureResultSet := (
SELECT TOP 10
LOGINID,
CASE
WHEN MARITALSTATUS = 'S' THEN 'SINGLE'
WHEN MARITALSTATUS = 'M' THEN 'MARIED'
ELSE 'OTHER'
END AS status
FROM
HUMANRESOURCES.EMPLOYEE);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL SelectCaseDemoProcedure();
LOGINID |STATUS|
-----------------------+------+
adventure-worksken0 |SINGLE|
adventure-works erri0 |SINGLE|
adventure-worksoberto0 |MARIED|
adventure-worksob0 |SINGLE|
adventure-worksgail0 |MARIED|
adventure-worksjossef0 |MARIED|
adventure-worksdylan0 |MARIED|
adventure-worksdiane1 |SINGLE|
adventure-worksgigi0 |MARIED|
adventure-worksmichael6|MARIED|
Set usando Case¶
O banco de dados AdventureWorks2019 foi usado em ambas as linguagens para obter os mesmos resultados.
Transact-SQL¶
CREATE OR ALTER PROCEDURE SetCaseDemoProcedure
AS
DECLARE @value INT;
DECLARE @result INT;
SET @value = 5;
SET @result =
CASE @value
WHEN 1 THEN @value * 10
WHEN 3 THEN @value * 20
WHEN 5 THEN @value * 30
WHEN 7 THEN @value * 40
ELSE -1
END;
RETURN @result
GO
DECLARE @result INT;
EXEC @result = SetCaseDemoProcedure;
PRINT @result;
CREATE OR ALTER PROCEDURE SetCaseDemoProcedure
AS
DECLARE @value INT;
DECLARE @result INT;
SET @value = 5;
SET @result =
CASE
WHEN @value = 1 THEN @value * 10
WHEN @value = 3 THEN @value * 20
WHEN @value = 5 THEN @value * 30
WHEN @value = 7 THEN @value * 40
ELSE -1
END;
RETURN @result
GO
DECLARE @result INT;
EXEC @result = SetCaseDemoProcedure;
PRINT @result;
|result|
|------|
|150 |
Snowflake Scripting ¶
Aviso
O Snowflake Scripting não permite definir uma expressão Case diretamente em uma variável. Ambos os formatos de expressão Transact-SQL Case são convertidos para a seguinte gramática no Snowflake Scripting.
CREATE OR REPLACE PROCEDURE SetCaseDemoProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
VALUE INT;
RESULT INT;
BEGIN
VALUE := 5;
CASE (:VALUE)
WHEN 1 THEN
RESULT := :VALUE * 10;
WHEN 3 THEN
RESULT := :VALUE * 20;
WHEN 5 THEN
RESULT := :VALUE * 30;
WHEN 7 THEN
RESULT := :VALUE * 40;
ELSE
RESULT := -1;
END;
RETURN :RESULT;
END;
$$;
DECLARE
RESULT INT;
BEGIN
CALL SetCaseDemoProcedure();
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Print' NODE ***/!!!
PRINT @result;
END;
CREATE OR REPLACE PROCEDURE SetCaseDemoProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
VALUE INT;
RESULT INT;
BEGIN
VALUE := 5;
CASE
WHEN :VALUE = 1 THEN
RESULT := :VALUE * 10;
WHEN :VALUE = 3 THEN
RESULT := :VALUE * 20;
WHEN :VALUE = 5 THEN
RESULT := :VALUE * 30;
WHEN :VALUE = 7 THEN
RESULT := :VALUE * 40;
ELSE
RESULT := -1;
END;
RETURN :RESULT;
END;
$$;
DECLARE
RESULT INT;
BEGIN
CALL SetCaseDemoProcedure();
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Print' NODE ***/!!!
PRINT @result;
END;
|result|
|------|
|150 |
Problemas conhecidos¶
Não foram encontrados problemas.
EWIs relacionados¶
SSC-EWI-0073: Revisão de equivalência funcional pendente.
CREATE PROCEDURE¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Descrição¶
A instrução create procedure permite a criação de procedimentos armazenados que podem:
Aceitar parâmetros de entrada e retornar vários valores na forma de parâmetros de saída para o procedimento de chamada ou lote.
Conter instruções de programação que executam operações no banco de dados, inclusive a chamada de outros procedimentos.
Retorna um valor de status para um procedimento de chamada ou lote para indicar sucesso ou falha (e o motivo da falha).
Para obter mais informações sobre Transact-SQL CREATE PROCEDURE, veja aqui.
CREATE [ OR ALTER ] { PROC | PROCEDURE }
[schema_name.] procedure_name [ ; number ]
[ { @parameter [ type_schema_name. ] data_type }
[ VARYING ] [ = default ] [ OUT | OUTPUT | [READONLY]
] [ ,...n ]
[ WITH <procedure_option> [ ,...n ] ]
[ FOR REPLICATION ]
AS { [ BEGIN ] sql_statement [;] [ ...n ] [ END ] }
[;]
Amostra de padrões da origem¶
Procedimento armazenado sem corpo¶
Um procedimento armazenado sem um corpo é um cenário incomum que é permitido no Transact-SQL. O Snowflake Scripting não permite definir procedimentos sem um corpo, mas o exemplo a seguir mostra a equivalência.
Transact-SQL¶
CREATE PROC SampleProcedure AS;
Script Snowflake¶
CREATE OR REPLACE PROCEDURE SampleProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
RETURN '';
END;
$$;
Procedimento armazenado básico¶
O exemplo a seguir detalha um procedimento armazenado simples que incluirá um novo departamento de privacidade no banco de dados AdventureWorks2019.
Transact-SQL¶
CREATE OR ALTER PROCEDURE Add_Privacy_Department
AS
EXECUTE ('INSERT INTO HumanResources.Department VALUES (''Privacy'', ''Executive General and Administration'', default)');
Script Snowflake¶
CREATE OR REPLACE PROCEDURE Add_Privacy_Department ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE 'INSERT INTO HumanResources.Department VALUES ('Privacy', 'Executive General and Administration', default);';
END;
$$;
Procedimento Alter¶
A transformação para o procedimento ALTER é equivalente ao procedimento básico.
Transact-SQL¶
ALTER PROCEDURE procedureName
AS
SELECT 1 AS ThisDB;
Script Snowflake¶
CREATE OR REPLACE PROCEDURE procedureName ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
ProcedureResultSet RESULTSET;
BEGIN
ProcedureResultSet := (
SELECT 1 AS ThisDB);
RETURN TABLE(ProcedureResultSet);
END;
$$;
Usando parâmetros¶
Você pode usar parâmetros para conduzir sua lógica ou construir instruções dinâmicas SQL dentro do procedimento armazenado. No exemplo a seguir, é criado um procedimento armazenado SetNewPrice simples, que define um novo preço de produto com base nos argumentos enviados pelo chamador.
Transact-SQL¶
CREATE OR ALTER PROCEDURE SetNewPrice @ProductID INT, @NewPrice MONEY
AS
BEGIN
DECLARE @dynSqlStatement AS VARCHAR(300);
SET @dynSqlStatement = 'UPDATE Production.ProductListPriceHistory SET ListPrice = ' + CAST(@NewPrice AS VARCHAR(10)) + ' WHERE ProductID = ' + CAST(@ProductID AS VARCHAR(10)) + ' AND EndDate IS NULL';
EXECUTE (@dynSqlStatement);
END;
Script Snowflake¶
CREATE OR REPLACE PROCEDURE SetNewPrice (PRODUCTID INT, NEWPRICE NUMBER(38, 4))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
DYNSQLSTATEMENT VARCHAR(300);
BEGIN
DYNSQLSTATEMENT := 'UPDATE Production.ProductListPriceHistory
SET
ListPrice = ' || CAST(:NEWPRICE AS VARCHAR(10)) || '
WHERE
ProductID = ' || CAST(:PRODUCTID AS VARCHAR(10)) || '
AND EndDate IS NULL;';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE :DYNSQLSTATEMENT;
END;
$$;
Parâmetros de saída¶
A palavra-chave output do Transact-SQL indica que o parâmetro é um parâmetro de saída, cujo valor será retornado ao chamador do procedimento armazenado. Por exemplo, o procedimento a seguir retornará o número de horas de férias de um funcionário específico.
Transact-SQL¶
CREATE PROCEDURE GetVacationHours
@employeeId INT,
@vacationHours INT OUTPUT
AS
BEGIN
SELECT @vacationHours = VacationHours
FROM HumanResources.Employee
WHERE NationalIDNumber = @employeeID
END;
Script Snowflake¶
CREATE OR REPLACE PROCEDURE GetVacationHours (EMPLOYEEID INT, VACATIONHOURS INT)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
SELECT
VacationHours
INTO
:VACATIONHOURS
FROM
HumanResources.Employee
WHERE
NationalIDNumber = :EMPLOYEEID;
RETURN VACATIONHOURS;
END;
$$;
Aviso
Apenas um parâmetro de saída pode ser retornado de um procedimento armazenado do Snowflake Scripting.
Parâmetros opcionais¶
Um parâmetro é considerado opcional se tiver um valor padrão especificado quando for declarado. Não é necessário fornecer um valor para um parâmetro opcional em uma chamada de procedimento.
Transact-SQL¶
CREATE PROCEDURE OPTIONAL_PARAMETER @VAR1 INT = 1, @VAR2 INT = 2
AS
BEGIN
RETURN NULL;
END
GO
EXEC OPTIONAL_PARAMETER @VAR2 = 4
Script Snowflake¶
CREATE OR REPLACE PROCEDURE OPTIONAL_PARAMETER (VAR1 INT DEFAULT 1, VAR2 INT DEFAULT 2)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
RETURN NULL;
END;
$$;
CALL OPTIONAL_PARAMETER(VAR2 => 4);
EXECUTE AS¶
A cláusula EXECUTE AS do Transact-SQL define o contexto de execução do procedimento armazenado, especificando qual conta de usuário o Mecanismo de Banco de Dados usa para validar as permissões dos objetos referenciados no procedimento. Por exemplo, podemos modificar o procedimento GetVacationHours anterior para definir diferentes contextos de execução.
Proprietário (padrão no Snowflake Scripting)
Transact-SQL¶
CREATE OR ALTER PROCEDURE GetVacationHours
@employeeId INT,
@vacationHours INT OUTPUT
WITH EXECUTE AS OWNER
AS
BEGIN
SELECT @vacationHours = VacationHours
FROM HumanResources.Employee
WHERE NationalIDNumber = @employeeID
END;
Script Snowflake¶
CREATE OR REPLACE PROCEDURE GetVacationHours (EMPLOYEEID INT, VACATIONHOURS INT)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS OWNER
AS
$$
BEGIN
SELECT
VacationHours
INTO
:VACATIONHOURS
FROM
HumanResources.Employee
WHERE
NationalIDNumber = :EMPLOYEEID;
RETURN VACATIONHOURS;
END;
$$;
Chamador
Transact-SQL¶
CREATE OR ALTER PROCEDURE GetVacationHours
@employeeId INT,
@vacationHours INT OUTPUT
WITH EXECUTE AS CALLER
AS
BEGIN
SELECT @vacationHours = VacationHours
FROM HumanResources.Employee
WHERE NationalIDNumber = @employeeID
END;
Script Snowflake¶
CREATE OR REPLACE PROCEDURE GetVacationHours (EMPLOYEEID INT, VACATIONHOURS INT)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
SELECT
VacationHours
INTO
:VACATIONHOURS
FROM
HumanResources.Employee
WHERE
NationalIDNumber = :EMPLOYEEID;
RETURN VACATIONHOURS;
END;
$$;
Aviso
SELF e contextos de execução de usuários específicos («user_name») não são suportados no Snowflake Scripting.
READONLY AND VARYING PARAMETERS¶
O Snowflake não oferece suporte aos tipos de parâmetros READONLY
e VARYING
. Em vez disso, foi adicionado um FDM.
Transact-SQL¶
CREATE OR ALTER PROCEDURE GetVacationHours
@Param1 INT READONLY,
@Param2 INT VARYING
AS
BEGIN
SELECT * FROM Table1;
END;
Script Snowflake¶
CREATE OR REPLACE PROCEDURE GetVacationHours (PARAM1 INT !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'READONLY PARAMETERS' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!, PARAM2 INT !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'VARYING PARAMETERS' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!)
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
ProcedureResultSet RESULTSET;
BEGIN
ProcedureResultSet := (
SELECT
*
FROM
Table1);
RETURN TABLE(ProcedureResultSet);
END;
$$;
Problemas conhecidos¶
Argumentos opcionais não suportados¶
[VARYING] Aplica-se somente aos parâmetros cursor. Especifica o conjunto de resultados suportado como um parâmetro de saída. Esse parâmetro é construído dinamicamente pelo procedimento e seu conteúdo pode variar. O Snowflake Scripting não é compatível com CURSOR como um tipo de dados de retorno válido.
[= default] Torna um parâmetro opcional por meio da definição de um valor padrão. O Snowflake Scripting não suporta nativamente valores de parâmetros padrão.
[READONLY] Indica que o parâmetro não pode ser atualizado ou modificado no corpo do procedimento. Atualmente, não há suporte para o Snowflake Scripting.
[WITH RECOMPILE] Força o mecanismo de banco de dados a compilar o plano de consulta do procedimento armazenado sempre que ele for executado. Atualmente, não há suporte para o Snowflake Scripting.
[WITH ENCRYPTION] Usado para criptografar o texto de um procedimento armazenado. Somente usuários com acesso a tabelas do sistema ou arquivos de banco de dados (como usuários administradores do sistema) poderão acessar o texto do procedimento após sua criação. Atualmente, não há suporte para o Snowflake Scripting.
[FOR REPLICATION] Restringe o procedimento armazenado a ser executado somente durante a replicação. Atualmente, não há suporte para o Snowflake Scripting.
EWIS relacionados¶
SSC-EWI-0030: A instrução abaixo tem usos de SQL dinâmico.
SSC-EWI-0058: No momento, a funcionalidade não é compatível com o Snowflake Scripting.
CURSOR¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Descrição¶
As instruções Transact-SQL produzem um conjunto completo de resultados, mas há ocasiões em que os resultados são melhor processados uma linha de cada vez. A abertura de um cursor em um conjunto de resultados permite processar o conjunto de resultados uma linha de cada vez. Você pode atribuir um cursor a uma variável ou parâmetro com um tipo de dados cursor. Para obter mais informações, veja aqui.
//ISO Syntax
DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR
FOR select_statement
[ FOR { READ ONLY | UPDATE [ OF column_name [ ,...n ] ] } ]
[;]
//Transact-SQL Extended Syntax
DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ]
[ FORWARD_ONLY | SCROLL ]
[ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
[ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
[ TYPE_WARNING ]
FOR select_statement
[ FOR UPDATE [ OF column_name [ ,...n ] ] ]
[;]
FETCH
[ [ NEXT | PRIOR | FIRST | LAST
| ABSOLUTE { n | @nvar }
| RELATIVE { n | @nvar }
]
FROM
]
{ { [ GLOBAL ] cursor_name } | @cursor_variable_name }
[ INTO @variable_name [ ,...n ] ]
OPEN { { [ GLOBAL ] cursor_name } | cursor_variable_name }
CLOSE { { [ GLOBAL ] cursor_name } | cursor_variable_name }
DEALLOCATE { { [ GLOBAL ] cursor_name } | @cursor_variable_name }
Amostra de padrões da origem¶
Transact-SQL¶
Observe que os parâmetros a seguir são inerentemente suportados pelo Snowflake Scripting.
[LOCAL].
\[FORWARD_ONLY].
[FAST_FORWARD] Especifica FORWARD_ONLY (somenteFETCH NEXT) e READ_ONLY
[READ_ONLY] o WHERE CURRENT OF não existe no Snowflake Scripting.
CREATE TABLE vEmployee (
PersonID INT,
LastName VARCHAR(255),
FirstName VARCHAR(255),
);
INSERT INTO vEmployee(PersonID, LastName, FirstName)
VALUES
(1, 'AA', 'A'),
(2, 'BB', 'B'),
(3, 'CC', 'C'),
(4, 'DD', 'D'),
(5, 'EE', 'E'),
(6, 'FF', 'F'),
(7, 'GG', 'G');
CREATE OR ALTER PROCEDURE CursorExample
AS
DECLARE
@CursorVar CURSOR,
@firstName VARCHAR;
SET @CursorVar = CURSOR LOCAL FORWARD_ONLY STATIC READ_ONLY
FOR
SELECT FirstName
FROM vEmployee;
OPEN @CursorVar;
FETCH NEXT FROM @CursorVar INTO @firstName;
FETCH NEXT FROM @CursorVar INTO @firstName;
CLOSE @CursorVar;
SELECT @firstName;
GO
B
Script Snowflake¶
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":"transact"}}'
;
INSERT INTO vEmployee (PersonID, LastName, FirstName)
VALUES
(1, 'AA', 'A'),
(2, 'BB', 'B'),
(3, 'CC', 'C'),
(4, 'DD', 'D'),
(5, 'EE', 'E'),
(6, 'FF', 'F'),
(7, 'GG', 'G');
CREATE OR REPLACE PROCEDURE CursorExample ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
CURSORVAR CURSOR
FOR
SELECT FirstName
FROM vEmployee;
FIRSTNAME VARCHAR;
ProcedureResultSet RESULTSET;
BEGIN
OPEN CURSORVAR;
FETCH
CURSORVAR
INTO
:FIRSTNAME;
FETCH
CURSORVAR
INTO
:FIRSTNAME;
CLOSE CURSORVAR;
ProcedureResultSet := (
SELECT
:FIRSTNAME);
RETURN TABLE(ProcedureResultSet);
END;
$$;
B
Problemas conhecidos¶
Não há suporte para os seguintes parâmetros:
DECLARE CURSOR
[ GLOBAL ] Permite fazer referência ao nome do cursor em qualquer procedimento armazenado ou lote executado pela conexão. O Snowflake Scripting só permite o uso do cursor localmente.
[ SCROLL ] O Snowflake Scripting suporta apenas FETCH NEXT.
[ KEYSET | DYNAMIC ] Se, após a abertura de um cursor, for feita uma atualização na tabela, essas opções poderão exibir algumas das alterações ao buscar o cursor. O Snowflake Scripting suporta apenas STATIC, ou seja, após a abertura do cursor, as alterações na tabela não são detectadas pelo cursor.
[SCROLL_LOCKS] Especifica que as atualizações ou exclusões posicionadas feitas por meio do cursor têm garantia de êxito; o Snowflake Scripting não pode garantir isso.
[OPTIMISTIC] Quando uma atualização ou exclusão é feita por meio do cursor, ele usa comparações de valores da coluna de carimbo de data/hora ou um valor de soma de verificação, se a tabela não tiver coluna de carimbo de data/hora, para determinar se a linha foi modificada depois de ter sido lida no cursor. O Snowflake Scripting não tem um processo interno para replicá-lo.
[TYPE_WARNING]
FETCH
[PRIOR | FIRST | LAST] O Snowscripting suporta apenas NEXT.
[ABSOLUTE] O Snowflake Scripting suporta apenas NEXT, mas o comportamento pode ser replicado.
[RELATIVE] Snowflake Scripting, mas o comportamento pode ser replicado.
[ GLOBAL ] Permite fazer referência ao nome do cursor em qualquer procedimento armazenado ou lote executado pela conexão. O Snowflake Scripting só permite o uso do cursor localmente.
FETCH sem INTO não é compatível.
Quando a instrução FETCH está localizada dentro de um loop, ela é considerada um padrão complexo, pois pode ter um impacto no desempenho do código convertido pelo Snowflake. Consulte a seção de problemas relacionados para obter mais informações.
Buscar amostra dentro do loop¶
CREATE OR ALTER PROCEDURE cursor_procedure1
AS
BEGIN
DECLARE cursor1 CURSOR FOR SELECT col1 FROM my_table;
WHILE 1=0
BEGIN
FETCH NEXT FROM @cursor1 INTO @variable1;
END
END;
CREATE OR REPLACE PROCEDURE cursor_procedure1 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
--** SSC-FDM-TS0013 - SNOWFLAKE SCRIPTING CURSOR ROWS ARE NOT MODIFIABLE **
cursor1 CURSOR
FOR
SELECT
col1
FROM
my_table;
BEGIN
WHILE (1=0) LOOP
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
FETCH
CURSOR1
INTO
:VARIABLE1;
END LOOP;
END;
$$;
OPEN
[ GLOBAL ] Permite fazer referência ao nome do cursor em qualquer procedimento armazenado ou lote executado pela conexão. O Snowflake Scripting só permite o uso do cursor localmente.
CLOSE
[ GLOBAL ] Permite fazer referência ao nome do cursor em qualquer procedimento armazenado ou lote executado pela conexão. O Snowflake Scripting só permite o uso do cursor localmente.
DEALLOCATED Remove uma referência de cursor e não há equivalente no Snowflake Scripting.
WHERE CURRENT OF o uso dessa instrução não é suportado, por exemplo:
CREATE OR ALTER PROCEDURE CursorWithCurrent
AS
DECLARE
@CursorVar CURSOR;
SET @CursorVar = CURSOR
FOR
SELECT FirstName
FROM vEmployee;
OPEN @CursorVar;
FETCH NEXT FROM @CursorVar;
FETCH NEXT FROM @CursorVar;
UPDATE vEmployee SET LastName = 'Changed' WHERE CURRENT OF @CursorVar;
CLOSE @CursorVar;
GO
Variáveis de ambiente
@@CURSOR_ROWS
@@FETCH_STATUS
EWIs relacionados¶
SSC-FDM-TS0013: As linhas de cursor do Snowflake Scripting não podem ser modificadas.
SSC-PRF-0003: A busca dentro de um loop é considerada um padrão complexo, o que pode prejudicar o desempenho do Snowflake.
DECLARE¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Descrição¶
A instrução Transact-SQL DECLARE permite a criação de variáveis que podem ser usadas no escopo do lote ou de um procedimento armazenado. Para obter mais informações sobre Transact-SQL DECLARE, veja aqui.
-- Syntax for SQL Server and Azure SQL Database
DECLARE
{
{ @local_variable [AS] data_type [ = value ] }
| { @cursor_variable_name CURSOR }
} [,...n]
| { @table_variable_name [AS] <table_type_definition> }
<table_type_definition> ::=
TABLE ( { <column_definition> | <table_constraint> } [ ,...n] )
<column_definition> ::=
column_name { scalar_data_type | AS computed_column_expression }
[ COLLATE collation_name ]
[ [ DEFAULT constant_expression ] | IDENTITY [ (seed ,increment ) ] ]
[ ROWGUIDCOL ]
[ <column_constraint> ]
<column_constraint> ::=
{ [ NULL | NOT NULL ]
| [ PRIMARY KEY | UNIQUE ]
| CHECK ( logical_expression )
| WITH ( <index_option > )
}
<table_constraint> ::=
{ { PRIMARY KEY | UNIQUE } ( column_name [ ,...n] )
| CHECK ( search_condition )
}
Amostra de padrões da origem¶
Declarar variáveis¶
As variáveis podem ser criadas de diferentes maneiras. As variáveis podem ou não ter um valor padrão e várias variáveis podem ser declaradas na mesma linha.
Observe que o Snowflake Scripting não permite a criação de mais de uma variável por linha.
Transact-SQL¶
DECLARE @find VARCHAR(30);
DECLARE @find2 VARCHAR(30) = 'Default';
DECLARE @var VARCHAR(5), @var2 varchar(5);
Snowflake Scripting
DECLARE
FIND VARCHAR(30);
FIND2 VARCHAR(30) := 'Default';
VAR VARCHAR(5);
VAR2 VARCHAR(5);
BEGIN
RETURN '';
END;
Declarar variáveis de tabela¶
O Transact-SQL permite a criação de variáveis de tabela que podem ser usadas como tabelas regulares. O Snowflake Scripting não suporta isso; em vez disso, uma tabela pode ser criada e descartada no final do procedimento.
Transact-SQL¶
DECLARE @MyTableVar TABLE(
column1 varchar(10));
Snowflake Scripting
BEGIN
DECLARE
T_MYTABLEVAR TABLE(
column1 VARCHAR(10));
END;
Instrução DECLARE fora de rotinas (funções e procedimentos)¶
Ao contrário do Transact-SQL, o Snowflake não suporta a execução de instruções isoladas como DECLARE fora de rotinas como funções ou procedimentos. Para esse cenário, a instrução deve ser encapsulada em um bloco anônimo, conforme mostrado nos exemplos a seguir. Essa instrução geralmente é usada antes de um SET STATEMENT
.
Transact-SQL¶
DECLARE @Group nvarchar(50), @Sales MONEY;
SET @Group = N'North America';
SET @Sales = 2000000;
Snowflake Scripting
DECLARE
_GROUP VARCHAR(50);
SALES NUMBER(38, 4);
BEGIN
_GROUP := 'North America';
SALES := 2000000;
END;
Se houver um cenário com apenas instruções DECLARE, o bloco BEGIN…END deverá ter uma instrução RETURN NULL para evitar erros, pois esse bloco não pode estar vazio.
Transact-SQL¶
DECLARE @Group nvarchar(50), @Sales MONEY;
Snowflake Scripting
DECLARE
_GROUP VARCHAR(50);
SALES NUMBER(38, 4);
BEGIN
RETURN '';
END;
Problemas conhecidos¶
Não foram encontrados problemas.
EWIs relacionados¶
Sem EWIs relacionados.
EXECUTE¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Descrição¶
A instrução Transact-SQL EXECUTE permite a execução de uma cadeia de comando ou cadeia de caracteres em um lote Transact-SQL, uma função definida pelo usuário com valor escalar ou um procedimento armazenado. Para obter mais informações sobre Transact-SQL EXECUTE, veja aqui.
-- Execute a character string
{ EXEC | EXECUTE }
( { @string_variable | [ N ]'tsql_string' } [ + ...n ] )
[ AS { LOGIN | USER } = ' name ' ]
[;]
-- Execute a stored procedure or function
[ { EXEC | EXECUTE } ]
{
[ @return_status = ]
{ module_name [ ;number ] | @module_name_var }
[ [ @parameter = ] { value
| @variable [ OUTPUT ]
| [ DEFAULT ]
}
]
[ ,...n ]
[ WITH <execute_option> [ ,...n ] ]
}
[;]
Amostra de padrões da origem¶
Execução da cadeia de caracteres¶
EXECUTE pode ser usado para realizar operações SQL passadas diretamente como literais. No exemplo a seguir, ele é usado em um procedimento armazenado que insere um novo departamento de privacidade no banco de dados AdventureWorks2019.
Transact-SQL¶
CREATE OR ALTER PROCEDURE AddPrivacyDepartment
AS
EXECUTE ('INSERT INTO HumanResources.Department VALUES (''Privacy'', ''Executive General and Administration'', default)');
Script Snowflake¶
CREATE OR REPLACE PROCEDURE AddPrivacyDepartment ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE 'INSERT INTO HumanResources.Department VALUES ('Privacy', 'Executive General and Administration', default);';
END;
$$;
Execução do procedimento armazenado¶
EXECUTE também pode ser usado para chamar um procedimento armazenado existente. O exemplo a seguir chamará o procedimento AddPrivacyDepartment que foi criado acima. Em seguida, ele executará um SELECT para verificar se o novo departamento foi incluído com sucesso.
Transact-SQL¶
EXECUTE AddPrivacyDepartment;
SELECT DepartmentID, Name, GroupName FROM HumanResources.Department;
DepartmentID|Name |GroupName |ModifiedDate |
------------+--------------------------+------------------------------------+-----------------------+
1|Engineering |Research and Development |2008-04-30 00:00:00.000|
2|Tool Design |Research and Development |2008-04-30 00:00:00.000|
3|Sales |Sales and Marketing |2008-04-30 00:00:00.000|
4|Marketing |Sales and Marketing |2008-04-30 00:00:00.000|
5|Purchasing |Inventory Management |2008-04-30 00:00:00.000|
6|Research and Development |Research and Development |2008-04-30 00:00:00.000|
7|Production |Manufacturing |2008-04-30 00:00:00.000|
8|Production Control |Manufacturing |2008-04-30 00:00:00.000|
9|Human Resources |Executive General and Administration|2008-04-30 00:00:00.000|
10|Finance |Executive General and Administration|2008-04-30 00:00:00.000|
11|Information Services |Executive General and Administration|2008-04-30 00:00:00.000|
12|Document Control |Quality Assurance |2008-04-30 00:00:00.000|
13|Quality Assurance |Quality Assurance |2008-04-30 00:00:00.000|
14|Facilities and Maintenance|Executive General and Administration|2008-04-30 00:00:00.000|
15|Shipping and Receiving |Inventory Management |2008-04-30 00:00:00.000|
16|Executive |Executive General and Administration|2008-04-30 00:00:00.000|
17|Privacy |Executive General and Administration|2021-11-17 12:42:54.640|
Script Snowflake¶
CALL AddPrivacyDepartment();
SELECT
DepartmentID,
Name,
GroupName
FROM
HumanResources.Department;
DEPARTMENTID|NAME |GROUPNAME |MODIFIEDDATE |
------------+--------------------------+------------------------------------+-----------------------+
1|Engineering |Research and Development |2021-11-17 10:29:36.963|
2|Tool Design |Research and Development |2021-11-17 10:29:37.463|
3|Sales |Sales and Marketing |2021-11-17 10:29:38.192|
4|Marketing |Sales and Marketing |2021-11-17 10:29:38.733|
5|Purchasing |Inventory Management |2021-11-17 10:29:39.298|
6|Research and Development |Research and Development |2021-11-17 10:31:53.770|
7|Production |Manufacturing |2021-11-17 10:31:55.082|
8|Production Control |Manufacturing |2021-11-17 10:31:56.638|
9|Human Resources |Executive General and Administration|2021-11-17 10:31:57.507|
10|Finance |Executive General and Administration|2021-11-17 10:31:58.473|
11|Information Services |Executive General and Administration|2021-11-17 10:34:35.200|
12|Document Control |Quality Assurance |2021-11-17 10:34:35.741|
13|Quality Assurance |Quality Assurance |2021-11-17 10:34:36.277|
14|Facilities and Maintenance|Executive General and Administration|2021-11-17 10:34:36.832|
15|Shipping and Receiving |Inventory Management |2021-11-17 10:34:37.373|
16|Executive |Executive General and Administration|2021-11-17 10:34:37.918|
17|Privacy |Executive General and Administration|2021-11-17 10:46:43.345|
Execução de variável local e uso de parâmetros¶
Um caso de uso comum para a instrução EXECUTE é quando são necessárias instruções SQL dinâmicas. Nesses casos, em vez de executar um literal de cadeia de caracteres, a instrução pode ser construída dinamicamente e atribuída a uma variável local, que será então executada. Um conjunto de argumentos pode ser enviado para o procedimento armazenado chamado para construir o comando dinâmico SQL.
No exemplo a seguir, é criado um procedimento armazenado SetNewPrice simples, que usa a instrução EXECUTE para definir um novo preço de produto com base nos argumentos enviados pelo chamador. Por fim, é realizado um SELECT para confirmar o novo preço do produto.
Transact-SQL¶
CREATE OR ALTER PROCEDURE SetNewPrice @ProductID INT, @NewPrice MONEY
AS
DECLARE @dynSqlStatement AS VARCHAR(300);
SET @dynSqlStatement = 'UPDATE Production.ProductListPriceHistory SET ListPrice = ' + CAST(@NewPrice AS VARCHAR(10)) + ' WHERE ProductID = ' + CAST(@ProductID AS VARCHAR(10)) + ' AND EndDate IS NULL';
EXECUTE (@dynSqlStatement);
GO
EXECUTE Set_New_Price @ProductID = 707, @NewPrice = 34.99;
SELECT ListPrice FROM Production.ProductListPriceHistory WHERE ProductID = 707 AND EndDate IS NULL;
ListPrice|
---------+
34.9900|
Script Snowflake¶
CREATE OR REPLACE PROCEDURE SetNewPrice (PRODUCTID INT, NEWPRICE NUMBER(38, 4))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
DYNSQLSTATEMENT VARCHAR(300);
BEGIN
DYNSQLSTATEMENT := 'UPDATE Production.ProductListPriceHistory
SET
ListPrice = ' || CAST(:NEWPRICE AS VARCHAR(10)) || '
WHERE
ProductID = ' || CAST(:PRODUCTID AS VARCHAR(10)) || '
AND EndDate IS NULL;';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE :DYNSQLSTATEMENT;
END;
$$;
CALL Set_New_Price(707, 34.99);
SELECT
ListPrice
FROM
Production.ProductListPriceHistory
WHERE
ProductID = 707 AND EndDate IS NULL;
LISTPRICE|
---------+
34.9900|
Problemas conhecidos¶
Uso de códigos de retorno¶
A sintaxe do Transact-SQL EXECUTE contém o argumento opcional @return_status, que permite criar uma variável escalar para armazenar o status de retorno de uma função definida pelo usuário com valor escalar.
Ele também pode ser usado em procedimentos armazenados, embora o status de retorno seja limitado ao tipo de dados inteiro.
Para representar essa funcionalidade, poderíamos modificar um pouco o exemplo acima e criar uma função definida pelo usuário para calcular o preço do novo produto como uma média dos preços históricos. Em vez de passá-lo para o procedimento armazenado, poderíamos agora chamar a função CalculateAveragePrice para obter o novo preço e armazená-lo na variável de retorno para construir o SQL dinâmico.
Transact-SQL¶
CREATE OR ALTER FUNCTION CalculateAveragePrice(@pid INT)
RETURNS MONEY
AS
BEGIN
DECLARE @average AS MONEY;
SELECT @average = AVG(LISTPRICE) FROM Production.ProductListPriceHistory WHERE ProductID = @pid;
RETURN @average;
END;
GO
CREATE OR ALTER PROCEDURE SetNewPrice @ProductID INT
AS
DECLARE @averageHistoricalPrice MONEY;
EXECUTE @averageHistoricalPrice = [dbo].Calculate_Average_Price @pid=@ProductID;
UPDATE Production.ProductListPriceHistory SET ListPrice = @averageHistoricalPrice WHERE ProductID = @ProductID AND EndDate IS NULL;
GO
EXECUTE Set_New_Price @ProductID = 707;
SELECT ListPrice FROM Production.ProductListPriceHistory WHERE ProductID = 707 AND EndDate IS NULL;
ListPrice|
---------+
34.0928|
Script Snowflake¶
CREATE OR REPLACE FUNCTION CalculateAveragePrice (PID INT)
RETURNS NUMBER(38, 4)
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
AS
$$
WITH CTE1 AS
(
SELECT
AVG(LISTPRICE) AS AVERAGE FROM
Production.ProductListPriceHistory
WHERE
ProductID = PID
)
SELECT
AVERAGE
FROM
CTE1
$$;
CREATE OR REPLACE PROCEDURE SetNewPrice (PRODUCTID INT)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
AVERAGEHISTORICALPRICE NUMBER(38, 4);
BEGIN
CALL dbo.Calculate_Average_Price(:PRODUCTID);
UPDATE Production.ProductListPriceHistory
SET
ListPrice = :AVERAGEHISTORICALPRICE
WHERE
ProductID = :PRODUCTID
AND EndDate IS NULL;
END;
$$;
CALL Set_New_Price(707);
SELECT
ListPrice
FROM
Production.ProductListPriceHistory
WHERE
ProductID = 707 AND EndDate IS NULL;
Argumentos opcionais não suportados¶
@return_status
;number
@module__name_v_ar
WITH RECOMPILE, WITH RESULT SETS NONE, WITH <definição do conjunto de resultados>
EWIs relacionados¶
SSC-EWI-0030: A instrução abaixo tem usos de SQL dinâmico.
IF¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Descrição ¶
A cláusula IF permite que uma instrução SQL ou um bloco de instruções seja executado condicionalmente, desde que a expressão booliana seja verdadeira; caso contrário, as instruções da cláusula opcional ELSE serão executadas. O Transact-SQL também suporta a incorporação de várias cláusulas IF… ELSE caso sejam necessárias várias condições, ou a cláusula CASE também pode ser usada.
Para obter mais informações sobre o Transact-SQL IF…ELSE, veja aqui.
IF Boolean_expression
{ sql_statement | statement_block }
[ ELSE
{ sql_statement | statement_block } ]
Observação: para definir um bloco de instruções, use as palavras-chave de controle de fluxo BEGIN
e END
.
Amostra de padrões de origem ¶
Transact-SQL¶
O código a seguir refere-se a um IF… ELSE no Transact-SQL que condiciona a variável @value para identificar se ela é menor que 5, se está entre 5 e 10 ou se tem qualquer outro valor. Como @value é inicializado como 7, a segunda condição deve ser verdadeira e o resultado deve ser 200.
CREATE OR ALTER PROCEDURE IfElseDemoProcedure
AS
DECLARE @value INT;
SET @value = 7;
IF @value < 5
SET @value = 100;
ELSE IF @value >= 5 AND @value < 10
BEGIN
SET @value = 300;
SET @value = @value - 100;
END;
ELSE
SET @value = -1;
RETURN @value
GO
DECLARE @result INT;
EXEC @result = IfElseDemoProcedure;
PRINT @result;
|result|
|------|
|200 |
Snowflake Scripting ¶
Nota
Observe que, no Snowflake Scripting, a condição incorporada IF… ELSE é chamada de ELSEIF.
Além disso, a condição booliana é encapsulada entre parênteses, e a cláusula sempre termina com a expressão END IF.
Além disso, no Snowflake Scripting, não é necessário usar as palavras-chave BEGIN e END para definir um bloco de instruções, mas elas podem ser usadas se necessário.
CREATE OR REPLACE PROCEDURE IfElseDemoProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
VALUE INT;
BEGIN
VALUE := 7;
IF (:VALUE < 5) THEN
VALUE := 100;
ELSEIF (:VALUE >= 5 AND :VALUE < 10) THEN
BEGIN
VALUE := 300;
VALUE := :VALUE - 100;
END;
ELSE
VALUE := -1;
END IF;
RETURN :VALUE;
END;
$$;
DECLARE
RESULT INT;
BEGIN
CALL IfElseDemoProcedure();
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Print' NODE ***/!!!
PRINT @result;
END;
|result|
|------|
|200 |
Instrução IF fora de rotinas (funções e procedimentos)¶
Ao contrário do Transact-SQL, o Snowflake não suporta a execução de instruções isoladas como IF…ELSE fora de rotinas como funções ou procedimentos. Para esse cenário, a instrução deve ser encapsulada em um bloco anônimo, conforme mostrado no exemplo a seguir. Você pode ler mais sobre como retornar corretamente os valores de saída na seção SELECT.
Transact-SQL¶
DECLARE @maxWeight FLOAT, @productKey INTEGER
SET @maxWeight = 100.00
SET @productKey = 424
IF @maxWeight <= 99
SELECT @productKey, 'This product is too heavy to ship and is only available for pickup.'
ELSE
SELECT @productKey, 'This product is available for shipping or pickup.'
Snowflake Scripting
DECLARE
MAXWEIGHT FLOAT;
PRODUCTKEY INTEGER;
BlockResultSet1 VARCHAR;
BlockResultSet2 VARCHAR;
return_arr ARRAY := array_construct();
BEGIN
MAXWEIGHT := 100.00;
PRODUCTKEY := 424;
IF (:MAXWEIGHT <= 99) THEN
BlockResultSet1 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:BlockResultSet1) AS
SELECT
:PRODUCTKEY, 'This product is too heavy to ship and is only available for pickup.';
return_arr := array_append(return_arr, :BlockResultSet1);
ELSE
BlockResultSet2 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:BlockResultSet2) AS
SELECT
:PRODUCTKEY, 'This product is available for shipping or pickup.';
return_arr := array_append(return_arr, :BlockResultSet2);
END IF;
--** SSC-FDM-0020 - MULTIPLE RESULT SETS ARE RETURNED IN TEMPORARY TABLES **
RETURN return_arr;
END;
Problemas conhecidos¶
Não foram encontrados problemas.
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.
LABEL e GOTO¶
Applies to
[x] SQL Server
Descrição¶
O Snowflake SQL não é compatível com instruções GOTO LABEL. Atualmente, LABELS é comentado e um aviso é adicionado a todas as ocorrências.
Amostra de padrões de origem ¶
Os exemplos a seguir detalham as instruções de transação BEGIN e COMMIT.
Transact-SQL ¶
CREATE PROCEDURE GoToProcedure
AS
BEGIN
DECLARE @TotalMaarks INT
SET @TotalMaarks = 49;
IF @TotalMaarks >= 50
GOTO Pass
IF @TotalMaarks < 50
GOTO Fail
Pass:
SELECT 1;
RETURN 1;
Fail:
SELECT 2;
RETURN 2;
END
Snowflake SQL ¶
CREATE OR REPLACE PROCEDURE GoToProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
TOTALMAARKS INT;
BEGIN
TOTALMAARKS := 49;
IF (:TOTALMAARKS >= 50) THEN
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'GOTO' NODE ***/!!!
GOTO Pass
END IF;
IF (:TOTALMAARKS < 50) THEN
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'GOTO' NODE ***/!!!
GOTO Fail
END IF;
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0045 - LABELED STATEMENT IS NOT SUPPORTED IN SNOWFLAKE SCRIPTING ***/!!!
Pass:
SELECT 1;
RETURN 1;
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0045 - LABELED STATEMENT IS NOT SUPPORTED IN SNOWFLAKE SCRIPTING ***/!!!
Fail:
SELECT 2;
RETURN 2;
END;
$$;
Instrução LABEL e GOTO fora das rotinas (funções e procedimentos)¶
Transact-SQL
CREATE TABLE T12(COL1 INT);
GOTO SecondStat
FirstStat:
INSERT INTO T12 VALUES (1);
SecondStat:
INSERT INTO T12 VALUES (2);
Snowflake Scripting
BEGIN
CREATE OR REPLACE TABLE T12 (
COL1 INT
);
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Goto' NODE ***/!!!
GOTO SecondStat;
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0045 - LABELED STATEMENT IS NOT SUPPORTED IN SNOWFLAKE SCRIPTING ***/!!!
FirstStat:
INSERT INTO T12 VALUES (1);
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0045 - LABELED STATEMENT IS NOT SUPPORTED IN SNOWFLAKE SCRIPTING ***/!!!
SecondStat:
INSERT INTO T12 VALUES (2);
END;
Problemas conhecidos¶
Não foram encontrados problemas.
EWIs relacionados¶
SSC-EWI-TS0045: A instrução Labeled não é compatível com o Snowflake Scripting.
SSC-EWI-0073: Revisão de equivalência funcional pendente.
OUTPUT PARAMETERS¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
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 o bloco de chamada SQL. 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¶
Parâmetro OUT único¶
O cenário mais básico para parâmetros OUT é quando o procedimento tem apenas um. Nesse caso, simplesmente retornamos o parâmetro OUT no final do corpo do procedimento.
O procedimento EXEC também precisa ser convertido. Para isso, é criado um CALL, os parâmetros são passados sem nenhum modificador («OUT» é removido) e, posteriormente, é feita uma atribuição para que o parâmetro seja associado ao respectivo valor resultante.
Transact-SQL¶
-- Procedure with output parameter
CREATE PROCEDURE dbo.outmain
@name VARCHAR (255) OUTPUT
AS
SET @name = 'Jane';
-- Auxiliary procedure that calls the main procedure
CREATE PROCEDURE dbo.outaux
AS
DECLARE @name VARCHAR (255);
EXEC dbo.outmain
@name = @name OUTPUT;
Script Snowflake¶
-- Procedure with output parameter
CREATE OR REPLACE PROCEDURE dbo.outmain (NAME STRING)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
NAME := 'Jane';
-- Auxiliary procedure that calls the main procedure
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'CREATE PROCEDURE' NODE ***/!!!
CREATE PROCEDURE dbo.outaux
AS
DECLARE @name VARCHAR (255);
EXEC dbo.outmain
@name = @name OUTPUT;
RETURN NAME;
END;
$$;
Múltiplos parâmetros OUT¶
Quando mais de um parâmetro OUT é encontrado, a cláusula RETURNS do procedimento muda para VARIANT. Isso é para acomodar o OBJECT_CONSTRUCT que será usado para armazenar os valores dos parâmetros OUT.
Além disso, uma instrução RETURN é adicionada ao final do corpo do procedimento. É aqui que o OBJECT_COSNTRUCT é criado e todos os valores de parâmetros do OUT são armazenados nele. Esse objeto será então usado pelo chamador para atribuir o valor dos parâmetros ao resultado correspondente.
Transact-SQL¶
CREATE OR ALTER PROCEDURE basicProc (
@col1 INT OUT,
@col2 VARCHAR(10) OUT
) AS
BEGIN
SET @col1 = 4;
SET @col2 = 'test';
END;
CREATE OR ALTER PROCEDURE basicProcCall AS
BEGIN
DECLARE @var1 INT = 0;
DECLARE @var2 VARCHAR(10) = 'EMPTY';
EXEC basicProc @var1 OUT, @var2 OUT;
INSERT INTO TABLE1(col1, col2) VALUES (@var1, @var2);
END;
EXEC basicProcCall;
Script Snowflake¶
CREATE OR REPLACE PROCEDURE basicProc (COL1 INT, COL2 STRING)
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
BEGIN
COL1 := 4;
COL2 := 'test';
END;
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'CREATE PROCEDURE' NODE ***/!!!
CREATE OR ALTER PROCEDURE basicProcCall AS
BEGIN
DECLARE @var1 INT = 0;
DECLARE @var2 VARCHAR(10) = 'EMPTY';
EXEC basicProc @var1 OUT, @var2 OUT;
INSERT INTO TABLE1(col1, col2) VALUES (@var1, @var2);
END;
EXEC basicProcCall;
RETURN OBJECT_CONSTRUCT('COL1', :COL1, 'COL2', :COL2);
END;
$$;
Parâmetros OUT e valores de retorno¶
O Transact-SQL permite que os procedimentos tenham valores de retorno. Quando um procedimento tem um valor de retorno e parâmetro(s) OUT, segue-se uma abordagem semelhante ao cenário Múltiplos parâmetros OUT. O valor de retorno original é tratado como um parâmetro OUT seria tratado, portanto, é armazenado dentro de OBJECT_CONSTRUCT e extraído dentro do procedimento do chamador.
Transact-SQL¶
-- Procedure with multiple output parameters
CREATE PROCEDURE dbo.outmain
@name VARCHAR (255) OUTPUT
AS
SET @name = 'Jane';
RETURN 0;
-- Auxiliary procedure that calls the main procedure
CREATE PROCEDURE dbo.outaux
AS
DECLARE @name VARCHAR (255);
DECLARE @returnValue INT;
EXEC @returnValue = dbo.outmain
@name = @name OUTPUT;
Script Snowflake¶
-- Procedure with multiple output parameters
CREATE OR REPLACE PROCEDURE dbo.outmain (NAME STRING)
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
NAME := 'Jane';
RETURN OBJECT_CONSTRUCT('SC_RET_VALUE', 0, 'NAME', :NAME);
-- Auxiliary procedure that calls the main procedure
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'CREATE PROCEDURE' NODE ***/!!!
CREATE PROCEDURE dbo.outaux
AS
DECLARE @name VARCHAR (255);
DECLARE @returnValue INT;
EXEC @returnValue = dbo.outmain
@name = @name OUTPUT;
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.
Transact-SQL¶
CREATE PROCEDURE procedure_udtype_out_params(
@p_employee_id INT,
@p_phone [dbo].[PhoneNumber] OUTPUT
) AS
BEGIN
SELECT @p_phone = phone
FROM employees
WHERE employee_id = @p_employee_id;
END;
Script Snowflake¶
CREATE OR REPLACE PROCEDURE procedure_udtype_out_params (P_EMPLOYEE_ID INT, P_PHONE VARIANT /*** SSC-FDM-TS0015 - DATA TYPE DBO.PHONENUMBER IS NOT SUPPORTED IN SNOWFLAKE ***/)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
SELECT
phone
INTO
:P_PHONE
FROM
employees
WHERE
employee_id = :P_EMPLOYEE_ID;
RETURN P_PHONE;
END;
$$;
Problemas conhecidos ¶
Não foram encontrados problemas.
EWIs relacionados¶
SSC-EWI-0073: Revisão de equivalência funcional pendente.
SSC-FDM-TS0015: O tipo de dados não é compatível com o Snowflake.
SET¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Descrição¶
Define a variável local especificada, criada anteriormente com o uso da instrução DECLARE @local_variable, com o valor especificado. Para obter mais informações sobre o Transact-SQL SET, veja aqui.
Há quatro casos de SET, que são os seguintes:
SET
{ @local_variable
[ . { property_name | field_name } ] = { expression | udt_name { . | :: } method_name }
}
|
{ @SQLCLR_local_variable.mutator_method
}
|
{ @local_variable
{+= | -= | *= | /= | %= | &= | ^= | |= } expression
}
|
{ @cursor_variable =
{ @cursor_variable | cursor_name
| { CURSOR [ FORWARD_ONLY | SCROLL ]
[ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
[ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
[ TYPE_WARNING ]
FOR select_statement
[ FOR { READ ONLY | UPDATE [ OF column_name [ ,...n ] ] } ]
}
}
}
Amostra de padrões de origem ¶
Transact-SQL¶
CREATE OR ALTER PROCEDURE SetProcedure
AS
DECLARE @MyCounter INT;
DECLARE @FloatCounter FLOAT;
--Numerical operators
SET @MyCounter = 3;
SET @MyCounter += 1; --@MyCounter has 4
SET @MyCounter -= 1; --@MyCounter has 3
SET @MyCounter *= 2; --@MyCounter has 6
SET @MyCounter /= 3; --@MyCounter has 2
SET @MyCounter = 6;
SET @MyCounter /= 5; --@MyCounter has 1
SET @MyCounter = 6;
SET @MyCounter /= 7; --@MyCounter has 0
SET @FloatCounter = 10;
SET @FloatCounter /= 4; --@FloatCounter has 2.5
SET @MyCounter = 6;
SET @MyCounter %= 4; --@MyCounter has 2
--Logical operators
SET @MyCounter &= 3; --@MyCounter has 2
SET @MyCounter ^= 2; --@MyCounter has 0
SET @MyCounter |= 0; --@MyCounter has 0
RETURN @MyCounter;
GO
DECLARE @result INT;
EXEC @result = SetProcedure;
PRINT @result;
CREATE TABLE vEmployee (
PersonID int,
LastName varchar(255),
FirstName varchar(255)
);
CREATE OR ALTER PROCEDURE SetCursor
AS
DECLARE @CursorVar CURSOR;
SET @CursorVar = CURSOR SCROLL DYNAMIC
FOR
SELECT LastName, FirstName
FROM vEmployee
WHERE LastName like 'B%';
GO
|Result |
|---------|
|0 |
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE SetProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
MYCOUNTER INT;
FLOATCOUNTER FLOAT;
BEGIN
--Numerical operators
MYCOUNTER := 3;
MYCOUNTER := MYCOUNTER + 1; --@MyCounter has 4
MYCOUNTER := MYCOUNTER - 1; --@MyCounter has 3
MYCOUNTER := MYCOUNTER * 2; --@MyCounter has 6
MYCOUNTER := TRUNC(MYCOUNTER / 3); --@MyCounter has 2
MYCOUNTER := 6;
MYCOUNTER := TRUNC(MYCOUNTER / 5); --@MyCounter has 1
MYCOUNTER := 6;
MYCOUNTER := TRUNC(MYCOUNTER / 7); --@MyCounter has 0
FLOATCOUNTER := 10;
FLOATCOUNTER := FLOATCOUNTER / 4; --@FloatCounter has 2.5
MYCOUNTER := 6;
MYCOUNTER := MYCOUNTER % 4; --@MyCounter has 2
--Logical operators
MYCOUNTER := BITAND(MYCOUNTER, 3); --@MyCounter has 2
MYCOUNTER := BITXOR(MYCOUNTER, 2); --@MyCounter has 0
MYCOUNTER := BITOR(MYCOUNTER, 0); --@MyCounter has 0
RETURN :MYCOUNTER;
END;
$$;
DECLARE
RESULT INT;
BEGIN
CALL SetProcedure();
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Print' NODE ***/!!!
PRINT @result;
END;
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":"transact"}}'
;
CREATE OR REPLACE PROCEDURE SetCursor ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0037 - SNOWFLAKE SCRIPTING CURSORS ARE NON-SCROLLABLE, ONLY FETCH NEXT IS SUPPORTED ***/!!!
--** SSC-FDM-TS0013 - SNOWFLAKE SCRIPTING CURSOR ROWS ARE NOT MODIFIABLE **
CURSORVAR CURSOR
FOR
SELECT LastName, FirstName
FROM vEmployee
WHERE LastName like 'B%';
BEGIN
RETURN '';
END;
$$;
|Result |
|---------|
|0 |
Instrução SET fora de rotinas (funções e procedimentos)¶
Ao contrário do Transact-SQL, o Snowflake não suporta a execução de instruções isoladas como SET fora de rotinas como funções ou procedimentos. Para esse cenário, a instrução deve ser encapsulada em um bloco anônimo, conforme mostrado nos exemplos a seguir. Essa instrução geralmente é usada depois de DECLARE STATEMENT.
Transact-SQL¶
DECLARE @Group nvarchar(50), @Sales MONEY;
SET @Group = N'North America';
SET @Sales = 2000000;
Snowflake Scripting
DECLARE
_GROUP VARCHAR(50);
SALES NUMBER(38, 4);
BEGIN
_GROUP := 'North America';
SALES := 2000000;
END;
Se houver um cenário com apenas instruções SET, o bloco DECLARE não será necessário. Provavelmente, esse cenário produzirá erros de tempo de execução se houver uma tentativa de definir um valor para uma variável que não foi declarada.
Transact-SQL¶
SET @Group = N'North America';
Snowflake Scripting
BEGIN
_GROUP := 'North America';
END;
Problemas conhecidos¶
1. SET of a local variable with property name¶
No momento, esse tipo de conjunto não é compatível com o Snowflake Scripting.
// TSQL custom data type with properties example
DECLARE @p Point;
SET @p.X = @p.X + 1.1;
2. SET of a local variable with mutator method¶
No momento, esse tipo de conjunto não é compatível com o Snowflake Scripting.
// TSQL custom data type with mutator method
SET @p.SetXY(22, 23);
EWIs relacionados¶
SSC-EWI-TS0037: Os cursores do Snowflake Scripting não podem ser rolados.
SSC-EWI-0073: Revisão de equivalência funcional pendente.
SSC-FDM-TS0013: As linhas de cursor do Snowflake Scripting não podem ser modificadas.
TRY CATCH¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Descrição¶
Implementa o tratamento de erros para o Transact SQL. Um grupo de instruções Transact-SQL pode ser incluído em um bloco TRY. Se ocorrer um erro no bloco TRY, o controle geralmente é passado para outro grupo de instruções que está incluído em um bloco CATCH.
Amostra de padrões de origem ¶
O exemplo a seguir detalha a transformação para TRY CATCH dentro de procedimentos.
Transact-SQL ¶
CREATE PROCEDURE ERROR_HANDLING_PROC
AS
BEGIN
BEGIN TRY
-- Generate divide-by-zero error.
SELECT 1/0;
END TRY
BEGIN CATCH
-- Execute error retrieval routine.
SELECT 'error';
END CATCH;
END;
|error |
Snowflake SQL ¶
CREATE OR REPLACE PROCEDURE ERROR_HANDLING_PROC ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
BEGIN
-- Generate divide-by-zero error.
SELECT
TRUNC( 1/0);
EXCEPTION
WHEN OTHER THEN
-- Execute error retrieval routine.
SELECT 'error';
END;
END;
$$;
|error |
Tentar capturar rotinas externas (funções e procedimentos)¶
Transact-SQL
BEGIN TRY
SELECT 1/0;
END TRY
BEGIN CATCH
SELECT 'error';
END CATCH;
Snowflake Scripting
DECLARE
BlockResultSet1 VARCHAR;
BlockResultSet2 VARCHAR;
return_arr ARRAY := array_construct();
BEGIN
BEGIN
BlockResultSet1 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:BlockResultSet1) AS
SELECT
TRUNC( 1/0);
return_arr := array_append(return_arr, :BlockResultSet1);
EXCEPTION
WHEN OTHER THEN
BlockResultSet2 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:BlockResultSet2) AS
SELECT 'error';
return_arr := array_append(return_arr, :BlockResultSet2);
END;
--** SSC-FDM-0020 - MULTIPLE RESULT SETS ARE RETURNED IN TEMPORARY TABLES **
RETURN return_arr;
END;
Problemas conhecidos¶
Não foram encontrados problemas.
EWIs relacionados¶
SSC-FDM-0020: Vários conjuntos de resultados são retornados em tabelas temporárias.
WHILE¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Descrição ¶
O comando While permite que uma instrução SQL ou um bloco de comandos seja executado repetidamente, desde que a condição especificada seja verdadeira. A execução das instruções no loop WHILE pode ser controlada de dentro do loop com as palavras-chave BREAK
e CONTINUE
.
Para obter mais informações sobre o Transact-SQL While, veja aqui.
WHILE Boolean_expression
{ sql_statement | statement_block | BREAK | CONTINUE }
Observação: para definir um bloco de instruções, use as palavras-chave de controle de fluxo BEGIN
e END
.
Amostra de padrões de origem ¶
Código padrão de origem básico¶
Transact-SQL ¶
O código a seguir refere-se a um While Loop no Transact-SQL que itera a variável @Iteration e controla o fluxo do loop para encerrar quando o valor de @Iteration for igual a 10.
Nota
As instruções após a palavra-chave CONTINUE
não serão executadas.
CREATE OR ALTER PROCEDURE WhileDemoProcedure
AS
DECLARE @iteration INT;
SET @iteration = 1;
WHILE @iteration < 100
BEGIN
IF @iteration = 10
BREAK;
ELSE
BEGIN
SET @iteration = @iteration + 1;
CONTINUE;
SET @iteration = 2 * @iteration;
END;
END;
RETURN @iteration;
GO
DECLARE @result INT;
EXEC @result = WhileDemoProcedure;
PRINT @result;
|iteration|
|---------|
|10 |
Snowflake Scripting ¶
Nota
Assim como no Transact-SQL, no Snowflake Scripting as instruções após a palavra-chave CONTINUE
não serão executadas.
Observe que, no Snowflake Scripting, não é necessário usar as palavras-chave BEGIN e END para definir um bloco de instruções, mas isso pode ser usado se necessário.
CREATE OR REPLACE PROCEDURE WhileDemoProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
ITERATION INT;
BEGIN
ITERATION := 1;
WHILE (:ITERATION < 100) LOOP
IF (:ITERATION = 10) THEN
BREAK;
ELSE
BEGIN
ITERATION := :ITERATION + 1;
CONTINUE;
ITERATION := 2 * :ITERATION;
END;
END IF;
END LOOP;
RETURN :ITERATION;
END;
$$;
DECLARE
RESULT INT;
BEGIN
CALL WhileDemoProcedure();
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Print' NODE ***/!!!
PRINT @result;
END;
O Snowflake Scripting permite usar a palavra-chave LOOP
em vez de DO
e a expressão END LOOP
em vez de END WHILE
.
WHILE (Boolean_expression) LOOP
-- statement or statement block
END LOOP;
|Iteration|
|---------|
|10 |
While com padrão de origem de corpo vazio¶
Transact-SQL ¶
Nota
Observe que este exemplo foi escrito quando não havia suporte para a instrução IF ELSE. As diferenças nos resultados devem desaparecer quando o suporte para a instrução for implementado.
CREATE OR ALTER PROCEDURE WhileEmptyBodyProc
AS
BEGIN
DECLARE @MyVar INT;
SET @MyVar = 1;
WHILE (@MyVar < 100)
BEGIN
IF @MyVar < 50
SET @MyVar *= 5;
ELSE
SET @MyVar *= 3;
END;
RETURN @MyVar;
END;
DECLARE @result INT;
EXEC @result = WhileEmptyBodyProc;
PRINT @result;
|result|
|------|
|125 |
Script Snowflake¶
Esse comando não pode ter um corpo vazio no Snowflake Scripting. Para resolver esse caso, um comando BREAK padrão é adicionado quando um corpo vazio é detectado.
CREATE OR REPLACE PROCEDURE WhileEmptyBodyProc ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
MYVAR INT;
RESULT INT;
BEGIN
BEGIN
MYVAR := 1;
WHILE (:MYVAR < 100) LOOP
IF (:MYVAR < 50) THEN
MYVAR := MYVAR * 5;
ELSE
MYVAR := MYVAR * 3;
END IF;
END LOOP;
RETURN :MYVAR;
END;
CALL WhileEmptyBodyProc();
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'PRINT' NODE ***/!!!
PRINT @result;
END;
$$;
|result|
|------|
|1 |
Instrução WHILE fora de rotinas (funções e procedimentos)¶
Ao contrário do Transact-SQL, o Snowflake não suporta a execução de instruções isoladas como WHILE fora de rotinas como funções ou procedimentos. Para esse cenário, a instrução deve ser encapsulada em um bloco anônimo, conforme mostrado no exemplo a seguir.
Transact-SQL ¶
DECLARE @iteration INT;
SET @iteration = 1;
WHILE @iteration < 100
BEGIN
IF @iteration = 10
BREAK;
ELSE
BEGIN
SET @iteration = @iteration + 1;
CONTINUE;
SET @iteration = 2 * @iteration;
END;
END;
Snowflake Scripting
DECLARE
ITERATION INT;
BEGIN
ITERATION := 1;
WHILE (:ITERATION < 100) LOOP
IF (:ITERATION = 10) THEN
BREAK;
ELSE
BEGIN
ITERATION := :ITERATION + 1;
CONTINUE;
ITERATION := 2 * :ITERATION;
END;
END IF;
END LOOP;
END;
Problemas conhecidos¶
Não foram encontrados problemas.
EWIs relacionados¶
SSC-EWI-0073: Revisão de equivalência funcional pendente.