SnowConvert AI - Servidor SQL - Azure Synapse - Elementos gerais de linguagem¶
Nesta seção você encontra informações sobre instruções gerais do Transect-SQL.
COLLATE¶
Applies to
SQL Server
Azure Synapse Analytics
A transformação de Collate depende de seu valor, pois pode ser compatível ou não.
Atualmente, estes são os idiomas suportados na transformação; se forem encontrados em Collate, serão transformados em seu equivalente no Snowflake.
SqlSever |
Snowflake |
|---|---|
Latin1_General |
EN |
Modern_Spanish |
ES |
Francês |
FR |
Se o idioma não for um dos mencionados acima, Collate será comentado.
Além disso, como Collate no SqlServer vem com especificações adicionais, como CI, CS, AI, e AS, somente essas são compatíveis; se houver mais e não forem compatíveis, elas serão comentadas no resultado.
Fonte¶
SELECT 'a' COLLATE Latin1_General_CI_AS;
SELECT 'a' COLLATE Modern_Spanish_CI_AS;
SELECT 'a' COLLATE French_CI_AS;
SELECT 'a' COLLATE Albanian_BIN;
SELECT 'a' COLLATE Latin1_General_CI_AS_WS;
SELECT 'a' COLLATE Latin1_General_CI_AS_KS_WS;
SELECT 'a' COLLATE Albanian_CI_AI;
Esperado¶
SELECT 'a' COLLATE 'EN-CI-AS';
SELECT 'a' COLLATE 'ES-CI-AS';
SELECT 'a' COLLATE 'FR-CI-AS';
SELECT 'a'
-- !!!RESOLVE EWI!!! /*** SSC-EWI-TS0077 - COLLATION Albanian_BIN NOT SUPPORTED ***/!!!
-- COLLATE Albanian_BIN
;
SELECT 'a' COLLATE 'EN-CI-AS' /*** SSC-FDM-TS0002 - COLLATION FOR VALUE WS NOT SUPPORTED ***/;
SELECT 'a' COLLATE 'EN-CI-AS' /*** SSC-FDM-TS0002 - COLLATION FOR VALUES KS,WS NOT SUPPORTED ***/;
SELECT 'a'
-- !!!RESOLVE EWI!!! /*** SSC-EWI-TS0077 - COLLATION Albanian_CI_AI NOT SUPPORTED ***/!!!
-- COLLATE Albanian_CI_AI
;
Vejamos um exemplo de Collate em Create Table
Fonte¶
CREATE TABLE TABLECOLLATE
(
COL1 VARCHAR COLLATE Latin1_General_CI_AS
);
Esperado¶
CREATE OR REPLACE TABLE TABLECOLLATE
(
COL1 VARCHAR COLLATE 'EN-CI-AS' /*** SSC-PRF-0002 - CASE INSENSITIVE COLUMNS CAN DECREASE THE PERFORMANCE OF QUERIES ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
;
Como você pode ver, a transformação de Collate dentro de Select ou Table é a mesma.
COMPUTED COLUMN¶
Não foi possível transformar a expressão computada.
Applies to
SQL Server
Azure Synapse Analytics
Descrição¶
A expressão de uma coluna computada não pôde ser transformada.
Exemplo de código¶
Código de entrada:¶
CREATE TABLE [TestTable](
[Col1] AS (CONVERT ([REAL], ExpressionValue))
);
Código de saída:¶
CREATE OR REPLACE TABLE TestTable (
Col1 REAL AS (CAST(ExpressionValue AS REAL)) /*** SSC-FDM-TS0014 - COMPUTED COLUMN WAS TRANSFORMED TO ITS SNOWFLAKE EQUIVALENT, FUNCTIONAL EQUIVALENCE VERIFICATION PENDING. ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
;
Recomendações¶
Adicione alterações manuais à expressão não transformada.
Se precisar de mais suporte, envie um e-mail para snowconvert-support@snowflake.com
EWIs relacionados¶
SSC-FDM-TS0014: Coluna computada transformada.
OUTER APPLY¶
Tradutor de equivalência de instrução de aplicação externa.
Applies to
SQL Server
Azure Synapse Analytics
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Descrição¶
Quando OUTER APPLY é especificado, uma linha é produzida para cada linha do conjunto de linhas à esquerda, mesmo quando a expressão do conjunto de linhas à direita retorna um conjunto de linhas vazio para essa linha. (Definição de OUTER APPLY)
Sintaxe¶
Apply_Operator :=
'CROSS' 'APPLY'
| 'OUTER' 'APPLY'.
Equivalência no Snowflake¶
Apesar da instrução sem suporte OUTER APPLY no Snowflake, há uma instrução equivalente, que é LATERAL. Portanto, a conversão da instrução é realizada para obter a mesma funcionalidade por meio do uso de soluções alternativas.
No entanto, a instrução LATERAL no Snowflake tem duas variações de sintaxe. Na verdade, a variação INNER JOIN LATERAL é usada nessa conversão específica.
A gramática de INNER JOIN LATERAL do Snowflake é a seguinte:
SELECT ...
FROM <left_hand_table_expression> INNER JOIN LATERAL ( <inline_view> )
...
Nota
_<inline\view> não pode ser um nome de tabela.
E a única instrução LATERAL é mostrada abaixo:
SELECT ...
FROM <left_hand_table_expression>, LATERAL ( <inline_view> )
...
Amostra de origem¶
O exemplo a seguir mostra uma conversão geral entre OUTER APPLY e INNER JOIN LATERAL:
SQL Server¶
SELECT p.ProjectName, e.ProjectName, e.FirstName
FROM Project p
OUTER APPLY (
SELECT
ProjectName,
FirstName,
LastName
FROM Employees e
) e;
Saída¶
p.ProjectName |
e.ProjectName |
FirstName |
|---|---|---|
Projeto A |
Projeto A |
John |
Projeto A |
Projeto A |
Jane |
Projeto A |
Projeto B |
Michael |
Projeto B |
Projeto A |
John |
Projeto B |
Projeto A |
Jane |
Projeto B |
Projeto B |
Michael |
Projeto C |
Projeto A |
John |
Projeto C |
Projeto A |
Jane |
Projeto C |
Projeto B |
Michael |
Snowflake¶
SELECT
p.ProjectName,
e.ProjectName,
e.FirstName
FROM
Project p
INNER JOIN
LATERAL (
SELECT
ProjectName,
FirstName,
LastName
FROM
Employees e
) e;
Saída¶
PROJECTNAME |
PROJECTNAME_2 |
FIRSTNAME |
|---|---|---|
Projeto A |
Projeto A |
John |
Projeto A |
Projeto A |
Jane |
Projeto A |
Projeto B |
Michael |
Projeto B |
Projeto A |
John |
Projeto B |
Projeto A |
Jane |
Projeto B |
Projeto B |
Michael |
Projeto C |
Projeto A |
John |
Projeto C |
Projeto A |
Jane |
Projeto C |
Projeto B |
Michael |
Problemas conhecidos¶
Como a conversão é uma equivalência da entrada, há algumas limitações.
As instruções TOP e WHERE podem ser revisadas para otimizar o comportamento.
Pode ser necessário um nome de correlação no final da instrução. No Snowflake, a consulta não representa um problema se o nome da correlação não estiver na consulta, mas a funcionalidade pode mudar e não faz parte do padrão aceito no SQL Server.
SQL Server¶
SELECT
SATT.UNIVERSAL_NAME
FROM
SAMPLE_ATLAS AS SATT
OUTER APPLY (
SELECT
TOP 1 UNIVERSAL_NAME,
INTERNATIONAL_NAME,
CODE_IDENTIFIER
FROM
SAMPLE_GLOBE AS SG
WHERE
SG.GLOBE_KEY = SATT.MbrPersGenKey
ORDER BY
GLOBE_KEY
);
Saída da tradução¶
SELECT
UNIVERSAL_NAME
FROM
SAMPLE_ATLAS
AS SATT
OUTER APPLY
/*** MSC-ERROR - MSCCP0001 - THE FOLLOWING SUBQUERY MATCHES AT LEAST ONE OF THE PATTERNS CONSIDERED INVALID AND MAY PRODUCE COMPILATION ERRORS ***/ (SELECT TOP 1
UNIVERSAL_NAME,
INTERNATIONAL_NAME,
CODE_IDENTIFIER
FROM
SAMPLE_GLOBE AS SG
WHERE
SG.GLOBE_KEY = SATT.MbrPersGenKey
ORDER BY GLOBE_KEY
);
Instruções específicas que não são compatíveis podem comentar todo o código do bloco (exemplo retirado de: Exemplo de JSON).
SQL Server¶
SELECT
SATT.UNIVERSAL_NAME
FROM
SAMPLE_ATLAS AS SATT
INNER JOIN LATERAL (
SELECT
TOP 1 UNIVERSAL_NAME,
INTERNATIONAL_NAME,
CODE_IDENTIFIER
FROM
SAMPLE_GLOBE AS SG
WHERE
SG.GLOBE_KEY = SATT.MbrPersGenKey
ORDER BY
GLOBE_KEY
);
Saída da tradução¶
SELECT
familyName,
c.givenName AS childGivenName,
c.firstName AS childFirstName,
p.givenName AS petName
FROM
Families f
LEFT OUTER JOIN
OPENJSON(f.doc) /*** MSC-WARNING - MSCEWI4030 - Equivalence from CROSS APPLY to LEFT OUTER JOIN must be checked. ***/;
-- ** MSC-ERROR - MSCEWI1001 - UNRECOGNIZED TOKEN ON LINE 7 OF THE SOURCE CODE. **
-- WITH (familyName nvarchar(100), children nvarchar(max) AS JSON)
-- CROSS APPLY OPENJSON(children)
-- WITH (givenName nvarchar(100), firstName nvarchar(100), pets nvarchar(max) AS JSON) as c
-- OUTER APPLY OPENJSON (pets)
-- WITH (givenName nvarchar(100)) as p
EWIs relacionados¶
Sem EWIs relacionados.
USE¶
Equivalente do Snowflake para a instrução Transact-SQL USE.
Applies to
SQL Server
A instrução USE tem seu próprio equivalente no Snowflake. A instrução será convertida para a instrução USE DATABASE no Snowflake.
Exemplos de conversão¶
Fonte¶
USE [MY DATABASE]
Saída¶
USE DATABASE "MY DATABASE";
Nome do banco de dados¶
O nome do banco de dados especificado na instrução USE poderá ser alterado se estiver entre colchetes ([ ]). O primeiro colchete e o último serão substituídos por aspas. Exemplo:
Fonte¶
[MYDATABASE]
[[[MYDATABASE]]
Saída¶
"MYDATABASE"
"[[MYDATABASE]"
Banco de dados definido pelo usuário¶
Se um usuário especificar na ferramenta de conversão um nome de banco de dados personalizado a ser aplicado a todos os objetos usando o parâmetro -d e quiser que as instruções USE sejam transformadas, o nome do banco de dados deverá ser aplicado apenas à instrução USE e não aos objetos. Isso substituirá o banco de dados especificado na instrução Use. Exemplo:
Fonte¶
-- Additional Params: -d MYCUSTOMDB
USE [MY DATABASE]
CREATE TABLE [TableName1].[TableName2](
[ColumnName1] varchar NULL
);
Saída¶
-- Additional Params: -d MYCUSTOMDB
USE DATABASE MYCUSTOMDB;
CREATE OR REPLACE TABLE MYCUSTOMDB.TableName1.TableName2 (
ColumnName1 VARCHAR NULL
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
;
Problemas conhecidos¶
Não foram encontrados problemas.
EWIs relacionados¶
Sem EWIs relacionados.
EXECUTE¶
Applies to
SQL Server
Azure Synapse Analytics
A conversão para as instruções Exec ou Execute não é compatível com o Snowflake, mas será convertida para a instrução CALL.
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Entrada¶
Exec db.sp1
Saída¶
CALL db.sp1();
Para mais informações sobre a execução, acesse: Executar dentro dos procedimentos
PRINT¶
Applies to
SQL Server
Azure Synapse Analytics
A instrução Print não tem suporte direto no Snowflake, mas será traduzida para o seu equivalente mais próximo, a função interna SYSTEM$LOG_INFO.
Entrada¶
PRINT 'My message';
Saída (dentro do SnowScript)¶
SYSTEM$LOG_INTO('My message');
Saída (fora do SnowScript)¶
Quando a instrução Print é usada fora de um procedimento armazenado, é necessário que ela seja chamada de um SnowConvert AI UDP.
CALL PUBLIC.LOG_INFO_UDP('My message');
Antes de começar a registrar mensagens, é necessário configurar uma tabela de eventos. Para mais informações, consulte: registro de mensagens no Snowflake Scripting
Procedimentos armazenados do sistema¶
SP_EXECUTESQL¶
Especificação de tradução para o procedimento do sistema SP_EXECUTESQL.
Applies to
SQL Server
Azure Synapse Analytics
Descrição¶
O procedimento armazenado do sistema SP_EXECUTESQL é usado para executar uma instrução ou um lote do Transact-SQL que pode ser reutilizado várias vezes ou que é criado dinamicamente. A instrução ou o lote pode conter parâmetros incorporados.
Essa funcionalidade pode ser emulada no Snowflake pela instrução EXECUTE IMMEDIATE e com uma função definida pelo usuário (UDF) para parâmetros incorporados.#x20;
Para mais informações sobre a função definida pelo usuário (UDF) usada para esta tradução, veja TRANSFORM_SP_EXECUTE_SQL_STRING_UDF(STRING, STRING, ARRAY, ARRAY).
Sintaxe¶
Transact¶
sp_executesql [ @stmt = ] N'statement'
[
[ , [ @params = ] N'@parameter_name data_type [ { OUT | OUTPUT } ] [ , ...n ]' ]
[ , [ @param1 = ] 'value1' [ , ...n ] ]
]
Amostra de padrões da origem¶
Todos os padrões transformarão SP_EXECUTESQL na instrução EXECUTE IMMEDIATE do Snowflake e somente modificarão a cadeia de caracteres SQL a ser executada ao usar parâmetros incorporados.
Aviso
SSC-EWI-0030 (Uso de SQL dinâmico) será adicionado a todos os padrões. Embora a conversão para SP_EXECUTESQL seja equivalente ao Snowflake, nesse contexto, esse EWI indica que a cadeia de caracteres SQL pode exigir correções manuais para que a conversão seja executada como pretendido.
Dados de configuração¶
Transact¶
CREATE TABLE PERSONS(
NAME VARCHAR(25),
ID INT,
AGE INT
);
-- DATA
INSERT INTO PERSONS VALUES ('John Smith', 1, 24);
INSERT INTO PERSONS VALUES ('John Doe', 2, 21);
INSERT INTO PERSONS VALUES ('Mary Keller', 3, 32);
INSERT INTO PERSONS VALUES ('Mundane Man', 4, 18);
Snowflake¶
CREATE OR REPLACE TABLE PERSONS (
NAME VARCHAR(25),
ID INT,
AGE INT
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/04/2024" }}'
;
-- DATA
INSERT INTO PERSONS VALUES ('John Smith', 1, 24);
INSERT INTO PERSONS VALUES ('John Doe', 2, 21);
INSERT INTO PERSONS VALUES ('Mary Keller', 3, 32);
INSERT INTO PERSONS VALUES ('Mundane Man', 4, 18);
Sem parâmetros incorporados¶
Quando nenhum parâmetro incorporado estiver sendo usado, SP_EXECUTESQL é transformado em uma instrução EXECUTE IMMEDIATE e usa a cadeia de caracteres SQL sem modificações.
Transact¶
CREATE PROCEDURE SIMPLE_SINGLE_QUERY
AS
BEGIN
DECLARE @SQLString NVARCHAR(500);
SET @SQLString = N'SELECT * FROM PERSONS';
EXECUTE sp_executesql @SQLString;
END
GO
EXEC SIMPLE_SINGLE_QUERY;
Resultados¶
Nome |
ID |
AGE |
|---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Mary Keller |
3 |
32 |
Mundane Man |
4 |
18 |
Snowflake¶
CREATE OR REPLACE PROCEDURE SIMPLE_SINGLE_QUERY ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/04/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
SQLSTRING VARCHAR(500);
ProcedureResultSet RESULTSET;
BEGIN
SQLSTRING := 'SELECT
*
FROM
PERSONS;';
ProcedureResultSet := (
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE :SQLSTRING
);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL SIMPLE_SINGLE_QUERY();
Resultados¶
Nome |
ID |
AGE |
|---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Mary Keller |
3 |
32 |
Mundane Man |
4 |
18 |
Com parâmetros incorporados para vinculação de dados¶
Para parâmetros incorporados para vinculação de dados, o SP_EXECUTESQL é transformado em uma instrução EXECUTE IMMEDIATE e a cadeia de caracteres SQL é modificada pelo TRANSFORM_SP_EXECUTE_SQL_STRING_UDF.#x20;
O resultado de EXECUTE IMMEDIATE é atribuído à variável ProcedureResultSet e, posteriormente, retornado como TABLE(ProcedureResultSet).
Transact¶
CREATE PROCEDURE QUERY_WITH_DATA_BINDING_PARAMS
AS
BEGIN
DECLARE @IntVariable INT;
DECLARE @SQLString NVARCHAR(500);
DECLARE @ParmDefinition NVARCHAR(500);
SET @IntVariable = 21;
SET @SQLString = N'SELECT * FROM PERSONS WHERE AGE = @age';
SET @ParmDefinition = N'@age INT';
EXECUTE sp_executesql @SQLString, @ParmDefinition, @age = @IntVariable;
END
GO
EXEC QUERY_WITH_DATA_BINDING_PARAMS;
Resultados¶
Nome |
ID |
AGE |
|---|---|---|
John Doe |
2 |
21 |
Snowflake¶
CREATE OR REPLACE PROCEDURE QUERY_WITH_DATA_BINDING_PARAMS ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/04/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
INTVARIABLE INT;
SQLSTRING VARCHAR(500);
PARMDEFINITION VARCHAR(500);
ProcedureResultSet RESULTSET;
BEGIN
INTVARIABLE := 21;
SQLSTRING := 'SELECT
*
FROM
PERSONS
WHERE
AGE = @age;';
PARMDEFINITION := '@age INT';
ProcedureResultSet := (
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE TRANSFORM_SP_EXECUTE_SQL_STRING_UDF(:SQLSTRING, :PARMDEFINITION, ARRAY_CONSTRUCT('AGE'), ARRAY_CONSTRUCT(:INTVARIABLE))
);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL QUERY_WITH_DATA_BINDING_PARAMS();
Resultados¶
Nome |
ID |
AGE |
|---|---|---|
John Doe |
2 |
21 |
Com parâmetros incorporados OUTPUT¶
Para parâmetros OUTPUT incorporados, SP_EXECUTESQL é transformado em uma instrução EXECUTE IMMEDIATE e a cadeia de caracteres SQL é modificada por meio de TRANSFORM_SP_EXECUTE_SQL_STRING_UDF.
Além disso, SELECT $1, ..., $n INTO :outputParam1, ..., :outputParamN FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())) é adicionado ao resultado de cada coluna para o parâmetro OUTPUT correspondente.
Aviso
SSC-FDM-TS0028 é adicionado à instrução SELECT INTO. É essencial que os parâmetros da cláusula INTO apareçam na mesma ordem em que foram atribuídos na cadeia de caracteres SQL original.
Caso contrário, serão necessárias alterações manuais para atender a esse requisito.
Transact¶
CREATE PROCEDURE QUERY_WITH_OUTPUT_PARAMS
AS
BEGIN
DECLARE @SQLString NVARCHAR(500);
DECLARE @ParamDefinition NVARCHAR(500);
DECLARE @MaxAge INT;
SET @SQLString = N'SELECT @MaxAgeOUT = max(AGE) FROM PERSONS';
SET @ParamDefinition = N'@MaxAgeOUT INT OUTPUT';
EXECUTE sp_executesql @SQLString, @ParamDefinition, @MaxAgeOUT = @MaxAge OUTPUT;
SELECT @MaxAge;
END
GO
EXEC QUERY_WITH_OUTPUT_PARAMS;
Resultados¶
<anônimo> |
|---|
32 |
Snowflake¶
CREATE OR REPLACE PROCEDURE QUERY_WITH_OUTPUT_PARAMS ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "11/27/2024", "domain": "test" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
SQLSTRING VARCHAR(500);
PARAMDEFINITION VARCHAR(500);
MAXAGE INT;
ProcedureResultSet RESULTSET;
BEGIN
SQLSTRING := 'SELECT
MAX(AGE) FROM
PERSONS;';
PARAMDEFINITION := '@MaxAgeOUT INT OUTPUT';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE TRANSFORM_SP_EXECUTE_SQL_STRING_UDF(:SQLSTRING, :PARAMDEFINITION, ARRAY_CONSTRUCT('MAXAGEOUT'), ARRAY_CONSTRUCT(:MAXAGE));
--** SSC-FDM-TS0028 - OUTPUT PARAMETERS MUST HAVE THE SAME ORDER AS THEY APPEAR IN THE EXECUTED CODE **
SELECT
$1
INTO
:MAXAGE
FROM
TABLE(RESULT_SCAN(LAST_QUERY_ID()));
ProcedureResultSet := (
SELECT
:MAXAGE);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL QUERY_WITH_OUTPUT_PARAMS();
Resultados¶
:MAXAGE::NUMBER(38,0) |
|---|
32 |
Com os parâmetros incorporados OUTPUT e a vinculação de dados¶
A conversão é a mesma que para apenas parâmetros OUTPUT.
Transact¶
CREATE PROCEDURE QUERY_WITH_BOTH_PARAMS
AS
BEGIN
DECLARE @AgeVariable INT;
DECLARE @IdVariable INT;
DECLARE @SQLString NVARCHAR(500);
DECLARE @ParmDefinition NVARCHAR(500);
DECLARE @MaxAge INT;
DECLARE @MaxId INT;
SET @AgeVariable = 30;
SET @IdVariable = 100;
SET @SQLString = N'SELECT @MaxAgeOUT = max(AGE), @MaxIdOut = max(ID) FROM PERSONS WHERE AGE < @age AND ID < @id;';
SET @ParmDefinition = N'@age INT, @id INT, @MaxAgeOUT INT OUTPUT, @MaxIdOUT INT OUTPUT';
EXECUTE sp_executesql @SQLString, @ParmDefinition, @age = @AgeVariable, @id = @IdVariable, @MaxAgeOUT = @MaxAge OUTPUT, @MaxIdOUT = @MaxId OUTPUT;
SELECT @MaxAge, @MaxId;
END
GO
EXEC QUERY_WITH_BOTH_PARAMS;
Resultados¶
<anônimo> |
<anônimo> |
|---|---|
24 |
4 |
Snowflake¶
CREATE OR REPLACE PROCEDURE QUERY_WITH_BOTH_PARAMS ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/04/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
AGEVARIABLE INT;
IDVARIABLE INT;
SQLSTRING VARCHAR(500);
PARMDEFINITION VARCHAR(500);
MAXAGE INT;
MAXID INT;
ProcedureResultSet RESULTSET;
BEGIN
AGEVARIABLE := 30;
IDVARIABLE := 100;
SQLSTRING := 'SELECT
MAX(AGE),
MAX(ID) FROM
PERSONS
WHERE
AGE < @age AND ID < @id;';
PARMDEFINITION := '@age INT, @id INT, @MaxAgeOUT INT OUTPUT, @MaxIdOUT INT OUTPUT';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE TRANSFORM_SP_EXECUTE_SQL_STRING_UDF(:SQLSTRING, :PARMDEFINITION, ARRAY_CONSTRUCT('AGE', 'ID', 'MAXAGEOUT', 'MAXIDOUT'), ARRAY_CONSTRUCT(:AGEVARIABLE, :IDVARIABLE, :MAXAGE, :MAXID));
--** SSC-FDM-TS0028 - OUTPUT PARAMETERS MUST HAVE THE SAME ORDER AS THEY APPEAR IN THE EXECUTED CODE **
SELECT
$1,
$2
INTO
:MAXAGE,
:MAXID
FROM
TABLE(RESULT_SCAN(LAST_QUERY_ID()));
ProcedureResultSet := (
SELECT
:MAXAGE,
:MAXID);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL QUERY_WITH_BOTH_PARAMS();
Resultados¶
:MAXAGE::NUMBER(38,0) |
:MAXID::NUMBER(38,0) |
|---|---|
24 |
4 |
Os parâmetros não estão em ordem de definição¶
Esse padrão segue as mesmas regras dos padrões anteriores. TRANSFORM_SP_EXECUTE_SQL_STRING_UDF substitui os valores dos parâmetros na ordem correta.
Transact¶
CREATE PROCEDURE QUERY_PARAMS_NOT_IN_ORDER_OF_DEF
AS
BEGIN
DECLARE @AgeVariable INT;
DECLARE @IdVariable INT;
DECLARE @SQLString NVARCHAR(500);
DECLARE @ParmDefinition NVARCHAR(500);
DECLARE @MaxAge INT;
DECLARE @MaxId INT;
SET @AgeVariable = 30;
SET @IdVariable = 100;
SET @SQLString = N'SELECT @MaxAgeOUT = max(AGE), @MaxIdOut = max(ID) FROM PERSONS WHERE AGE < @age AND ID < @id;';
SET @ParmDefinition = N'@age INT, @id INT, @MaxAgeOUT INT OUTPUT, @MaxIdOUT INT OUTPUT';
EXECUTE sp_executesql @SQLString, @ParmDefinition, @id = @IdVariable, @MaxAgeOUT = @MaxAge OUTPUT, @age = @AgeVariable, @MaxIdOUT = @MaxId OUTPUT;
SELECT @MaxAge, @MaxId;
END
GO
EXEC QUERY_PARAMS_NOT_IN_ORDER_OF_DEF;
CREATE PROCEDURE QUERY_PARAMS_NOT_IN_ORDER_OF_DEF_2
AS
BEGIN
DECLARE @AgeVariable INT;
DECLARE @IdVariable INT;
DECLARE @SQLString NVARCHAR(500);
DECLARE @ParmDefinition NVARCHAR(500);
DECLARE @MaxAge INT;
DECLARE @MaxId INT;
SET @AgeVariable = 30;
SET @IdVariable = 100;
SET @SQLString = N'SELECT @MaxAgeOUT = max(AGE), @MaxIdOut = max(ID) FROM PERSONS WHERE AGE < @age AND ID < @id;';
SET @ParmDefinition = N'@age INT, @id INT, @MaxAgeOUT INT OUTPUT, @MaxIdOUT INT OUTPUT';
EXECUTE sp_executesql @SQLString, @ParmDefinition, @AgeVariable, @MaxAgeOUT = @MaxAge OUTPUT, @id = @IdVariable, @MaxIdOUT = @MaxId OUTPUT;
SELECT @MaxAge, @MaxId;
END
GO
EXEC QUERY_PARAMS_NOT_IN_ORDER_OF_DEF_2;
Resultados¶
<anônimo> |
<anônimo> |
|---|---|
24 |
4 |
<anônimo> |
<anônimo> |
|---|---|
24 |
4 |
Snowflake¶
CREATE OR REPLACE PROCEDURE QUERY_PARAMS_NOT_IN_ORDER_OF_DEF ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/04/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
AGEVARIABLE INT;
IDVARIABLE INT;
SQLSTRING VARCHAR(500);
PARMDEFINITION VARCHAR(500);
MAXAGE INT;
MAXID INT;
ProcedureResultSet RESULTSET;
BEGIN
AGEVARIABLE := 30;
IDVARIABLE := 100;
SQLSTRING := 'SELECT
MAX(AGE),
MAX(ID) FROM
PERSONS
WHERE
AGE < @age AND ID < @id;';
PARMDEFINITION := '@age INT, @id INT, @MaxAgeOUT INT OUTPUT, @MaxIdOUT INT OUTPUT';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE TRANSFORM_SP_EXECUTE_SQL_STRING_UDF(:SQLSTRING, :PARMDEFINITION, ARRAY_CONSTRUCT('ID', 'MAXAGEOUT', 'AGE', 'MAXIDOUT'), ARRAY_CONSTRUCT(:IDVARIABLE, :MAXAGE, :AGEVARIABLE, :MAXID));
--** SSC-FDM-TS0028 - OUTPUT PARAMETERS MUST HAVE THE SAME ORDER AS THEY APPEAR IN THE EXECUTED CODE **
SELECT
$1,
$2
INTO
:MAXAGE,
:MAXID
FROM
TABLE(RESULT_SCAN(LAST_QUERY_ID()));
ProcedureResultSet := (
SELECT
:MAXAGE,
:MAXID);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL QUERY_PARAMS_NOT_IN_ORDER_OF_DEF();
CREATE OR REPLACE PROCEDURE QUERY_PARAMS_NOT_IN_ORDER_OF_DEF_2 ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/04/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
AGEVARIABLE INT;
IDVARIABLE INT;
SQLSTRING VARCHAR(500);
PARMDEFINITION VARCHAR(500);
MAXAGE INT;
MAXID INT;
ProcedureResultSet RESULTSET;
BEGIN
AGEVARIABLE := 30;
IDVARIABLE := 100;
SQLSTRING := 'SELECT
MAX(AGE),
MAX(ID) FROM
PERSONS
WHERE
AGE < @age AND ID < @id;';
PARMDEFINITION := '@age INT, @id INT, @MaxAgeOUT INT OUTPUT, @MaxIdOUT INT OUTPUT';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE TRANSFORM_SP_EXECUTE_SQL_STRING_UDF(:SQLSTRING, :PARMDEFINITION, ARRAY_CONSTRUCT('', 'MAXAGEOUT', 'ID', 'MAXIDOUT'), ARRAY_CONSTRUCT(:AGEVARIABLE, :MAXAGE, :IDVARIABLE, :MAXID));
--** SSC-FDM-TS0028 - OUTPUT PARAMETERS MUST HAVE THE SAME ORDER AS THEY APPEAR IN THE EXECUTED CODE **
SELECT
$1,
$2
INTO
:MAXAGE,
:MAXID
FROM
TABLE(RESULT_SCAN(LAST_QUERY_ID()));
ProcedureResultSet := (
SELECT
:MAXAGE,
:MAXID);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL QUERY_PARAMS_NOT_IN_ORDER_OF_DEF_2();
Resultados¶
:MAXAGE::NUMBER(38,0) |
:MAXID::NUMBER(38,0) |
|---|---|
24 |
4 |
:MAXAGE::NUMBER(38,0) |
:MAXID::NUMBER(38,0) |
|---|---|
24 |
4 |
Executar valores diretos¶
Essa conversão também lida com os casos em que os valores são atribuídos diretamente em vez de usar variáveis.
Transact¶
CREATE PROCEDURE QUERY_WITH_DIRECT_PARAMS_VALUES_ALL
AS
BEGIN
DECLARE @MaxAge INT;
DECLARE @MaxId INT;
EXECUTE sp_executesql
N'SELECT @MaxAgeOUT = max(AGE), @MaxIdOut = max(ID) FROM PERSONS WHERE ID < @id AND AGE < @age;',
N'@age INT, @id INT, @MaxAgeOUT INT OUTPUT, @MaxIdOUT INT OUTPUT',
30,
100,
@MaxAge OUTPUT,
@MaxId OUTPUT;
SELECT @MaxAge, @MaxId;
END
GO
EXEC QUERY_WITH_DIRECT_PARAMS_VALUES_ALL;
Resultados¶
<anônimo> |
<anônimo> |
|---|---|
24 |
4 |
Snowflake¶
CREATE OR REPLACE PROCEDURE QUERY_WITH_DIRECT_PARAMS_VALUES_ALL ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/07/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
MAXAGE INT;
MAXID INT;
ProcedureResultSet RESULTSET;
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE TRANSFORM_SP_EXECUTE_SQL_STRING_UDF('SELECT
MAX(AGE),
MAX(ID) FROM
PERSONS
WHERE
ID < @id AND AGE < @age;', '@age INT, @id INT, @MaxAgeOUT INT OUTPUT, @MaxIdOUT INT OUTPUT', ARRAY_CONSTRUCT('', '', '', ''), ARRAY_CONSTRUCT(
30,
100, :MAXAGE, :MAXID));
--** SSC-FDM-TS0028 - OUTPUT PARAMETERS MUST HAVE THE SAME ORDER AS THEY APPEAR IN THE EXECUTED CODE **
SELECT
$1,
$2
INTO
:MAXAGE,
:MAXID
FROM
TABLE(RESULT_SCAN(LAST_QUERY_ID()));
ProcedureResultSet := (
SELECT
:MAXAGE,
:MAXID);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL QUERY_WITH_DIRECT_PARAMS_VALUES_ALL();
Resultados¶
:MAXAGE::NUMBER(38,0) |
:MAXID::NUMBER(38,0) |
|---|---|
24 |
4 |
Cadeia de caracteres SQL construída dinamicamente¶
Esse padrão segue as mesmas regras dos padrões anteriores. No entanto, a atribuição do resultado da instrução EXECUTE IMMEDIATE pode não ser adicionada se a cadeia de caracteres SQL não for uma consulta simples e única com ou sem parâmetros incorporados.
Além disso, a cadeia de caracteres SQL precisa começar com o valor literal 'SELECT' para SnowConvert AI para identificar corretamente que uma instrução SELECT será executada.
Transact¶
CREATE PROCEDURE DYNAMIC_WITH_PARAMS
AS
BEGIN
DECLARE @IntVariable INT;
DECLARE @SQLString NVARCHAR(500);
DECLARE @ParmDefinition NVARCHAR(500);
DECLARE @where_clause nvarchar(100);
SET @where_clause = 'WHERE AGE = @age';
SET @IntVariable = 21;
SET @SQLString = N'SELECT * FROM PERSONS ' + @where_clause;
SET @ParmDefinition = N'@age INT';
EXECUTE sp_executesql @SQLString, @ParmDefinition, @age = @IntVariable;
END
GO
EXEC DYNAMIC_WITH_PARAMS;
Resultados¶
Nome |
ID |
AGE |
|---|---|---|
John Doe |
2 |
21 |
Snowflake¶
CREATE OR REPLACE PROCEDURE DYNAMIC_WITH_PARAMS ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/04/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
INTVARIABLE INT;
SQLSTRING VARCHAR(500);
PARMDEFINITION VARCHAR(500);
WHERE_CLAUSE VARCHAR(100);
ProcedureResultSet RESULTSET;
BEGIN
WHERE_CLAUSE := 'WHERE AGE = @age';
INTVARIABLE := 21;
SQLSTRING := 'SELECT
*
FROM
PERSONS ' || :WHERE_CLAUSE || ';';
PARMDEFINITION := '@age INT';
ProcedureResultSet := (
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE TRANSFORM_SP_EXECUTE_SQL_STRING_UDF(:SQLSTRING, :PARMDEFINITION, ARRAY_CONSTRUCT('AGE'), ARRAY_CONSTRUCT(:INTVARIABLE))
);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL DYNAMIC_WITH_PARAMS();
Resultados¶
Nome |
ID |
AGE |
|---|---|---|
John Doe |
2 |
21 |
Retorno de vários conjuntos de resultados¶
Os procedimentos do Snowflake Scripting permitem que apenas um conjunto de resultados seja retornado por procedimento.
Para replicar o comportamento do Transact-SQL, quando dois ou mais conjuntos de resultados devem ser retornados, eles são armazenados em tabelas temporárias. O procedimento Snowflake Scripting retornará uma matriz contendo os nomes das tabelas temporárias. Para obter mais informações, consulte SSC-FDM-0020.
Transact¶
CREATE PROCEDURE WITH_MULTIPLE_RETURNS
AS
BEGIN
DECLARE @SQLString NVARCHAR(500);
DECLARE @ParmDefinition NVARCHAR(500);
SET @SQLString = N'SELECT * FROM PERSONS WHERE AGE = @age';
SET @ParmDefinition = N'@age INT';
EXECUTE sp_executesql @SQLString, @ParmDefinition, @age = 21;
SET @SQLString = N'INSERT INTO PERSONS VALUES (''INSERT FIRST'', 1200, 230);';
EXECUTE sp_executesql @SQLString;
SET @SQLString = N'SELECT * FROM PERSONS';
EXECUTE sp_executesql @SQLString;
END
GO
EXECUTE WITH_MULTIPLE_RETURNS;
Resultados¶
Nome |
ID |
AGE |
|---|---|---|
John Doe |
2 |
21 |
Nome |
ID |
AGE |
|---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Mary Keller |
3 |
32 |
Mundane Man |
4 |
18 |
INSERT FIRST |
1200 |
230 |
Snowflake¶
CREATE OR REPLACE PROCEDURE WITH_MULTIPLE_RETURNS ()
RETURNS ARRAY
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/07/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
SQLSTRING VARCHAR(500);
PARMDEFINITION VARCHAR(500);
ProcedureResultSet1 VARCHAR;
ProcedureResultSet2 VARCHAR;
return_arr ARRAY := array_construct();
BEGIN
SQLSTRING := 'SELECT
*
FROM
PERSONS
WHERE
AGE = @age;';
PARMDEFINITION := '@age INT';
ProcedureResultSet1 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE TRANSFORM_SP_EXECUTE_SQL_STRING_UDF(:SQLSTRING, :PARMDEFINITION, ARRAY_CONSTRUCT('AGE'), ARRAY_CONSTRUCT(21));
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:ProcedureResultSet1) AS
SELECT
*
FROM
TABLE(RESULT_SCAN(LAST_QUERY_ID()));
return_arr := array_append(return_arr, :ProcedureResultSet1);
SQLSTRING := 'INSERT INTO PERSONS VALUES ('INSERT FIRST', 1200, 230);';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE :SQLSTRING;
SQLSTRING := 'SELECT
*
FROM
PERSONS;';
ProcedureResultSet2 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE :SQLSTRING;
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:ProcedureResultSet2) AS
SELECT
*
FROM
TABLE(RESULT_SCAN(LAST_QUERY_ID()));
return_arr := array_append(return_arr, :ProcedureResultSet2);
--** SSC-FDM-0020 - MULTIPLE RESULT SETS ARE RETURNED IN TEMPORARY TABLES **
RETURN return_arr;
END;
$$;
CALL WITH_MULTIPLE_RETURNS();
Resultados¶
WITH_MULTIPLE_RETURNS |
|---|
[ «RESULTSET_88C35D7A_1E5B_455D_97A4_247806E583A5», «RESULTSET_B2345B61_A015_43CB_BA11_6D3E013EF262» ] |
Problemas conhecidos¶
1. Invalid code is detected¶
SP_EXECUTESQL pode executar mais de uma instrução SQL dentro da cadeia de caracteres SQL. O Snowflake também oferece suporte à execução de várias instruções SQL, mas elas precisam estar em um bloco BEGIN … END. Além disso, ao executar várias instruções de um bloco BEGIN … END, o EXECUTE IMMEDIATE não retornará um conjunto de resultados. O SnowConvert AI ainda não oferece suporte para a tradução nesses casos. Para mais informações, veja SSC-EWI-0030.
Assim, quando esse caso for detectado, no código convertido, EXECUTE IMMEDIATE não será atribuído a ProcedureResultSet.
Transact¶
CREATE PROCEDURE WITH_INVALID_CODE_DETECTED
AS
BEGIN
DECLARE @SQLString NVARCHAR(500);
SET @SQLString = N'INSERT INTO PERSONS VALUES (''INSERT FIRST'', 1200, 230); SELECT * FROM PERSONS;';
EXECUTE sp_executesql @SQLString;
END
GO
EXEC WITH_INVALID_CODE_DETECTED;
Resultados¶
Nome |
ID |
AGE |
|---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Mary Keller |
3 |
32 |
Mundane Man |
4 |
18 |
INSERT FIRST |
1200 |
230 |
Snowflake¶
CREATE OR REPLACE PROCEDURE WITH_INVALID_CODE_DETECTED ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/04/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
SQLSTRING VARCHAR(500);
BEGIN
SQLSTRING := 'INSERT INTO PERSONS VALUES ('INSERT FIRST', 1200, 230); SELECT
*
FROM
PERSONS;';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE :SQLSTRING;
END;
$$;
CALL WITH_INVALID_CODE_DETECTED();
Resultados¶
000006 (0A000): Uncaught exception of type 'STATEMENT_ERROR' on line 10 at position 4 : Multiple SQL statements in a single API call are not supported; use one API call per statement instead.
2. Valid or Invalid code is not detected¶
Se a cadeia de caracteres SQL for construída dinamicamente através de concatenações, pode ser que a SnowConvert AI não detecte qual instrução será executada. Assim, no código traduzido, EXECUTE IMMEDIATE não será atribuído ao ProcedureResultSet.
Transact¶
CREATE PROCEDURE WITH_INVALID_CODE_NOT_DETECTED
AS
BEGIN
DECLARE @SQLString NVARCHAR(500);
DECLARE @SQLInsert NVARCHAR(500);
SET @SQLInsert = N'INSERT INTO PERSONS VALUES (''INSERT FIRST'', 1200, 230)';
SET @SQLString = @SQLInsert + N'SELECT * FROM PERSONS;';
EXECUTE sp_executesql @SQLString;
END
GO
EXEC WITH_INVALID_CODE_NOT_DETECTED;
Resultados¶
Nome |
ID |
AGE |
|---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Mary Keller |
3 |
32 |
Mundane Man |
4 |
18 |
INSERT FIRST |
1200 |
230 |
Snowflake¶
CREATE OR REPLACE PROCEDURE WITH_INVALID_CODE_NOT_DETECTED ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/04/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
SQLSTRING VARCHAR(500);
SQLINSERT VARCHAR(500);
BEGIN
SQLINSERT := 'INSERT INTO PERSONS VALUES ('INSERT FIRST', 1200, 230);';
SQLSTRING := :SQLINSERT || 'SELECT * FROM PERSONS;';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE :SQLSTRING;
END;
$$;
CALL WITH_INVALID_CODE_NOT_DETECTED();
Resultados¶
000006 (0A000): Uncaught exception of type 'STATEMENT_ERROR' on line 10 at position 4 : Multiple SQL statements in a single API call are not supported; use one API call per statement instead.
3. Invalid code is mistaken as valid¶
Se a cadeia de caracteres SQL começar com uma instrução SELECT e for seguida por mais instruções, a SnowConvert AI detectará isso como um código válido e tentará atribuir o resultado do EXECUTE IMMEDIATE para o ProcedureResultSet. Isso gera um erro de compilação. Para mais informações, veja SSC-EWI-0030.
Transact¶
CREATE PROCEDURE WITH_INVALID_CODE_MISTAKEN_AS_VALID
AS
BEGIN
DECLARE @SQLString NVARCHAR(500);
SET @SQLString = N'SELECT * FROM PERSONS; SELECT * FROM PERSONS;';
EXECUTE sp_executesql @SQLString;
END
GO
EXEC WITH_INVALID_CODE_MISTAKEN_AS_VALID;
Resultados¶
Nome |
ID |
AGE |
|---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Mary Keller |
3 |
32 |
Mundane Man |
4 |
18 |
Nome |
ID |
AGE |
|---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Mary Keller |
3 |
32 |
Mundane Man |
4 |
18 |
Snowflake¶
CREATE OR REPLACE PROCEDURE WITH_INVALID_CODE_MISTAKEN_AS_VALID ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/04/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
SQLSTRING VARCHAR(500);
ProcedureResultSet RESULTSET;
BEGIN
SQLSTRING := 'SELECT
*
FROM
PERSONS; SELECT
*
FROM
PERSONS;';
ProcedureResultSet := (
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE :SQLSTRING
);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL WITH_INVALID_CODE_MISTAKEN_AS_VALID();
Resultados¶
000006 (0A000): Uncaught exception of type 'STATEMENT_ERROR' on line 10 at position 4 : Multiple SQL statements in a single API call are not supported; use one API call per statement instead.
EWIs relacionados¶
SSC-EWI-0030: A instrução abaixo tem usos de SQL dinâmico
SSC-FDM-TS0028: Os parâmetros de saída devem ter a mesma ordem em que aparecem no código executado.
SSC-FDM-0020: Vários conjuntos de resultados são retornados em tabelas temporárias.
SP_RENAME¶
Procedimento de armazenamento para renomear determinados objetos no servidor SQL
Applies to
SQL Server
Azure Synapse Analytics
O procedimento de armazenamento do sistema SP_RENAME pode ser emulado no Snowflake em determinados cenários. Em geral, o equivalente é EXECUTE IMMEDIATE, usando uma instrução dinâmica com ALTER TABLE e os parâmetros originais.
Exemplos de conversão para tabelas¶
Fonte¶
EXEC sp_rename 'TABLE1', 'TABLENEW1'
Saída¶
EXECUTE IMMEDIATE 'ALTER TABLE TABLE1 RENAME TO TABLENEW1';
Fonte¶
DECLARE @varname1 nvarchar(50) = 'previous_name'
DECLARE @varname2 nvarchar(50) = 'newer_name'
EXEC sp_rename @varname1, @varname2
Saída¶
DECLARE
VARNAME1 VARCHAR(50) := 'previous_name';
VARNAME2 VARCHAR(50) := 'newer_name';
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE ' || :VARNAME1 || ' RENAME TO ' || :VARNAME2;
END;
Exemplos de conversão para colunas¶
Fonte¶
EXEC sp_rename 'sample_BACKUP_2.column_old', 'column_new', 'COLUMN'
EXEC sp_rename 'database1.sample_BACKUP_3.column_old', 'column_new', 'COLUMN'
Saída¶
EXECUTE IMMEDIATE 'ALTER TABLE sample_BACKUP_2 RENAME COLUMN column_old TO column_new';
EXECUTE IMMEDIATE 'ALTER TABLE database1.sample_BACKUP_3 RENAME COLUMN column_old TO column_new';
Fonte¶
DECLARE @oldColumnName nvarchar(50) = 'previous_name'
DECLARE @newColumnName nvarchar(50) = 'newer_name'
DECLARE @tableName nvarchar(50) = 'TABLE'
EXEC sp_rename @objname = @tableName + '.' + @oldColumnName, @newname = @newColumnName, @objtype = 'COLUMN';
Saída¶
DECLARE
OLDCOLUMNNAME VARCHAR(50) := 'previous_name';
NEWCOLUMNNAME VARCHAR(50) := 'newer_name';
TABLENAME VARCHAR(50) := 'TABLE';
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0075 - TRANSLATION FOR BUILT-IN PROCEDURE 'SP_RENAME' IS NOT CURRENTLY SUPPORTED. ***/!!!
EXEC sp_rename OBJNAME = :TABLENAME || '.' || :OLDCOLUMNNAME, NEWNAME = :NEWCOLUMNNAME, OBJTYPE = 'COLUMN';
END;
EWIs relacionados¶
SSC-EWI-TS0075: A conversão para o procedimento interno não é suportada no momento.