SnowConvert: Transact allgemeine Sprachelemente¶
Collate¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Die Transformation von Collate hängt von seinem Wert ab, da er unterstützt oder nicht unterstützt werden kann.
Derzeit sind dies die Sprachen, die für die Transformation unterstützt werden. Wenn sie in der Zusammenstellung gefunden werden, werden sie in ihre Snowflake-Entsprechung umgewandelt.
SqlSever |
Snowflake |
---|---|
Latin1_General |
EN |
Modern_Spanish |
ES |
Französisch |
FR |
Wenn die Sprache nicht eine der oben genannten ist, wird die Sortierung (Collate) kommentiert.
Da Collate in SqlServer zusätzliche Spezifikationen enthält, wie CI, CS, AI, und AS, werden nur diese unterstützt. Wenn es weitere Spezifikationen gibt, die nicht unterstützt werden, werden sie im Ergebnis kommentiert.
Quelle
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;
Erwartet
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
;
Sehen wir uns ein Collate-Beispiel in einem Create Table an
Quelle
CREATE TABLE TABLECOLLATE
(
COL1 VARCHAR COLLATE Latin1_General_CI_AS
);
Erwartet
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"}}'
;
Wie Sie sehen können, ist die Transformation von Collate innerhalb eines Selects oder einer Tabelle dieselbe.
COMPUTED COLUMN¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Beschreibung¶
Der Ausdruck einer berechneten Spalte konnte nicht umgewandelt werden.
Codebeispiel¶
Eingabecode:¶
CREATE TABLE [TestTable](
[Col1] AS (CONVERT ([REAL], ExpressionValue))
);
Ausgabecode:¶
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"}}'
;
Empfehlungen¶
Fügen Sie manuelle Änderungen an dem nicht transformierten Ausdruck hinzu.
Wenn Sie weitere Unterstützung benötigen, können Sie uns eine E-Mail an snowconvert-support@snowflake.com senden
Zugehörige EWIs¶
[SSC-FDM-TS0014](../../general/technical-documentation/issues-and-troubleshooting/functional-difference/sqlServerFDM. md#ssc-fdm-ts0014): Berechnete Spalte transformiert.
OUTER APPLY¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Beschreibung¶
Wenn OUTER APPLY angegeben ist, wird für jede Zeile des linken Rowsets eine Zeile erzeugt, auch wenn der rechtsseitige Rowset-Ausdruck für diese Zeile ein leeres Rowset liefert. (OUTER APPLY-Definition)
Syntax¶
Apply_Operator :=
'CROSS' 'APPLY'
| 'OUTER' 'APPLY'.
Snowflake-Äquivalenz¶
Trotz der nicht unterstützten Anweisung OUTER APPLY in Snowflake gibt es eine gleichwertige Anweisung, die LATERAL lautet. Daher wird die Übersetzung für die Anweisung durchgeführt, um die gleiche Funktionalität durch die Verwendung von alternativen Lösungen zu erhalten.
Dennoch gibt es für die Anweisung LATERAL in Snowflake zwei Varianten der Syntax. In der Tat wird in dieser speziellen Übersetzung die Variante INNER JOIN LATERAL verwendet.
Die INNER JOIN LATERAL Grammatik von Snowflake lautet wie folgt:
SELECT ...
FROM <left_hand_table_expression> INNER JOIN LATERAL ( <inline_view> )
...
Bemerkung
<inline\view> darf kein Tabellenname sein.
Und die einzelne LATERAL-Anweisung wird unten angezeigt:
SELECT ...
FROM <left_hand_table_expression>, LATERAL ( <inline_view> )
...
Beispielhafte Quelle¶
Das folgende Beispiel zeigt eine allgemeine Übersetzung zwischen OUTER APPLY und 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 |
Bekannte Probleme¶
Da die Übersetzung eine Äquivalenz aus der Eingabe ist, gibt es einige Beschränkungen.
TOP- und WHERE-Anweisungen lassen sich auf eine optimale Verhaltensweise überprüfen.
Ein Korrelationsname am Ende der Anweisung kann erforderlich sein. In Snowflake stellt die Abfrage kein Problem dar, wenn der Korrelationsname nicht in der Abfrage enthalten ist, aber die Funktionalität kann sich ändern und ist nicht Teil des akzeptierten Musters in 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
);
Bei bestimmten Anweisungen, die nicht unterstützt werden, kann der gesamte Blockcode auskommentiert werden (Beispiel aus: JSON-Beispiel).
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
Zugehörige EWIs¶
Keine zugehörigen EWIs.
USE¶
Applies to
[x] SQL Server
USE-Anweisung hat ihre eigene Entsprechung in Snowflake. Die Anweisung wird in die USE DATABASE-Anweisung in Snowflake übersetzt.
Beispiele für Übersetzungen¶
Quelle¶
USE [MY DATABASE]
Ausgabe¶
USE DATABASE "MY DATABASE";
Name der Datenbank¶
Der database name
, der in der Anweisung USE
angegeben ist, kann sich ändern, wenn er innerhalb von eckigen Klammern ([ ])
steht. Die erste und die letzte Klammer werden durch Anführungszeichen ersetzt. Beispiel:
Quelle¶
[MYDATABASE]
[[[MYDATABASE]]
Ausgabe¶
"MYDATABASE"
"[[MYDATABASE]"
Benutzerdefinierte Datenbank¶
Wenn ein Benutzer dem Konvertierungstool mit dem Parameter -d
einen benutzerdefinierten Datenbanknamen angibt, der auf alle Objekte angewendet werden soll, und möchte, dass die USE Anweisungen transformiert werden, sollte der Datenbankname nur auf die USE
-Anweisung und nicht auf die Objekte angewendet werden. Dadurch wird die in der USE-Anweisung angegebene Datenbank außer Kraft gesetzt. Beispiel:
Quelle¶
-- Additional Params: -d MYCUSTOMDB
USE [MY DATABASE]
CREATE TABLE [TableName1].[TableName2](
[ColumnName1] varchar NULL
);
Ausgabe¶
-- 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"}}'
;
Bekannte Probleme ¶
Es wurden keine Probleme gefunden.
Zugehörige EWIs ¶
Keine zugehörigen EWIs.
EXECUTE¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Die Übersetzung für EXEC- oder EXECUTE-Anweisungen wird in Snowflake nicht unterstützt, aber sie wird in CALL-Anweisung übersetzt.
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Eingabe¶
Exec db.sp1
Ausgabe¶
CALL db.sp1();
Weitere Informationen über Execute finden Sie unter: In Prozeduren ausführen.
Bekannte Probleme ¶
Es wurden keine Probleme gefunden.
Zugehörige EWIs ¶
Keine zugehörigen EWIs.
Systemgespeicherte Prozeduren¶
SP_EXECUTESQL¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Beschreibung¶
Die systemgespeicherte Prozedur SP_EXECUTESQL wird verwendet, um eine Transact-SQL-Anweisung oder einen Batch auszuführen, die bzw. der mehrmals wiederverwendet werden kann oder dynamisch erstellt wird. Die Anweisung oder der Batch kann eingebettete Parameter enthalten.
Diese Funktionalität kann in Snowflake durch die Anweisung EXECUTE IMMEDIATE und mit einer benutzerdefinierten Funktion (UDF) für eingebettete Parameter emuliert werden.
Weitere Informationen über die benutzerdefinierte Funktion (UDF), die für diese Übersetzung verwendet wird, finden Sie unter [TRANSFORM_SP_EXECUTE_SQL\_STRING\_UDF(STRING, STRING, ARRAY, ARRAY)](../…/general/technical-documentation/function-references/sql-server/README. md#transform_sp_execute_sql_string_udfstring-string-array-array).
Syntax¶
sp_executesql [ @stmt = ] N'statement'
[
[ , [ @params = ] N'@parameter_name data_type [ { OUT | OUTPUT } ] [ , ...n ]' ]
[ , [ @param1 = ] 'value1' [ , ...n ] ]
]
Beispielhafte Quellcode-Muster¶
Alle Muster wandeln SP_EXECUTESQL in die Anweisung EXECUTE IMMEDIATE von Snowflake um und ändern die auszuführende Zeichenfolge SQL nur, wenn Sie eingebettete Parameter verwenden.
Warnung
[SSC-EWI-0030](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0030) (Verwendung von dynamischem SQL) wird für alle Muster hinzugefügt. Auch wenn die Übersetzung für SP_EXECUTESQL mit Snowflake übereinstimmt, zeigt EWI in diesem Zusammenhang an, dass die Zeichenfolge SQL möglicherweise manuell korrigiert werden muss, damit die Übersetzung wie vorgesehen ausgeführt werden kann.
Datenkonfiguration¶
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);
Ohne eingebettete Parameter¶
Wenn keine eingebetteten Parameter verwendet werden, wird SP_EXECUTESQL in eine EXECUTE IMMEDIATE-Anweisung umgewandelt und die SQL-Zeichenfolge ohne Änderungen verwendet.
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;
Name |
ID |
AGE |
---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Maria Keller |
3 |
32 |
Mundane Mann |
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();
Name |
ID |
AGE |
---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Maria Keller |
3 |
32 |
Mundane Mann |
4 |
18 |
Mit eingebetteten Parametern für die Datenbindung¶
Bei eingebetteten Parametern für die Datenbindung wird SP_EXECUTESQL in eine EXECUTE IMMEDIATE-Anweisung umgewandelt, und die SQL-Zeichenfolge wird durch TRANSFORM_SP_EXECUTE_SQL_STRING_UDF
geändert.
Das Ergebnis von EXECUTE IMMEDIATE wird der Variablen ProcedureResultSet
zugewiesen und später als TABLE(ProcedureResultSet)
zurückgegeben.
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;
Name |
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();
Name |
ID |
AGE |
---|---|---|
John Doe |
2 |
21 |
Mit eingebetteten OUTPUT-Parametern¶
Bei eingebetteten OUTPUT-Parametern wird SP_EXECUTESQL in eine EXECUTE IMMEDIATE-Anweisung umgewandelt, und die SQL-Zeichenfolge wird durch TRANSFORM_SP_EXECUTE_SQL_STRING_UDF
geändert.
Zusätzlich wird ein SELECT $1, ..., $n INTO: outputParam1, ..., :outputParamN FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))
zu dem Ergebnis jeder Spalte zu dem entsprechenden OUTPUT-Parameter hinzugefügt.
Warnung
SSC-FDM-TS0028 wird der Anweisung SELECT INTO hinzugefügt. Es ist wichtig, dass die Parameter in der INTO-Klausel in der gleichen Reihenfolge erscheinen, wie sie in der ursprünglichen SQL -Zeichenfolge zugewiesen wurden.
Andernfalls sind manuelle Änderungen erforderlich, um diese Anforderung zu erfüllen.
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 |
Sowohl mit eingebetteten OUTPUT-Parametern als auch mit Datenbindung¶
Die Übersetzung ist dieselbe wie bei den OUTPUT-Parametern.
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 |
Parameter nicht in der Reihenfolge der Definition¶
Dieses Muster folgt den gleichen Regeln wie die vorherigen Muster. TRANSFORM_SP_EXECUTE_SQL_STRING_UDF
ersetzt die Parameterwerte in der richtigen Reihenfolge.
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 |
Direkte Werte ausführen¶
Diese Übersetzung behandelt auch die Fälle, in denen die Werte direkt zugewiesen werden, anstatt Variablen zu verwenden.
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 |
SQL-Zeichenfolge dynamisch aufgebaut¶
Dieses Muster folgt den gleichen Regeln wie die vorherigen Muster. Die Zuweisung des Ergebnisses der EXECUTE IMMEDIATE-Anweisung wird jedoch möglicherweise nicht hinzugefügt, wenn es sich bei der Zeichenfolge SQL nicht um eine einfache Abfrage mit oder ohne eingebettete Parameter handelt.
Außerdem muss die Zeichenfolge SQL mit dem literalen Wert SELECT
beginnen, damit SnowConvert korrekt erkennen kann, dass eine Anweisung SELECT ausgeführt werden soll. Weitere Informationen finden Sie im Abschnitt Bekannte Probleme.
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;
Name |
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();
Name |
ID |
AGE |
---|---|---|
John Doe |
2 |
21 |
Mehrere Resultsets zurückgeben¶
Bei Snowflake Scripting-Prozeduren kann nur ein Resultset pro Prozedur zurückgegeben werden.
Um die Verhaltensweise von Transact-SQL zu replizieren, werden zwei oder mehr Resultsets, die zurückgegeben werden sollen, in temporären Tabellen gespeichert. Die Snowflake Scripting-Prozedur gibt ein Array mit den Namen der temporären Tabellen zurück. Weitere Informationen finden Sie unter [SSC-FDM-0020](../../general/technical-documentation/issues-and-troubleshooting/functional-difference/generalFDM. md#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;
Name |
ID |
AGE |
---|---|---|
John Doe |
2 |
21 |
Name |
ID |
AGE |
---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Maria Keller |
3 |
32 |
Mundane Mann |
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“ ] |
Bekannte Probleme¶
1. Invalid code is detected¶
SP_EXECUTESQL
kann mehr als eine SQL-Anweisung innerhalb der SQL Zeichenfolge ausführen. Snowflake unterstützt auch die Ausführung mehrerer SQL-Anweisungen, die jedoch in einen BEGIN... END
-Block eingeschlossen sein müssen. Wenn Sie außerdem mehrere Anweisungen aus einem BEGIN... END
Block ausführen, gibt EXECUTE IMMEDIATE
kein Resultset zurück. Die Übersetzung für diese Fälle wird von SnowConvert noch nicht unterstützt. Weitere Informationen finden Sie unter [SSC-EWI-0030](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0030).
Wenn also dieser Fall erkannt wird, wird im übersetzten Code EXECUTE IMMEDIATE
nicht ProcedureResultSet
zugewiesen.
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;
Name |
ID |
AGE |
---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Maria Keller |
3 |
32 |
Mundane Mann |
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¶
Wenn die Zeichenfolge SQL dynamisch durch Verkettungen aufgebaut wird, erkennt SnowConvert möglicherweise nicht, welche Anweisung ausgeführt werden soll. Im übersetzten Code wird EXECUTE IMMEDIATE
also nicht ProcedureResultSet
zugewiesen.
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;
Name |
ID |
AGE |
---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Maria Keller |
3 |
32 |
Mundane Mann |
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¶
Wenn die Zeichenfolge SQL mit einer Anweisung SELECT beginnt und von weiteren Anweisungen gefolgt wird, erkennt SnowConvert dies als gültigen Code und versucht, das Ergebnis EXECUTE IMMEDIATE
dem ProcedureResultSet
zuzuweisen. Dies führt zu einem Kompilierungsfehler. Weitere Informationen finden Sie unter [SSC-EWI-0030](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#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;
Name |
ID |
AGE |
---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Maria Keller |
3 |
32 |
Mundane Mann |
4 |
18 |
Name |
ID |
AGE |
---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Maria Keller |
3 |
32 |
Mundane Mann |
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.
Zugehörige EWIs¶
[SSC-EWI-0030](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0030): Die folgende Anweisung enthält dynamische SQL-Verwendungen
[SSC-FDM-TS0028](../../general/technical-documentation/issues-and-troubleshooting/functional-difference/sqlServerFDM. md#ssc-fdm-ts0028): Die Ausgabeparameter müssen die gleiche Reihenfolge haben, wie sie im ausgeführten Code erscheinen.
[SSC-FDM-0020](../../general/technical-documentation/issues-and-troubleshooting/functional-difference/generalFDM. md#ssc-fdm-0020): Mehrere Resultsets werden in temporären Tabellen zurückgegeben.
SP_RENAME¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Der SP_RENAME-Systemspeicherprozess kann in Snowflake in bestimmten Szenarien emuliert werden. Im Allgemeinen entspricht dies dem Befehl EXECUTE IMMEDIATE unter Verwendung einer dynamischen Anweisung mit ALTER TABLE und den ursprünglichen Parametern.
Übersetzungsbeispiele für Tabellen¶
Quelle¶
EXEC sp_rename 'TABLE1', 'TABLENEW1'
Ausgabe¶
EXECUTE IMMEDIATE 'ALTER TABLE TABLE1 RENAME TO TABLENEW1';
Quelle¶
DECLARE @varname1 nvarchar(50) = 'previous_name'
DECLARE @varname2 nvarchar(50) = 'newer_name'
EXEC sp_rename @varname1, @varname2
Ausgabe¶
DECLARE
VARNAME1 VARCHAR(50) := 'previous_name';
VARNAME2 VARCHAR(50) := 'newer_name';
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE ' || :VARNAME1 || ' RENAME TO ' || :VARNAME2;
END;
Übersetzungsbeispiele für Spalten¶
Quelle¶
EXEC sp_rename 'sample_BACKUP_2.column_old', 'column_new', 'COLUMN'
EXEC sp_rename 'database1.sample_BACKUP_3.column_old', 'column_new', 'COLUMN'
Ausgabe¶
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';
Quelle¶
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';
Ausgabe¶
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;
Zugehörige EWIs¶
[SSC-EWI-TS0075](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/sqlServerEWI. md#ssc-ewi-ts0075): Übersetzung für integrierte Prozedur wird derzeit nicht unterstützt.