SnowConvert: Elementos de linguagem gerais do Transact¶
Collate¶
Applies to
[x] SQL Server
[x] 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¶
Applies to
[x] SQL Server
[x] 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, pode nos enviar um e-mail para snowconvert-support@snowflake.com
EWIs relacionados¶
SSC-FDM-TS0014: Coluna computada transformada.
OUTER APPLY¶
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¶
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;
p.ProjectName | e.ProjectName | FirstName |
---|---|---|
Project A | Project A | John |
Project A | Project A | Jane |
Project A | Project B | Michael |
Project B | Project A | John |
Project B | Project A | Jane |
Project B | Project B | Michael |
Project C | Project A | John |
Project C | Project A | Jane |
Project C | Project B | Michael |
Snowflake¶
SELECT
p.ProjectName,
e.ProjectName,
e.FirstName
FROM
Project p
INNER JOIN
LATERAL (
SELECT
ProjectName,
FirstName,
LastName
FROM
Employees e
) e;
PROJECTNAME | PROJECTNAME_2 | FIRSTNAME |
---|---|---|
Project A | Project A | John |
Project A | Project A | Jane |
Project A | Project B | Michael |
Project B | Project A | John |
Project B | Project A | Jane |
Project B | Project B | Michael |
Project C | Project A | John |
Project C | Project A | Jane |
Project C | Project 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.
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
);
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).
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
);
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¶
Applies to
[x] 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
[x] SQL Server
[x] 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 obter mais informações sobre Execute, visite: Execute dentro de procedimentos.
Problemas conhecidos ¶
Não foram encontrados problemas.
EWIs Relacionados ¶
Sem EWIs relacionados.
Procedimentos armazenados do sistema¶
SP_EXECUTESQL¶
Applies to
[x] SQL Server
[x] 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 por meio da instrução EXECUTE IMMEDIATE e com uma função definida pelo usuário (UDF) para parâmetros incorporados.
Para obter mais informações sobre a função definida pelo usuário (UDF) usada para essa conversão, consulte TRANSFORM_SP_EXECUTE_SQL_STRING_UDF(STRING, STRING, ARRAY, ARRAY).
Sintaxe¶
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¶
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);
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;
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();
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, 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
.
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;
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();
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;
<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();
: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;
<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();
: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;
<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();
: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;
<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();
: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 deve começar com o valor literal 'SELECT'
para que o SnowConvert identifique corretamente que uma instrução SELECT será executada. Para obter mais informações, consulte a seção Problemas conhecidos.
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;
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();
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;
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();
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 suporta a execução de várias instruções SQL, mas elas precisam ser incluídas em um bloco BEGIN ... END
. Além disso, ao executar várias instruções de um bloco BEGIN ... END
, EXECUTE IMMEDIATE
não retornará um conjunto de resultados. A conversão para esses casos ainda não é compatível com o SnowConvert. Para obter mais informações, consulte 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;
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();
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¶
Quando a cadeia de caracteres SQL é criada dinamicamente por meio de concatenações, o SnowConvert pode não detectar qual instrução será executada. Assim, no código convertido, EXECUTE IMMEDIATE
não será atribuído a 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;
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();
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, o SnowConvert detectará isso como um código válido e tentará atribuir o resultado de EXECUTE IMMEDIATE
aProcedureResultSet
. Isso leva a um erro de compilação. Para obter mais informações, consulte 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;
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();
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¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
O procedimento armazenado 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.