SnowConvert : Éléments de langage généraux de Transact¶
Classement¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
La transformation du classement dépend de sa valeur, puisqu’il peut être pris en charge ou non.
Actuellement, voici les langues prises en charge pour la transformation, si elles se trouvent dans le classement, elles seront transformées en leur équivalent Snowflake.
SqlSever |
Snowflake |
---|---|
Latin1_général |
EN |
Espagnol_moderne |
ES |
Français |
FR |
Si la langue n’est pas l’une des langues ci-dessus, le classement sera commenté.
De plus, comme le classement SqlServer est accompagné de spécifications supplémentaires, telles que CI, CS, AI, et AS, seules celles-ci sont prises en charge ; s’il en existe d’autres et qu’elles ne sont pas prises en charge, elles seront commentées dans le résultat.
Source
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;
Valeur attendue
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
;
Voyons un exemple de classement dans un Create Table
Source
CREATE TABLE TABLECOLLATE
(
COL1 VARCHAR COLLATE Latin1_General_CI_AS
);
Valeur attendue
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"}}'
;
Comme vous pouvez le constater, la transformation du classement à l’intérieur d’un Select ou d’une Table est la même.
COMPUTED COLUMN¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Description¶
L’expression d’une colonne calculée n’a pas pu être transformée.
Exemple de code¶
Code d’entrée :¶
CREATE TABLE [TestTable](
[Col1] AS (CONVERT ([REAL], ExpressionValue))
);
Code de sortie :¶
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"}}'
;
Recommandations¶
Ajoutez des modifications manuelles à l’expression non transformée.
Si vous avez encore besoin d’aide, vous pouvez nous envoyer un e-mail à l’adresse suivante : snowconvert-support@snowflake.com
EWIs connexes¶
SSC-FDM-TS0014 : Colonne calculée transformée.
OUTER APPLY¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Description¶
Lorsque OUTER APPLY est spécifié, une ligne est produite pour chaque ligne du jeu de lignes de gauche, même si l’expression du jeu de lignes de droite renvoie un jeu de lignes vide pour cette ligne. (Définition OUTER APPLY)
Syntaxe¶
Apply_Operator :=
'CROSS' 'APPLY'
| 'OUTER' 'APPLY'.
Équivalence Snowflake¶
Malgré l’instruction non prise en charge OUTER APPLY dans Snowflake, il existe une instruction équivalente, à savoir LATERAL. Par conséquent, la traduction de l’instruction est effectuée pour obtenir la même fonctionnalité par l’utilisation de solutions alternatives.
Néanmoins, l’instruction LATERAL dans Snowflake présente deux variantes de syntaxe. En fait, c’est la variante INNER JOIN LATERAL qui est utilisée dans cette traduction spécifique.
La grammaire INNER JOIN LATERAL de Snowflake est la suivante :
SELECT ...
FROM <left_hand_table_expression> INNER JOIN LATERAL ( <inline_view> )
...
Note
<inline_view> ne doit pas être un nom de table.
L’instruction unique LATERAL est présentée ci-dessous :
SELECT ...
FROM <left_hand_table_expression>, LATERAL ( <inline_view> )
...
Source de l’échantillon¶
L’exemple suivant montre une traduction générale entre OUTER APPLY et 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 |
Problèmes connus¶
La traduction étant une équivalence à partir de l’entrée, il existe certaines limites.
Les instructions TOP et WHERE peuvent être révisées pour un comportement optimal.
Un nom de corrélation à la fin de l’instruction peut être nécessaire. Dans Snowflake, la requête ne pose pas de problème si le nom de la corrélation ne figure pas dans la requête, mais la fonctionnalité peut changer et ne fait pas partie du modèle accepté dans 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
);
Les instructions spécifiques qui ne sont pas prises en charge peuvent faire l’objet d’un commentaire sur l’ensemble du code du bloc (exemple tiré de : Exemple 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 connexes¶
Pas d’EWIs connexes.
USE¶
Applies to
[x] SQL Server
L’instruction USE a son propre équivalent dans Snowflake. L’instruction sera traduite en instruction USE DATABASE dans Snowflake.
Exemples de traduction¶
Source¶
USE [MY DATABASE]
Sortie¶
USE DATABASE "MY DATABASE";
Nom de la base de données¶
Le database name
spécifié dans l’instruction USE
peut être modifié s’il est placé entre crochets ([ ])
. Le premier et le dernier crochet seront remplacés par des guillemets. Exemple :
Source¶
[MYDATABASE]
[[[MYDATABASE]]
Sortie¶
"MYDATABASE"
"[[MYDATABASE]"
Base de données définie par l’utilisateur¶
Si un utilisateur indique à l’outil de conversion un nom de base de données personnalisé à appliquer à tous les objets en utilisant le paramètre -d
, et qu’il souhaite que les instructions USE soient transformées, le nom de la base de données doit être appliqué uniquement à l’instruction USE
et non aux objets. Cette option remplace la base de données spécifiée dans l’instruction d’utilisation. Exemple :
Source¶
-- Additional Params: -d MYCUSTOMDB
USE [MY DATABASE]
CREATE TABLE [TableName1].[TableName2](
[ColumnName1] varchar NULL
);
Sortie¶
-- 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"}}'
;
Problèmes connus ¶
Aucun problème n’a été constaté.
EWIs connexes ¶
Pas d’EWIs connexes.
EXECUTE¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
La traduction des instructions Exec ou Execute n’est pas prise en charge dans Snowflake, mais elle sera traduite en instruction CALL.
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Entrée¶
Exec db.sp1
Sortie¶
CALL db.sp1();
Pour plus d’informations sur l’exécution, consultez : Execute à l’intérieur des procédures.
Problèmes connus ¶
Aucun problème n’a été constaté.
EWIs connexes ¶
Pas d’EWIs connexes.
Procédures stockées dans le système¶
SP_EXECUTESQL¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Description¶
La procédure stockée du système SP_EXECUTESQL est utilisée pour exécuter une instruction ou un lot Transact-SQL qui peut être réutilisé plusieurs fois, ou qui est construit dynamiquement. L’instruction ou le lot peut contenir des paramètres intégrés.
Cette fonctionnalité peut être émulée dans Snowflake grâce à l’instruction EXECUTE IMMEDIATE et à une fonction définie par l’utilisateur (UDF) pour les paramètres intégrés.
Pour plus d’informations sur la fonction définie par l’utilisateur (UDF) utilisée pour cette traduction, consultez TRANSFORM_SP_EXECUTE_SQL_STRING_UDF(STRING, STRING, ARRAY, ARRAY).
Syntaxe¶
sp_executesql [ @stmt = ] N'statement'
[
[ , [ @params = ] N'@parameter_name data_type [ { OUT | OUTPUT } ] [ , ...n ]' ]
[ , [ @param1 = ] 'value1' [ , ...n ] ]
]
Modèles d’échantillons de sources¶
Tous les modèles transformeront SP_EXECUTESQL en instruction EXECUTE IMMEDIATE de Snowflake et ne modifieront la chaîne SQL à exécuter qu’en cas d’utilisation de paramètres intégrés.
Avertissement
SSC-EWI-0030 (Utilisation de Dynamic SQL) sera ajouté pour tous les modèles. Même si la traduction de SP_EXECUTESQL est équivalente à Snowflake, dans ce contexte, cette EWI indique que la chaîne SQL pourrait nécessiter des corrections manuelles pour que la traduction s’exécute comme prévu.
Données de configuration¶
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);
Sans paramètres intégrés¶
Lorsqu’aucun paramètre intégré n’est utilisé, SP\EXECUTESQL est transformé en instruction EXECUTE IMMEDIATE et utilise la chaîne SQL sans modifications.
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;
Nom |
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();
Nom |
ID |
AGE |
---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Mary Keller |
3 |
32 |
Mundane Man |
4 |
18 |
Avec des paramètres intégrés pour la liaison des données¶
En ce qui concerne les paramètres intégrés pour la liaison de données, l’instruction SP_EXECUTESQL est transformée en instruction EXECUTE IMMEDIATE, et la chaîne SQL est modifiée par l’intermédiaire de l’instruction TRANSFORM_SP_EXECUTE_SQL_STRING_UDF
.
Le résultat de l’opération EXECUTE IMMEDIATE est affecté à la variable ProcedureResultSet
et renvoyé ultérieurement sous la forme 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;
Nom |
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();
Nom |
ID |
AGE |
---|---|---|
John Doe |
2 |
21 |
Avec paramètres intégrés OUTPUT¶
Pour les paramètres incorporés OUTPUT, SP_EXECUTESQL est transformé en instruction EXECUTE IMMEDIATE, et la chaîne SQL est modifiée par TRANSFORM_SP_EXECUTE_SQL_STRING_UDF
.
En outre, SELECT $1, ..., $n INTO :outputParam1, ..., :outputParamN FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))
est ajouté au résultat de chaque colonne au paramètre OUTPUT correspondant.
Avertissement
SSC-FDM-TS0028 est ajouté à l’instruction SELECT INTO. Il est essentiel que les paramètres de la clause INTO apparaissent dans le même ordre que celui dans lequel ils ont été attribués dans la chaîne originale SQL.
Dans le cas contraire, des modifications manuelles sont nécessaires pour répondre à cette exigence.
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;
<anonymous> |
---|
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 |
Avec les paramètres intégrés de OUTPUT et la liaison des données¶
La traduction est la même que pour les paramètres 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;
<anonymous> |
<anonymous> |
---|---|
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 |
Paramètres non classés par ordre de définition¶
Ce modèle suit les mêmes règles que les modèles précédents. TRANSFORM_SP_EXECUTE_SQL_STRING_UDF
remplace les valeurs des paramètres dans l’ordre correct.
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;
<anonymous> |
<anonymous> |
---|---|
24 |
4 |
<anonymous> |
<anonymous> |
---|---|
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 |
Exécuter les valeurs directes¶
Cette traduction traite également les cas où les valeurs sont directement assignées au lieu d’utiliser des variables.
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;
<anonymous> |
<anonymous> |
---|---|
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 |
Chaîne SQL construite dynamiquement¶
Ce modèle suit les mêmes règles que les modèles précédents. Toutefois, l’affectation du résultat de l’instruction EXECUTE IMMEDIATE peut ne pas être ajoutée si la chaîne SQL n’est pas une simple requête unique avec ou sans paramètres intégrés.
En outre, la chaîne SQL doit commencer par la valeur littérale 'SELECT'
pour que SnowConvert identifie correctement qu’une instruction SELECT va être exécutée. Pour plus d’informations, consultez la section Problèmes connus.
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;
Nom |
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();
Nom |
ID |
AGE |
---|---|---|
John Doe |
2 |
21 |
Renvoi de plusieurs jeux de résultats¶
Les procédures de Snowflake Scripting ne permettent de renvoyer qu’un seul jeu de résultats par procédure.
Pour répliquer le comportement de Transact-SQL, lorsque deux ou plusieurs jeux de résultats doivent être renvoyés, ils sont stockés dans des tables temporaires. La procédure Snowflake Scripting renvoie un tableau contenant les noms des tables temporaires. Pour plus d’informations, consultez 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;
Nom |
ID |
AGE |
---|---|---|
John Doe |
2 |
21 |
Nom |
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 » ] |
Problèmes connus¶
1. Invalid code is detected¶
SP_EXECUTESQL
peut exécuter plus d’une instruction SQL à l’intérieur de la chaîne SQL. Snowflake prend également en charge l’exécution de plusieurs instructions SQL, mais elles doivent être incluses dans un bloc BEGIN ... END
. En outre, lors de l’exécution de plusieurs instructions à partir d’un bloc BEGIN ... END
, le bloc EXECUTE IMMEDIATE
ne renverra pas de jeu de résultats. La traduction de ces cas n’est pas encore prise en charge par SnowConvert. Pour plus d’informations, consultez SSC-EWI-0030.
Ainsi, lorsque ce cas est détecté, dans le code traduit, EXECUTE IMMEDIATE
ne sera pas affecté à 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;
Nom |
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¶
Lorsque la chaîne SQL est construite dynamiquement par concaténation, SnowConvert peut ne pas détecter l’instruction qui va être exécutée. Ainsi, dans le code traduit, EXECUTE IMMEDIATE
ne sera pas assigné à 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;
Nom |
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¶
Si la chaîne SQL commence par une instruction SELECT et est suivie d’autres instructions, SnowConvert détectera qu’il s’agit d’un code valide et essaiera d’attribuer le résultat de EXECUTE IMMEDIATE
à ProcedureResultSet
. Cela entraîne une erreur de compilation. Pour plus d’informations, consultez 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;
Nom |
ID |
AGE |
---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Mary Keller |
3 |
32 |
Mundane Man |
4 |
18 |
Nom |
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 connexes¶
SSC-EWI-0030 : L’instruction ci-dessous a des utilisations de SQL dynamique
SSC-FDM-TS0028 : Les paramètres de sortie doivent avoir le même ordre que celui dans lequel ils apparaissent dans le code exécuté.
SSC-FDM-0020 : Plusieurs jeux de résultats sont renvoyés dans des tables temporaires.
SP_RENAME¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
La procédure de stockage du système SP_RENAME peut être émulée dans Snowflake dans certains scénarios. En général, l’équivalent est EXECUTE IMMEDIATE utilisant une instruction dynamique avec ALTER TABLE et les paramètres d’origine.
Exemples de traduction pour les tables¶
Source¶
EXEC sp_rename 'TABLE1', 'TABLENEW1'
Sortie¶
EXECUTE IMMEDIATE 'ALTER TABLE TABLE1 RENAME TO TABLENEW1';
Source¶
DECLARE @varname1 nvarchar(50) = 'previous_name'
DECLARE @varname2 nvarchar(50) = 'newer_name'
EXEC sp_rename @varname1, @varname2
Sortie¶
DECLARE
VARNAME1 VARCHAR(50) := 'previous_name';
VARNAME2 VARCHAR(50) := 'newer_name';
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE ' || :VARNAME1 || ' RENAME TO ' || :VARNAME2;
END;
Exemples de traduction pour les colonnes¶
Source¶
EXEC sp_rename 'sample_BACKUP_2.column_old', 'column_new', 'COLUMN'
EXEC sp_rename 'database1.sample_BACKUP_3.column_old', 'column_new', 'COLUMN'
Sortie¶
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';
Source¶
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';
Sortie¶
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 connexes¶
SSC-EWI-TS0075 : La traduction de la procédure intégrée n’est pas prise en charge actuellement.