SnowConvert: Snowflake Scripting¶
BEGIN- und COMMIT-Transaktion¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Beschreibung¶
Snowflake SQL kann eine Transaktion explizit durch die Ausführung einer BEGIN-Anweisung gestartet werden. Snowflake unterstützt die Synonyme BEGINWORK
und BEGINTRANSACTION
. Snowflake empfiehlt die Verwendung von BEGINTRANSACTION
.
Eine Transaktion kann explizit durch die Ausführung von COMMIT beendet werden. Lesen Sie hier mehr über Snowflake-Transaktionen.
Beispielhafte Quellcode-Muster ¶
Die folgenden Beispiele zeigen die Transaktionsanweisungen BEGIN und COMMIT.
Transact-SQL ¶
CREATE PROCEDURE TestTransaction
AS
BEGIN
DROP TABLE IF EXISTS NEWTABLE;
CREATE TABLE NEWTABLE(COL1 INT, COL2 VARCHAR);
BEGIN TRANSACTION;
INSERT INTO NEWTABLE VALUES (1, 'MICHAEL');
INSERT INTO NEWTABLE VALUES(2, 'JACKSON');
COMMIT TRANSACTION;
END
CREATE PROCEDURE TestTransaction
AS
BEGIN
DROP TABLE IF EXISTS NEWTABLE;
CREATE TABLE NEWTABLE(COL1 INT, COL2 VARCHAR);
BEGIN TRANSACTION LabelA;
INSERT INTO NEWTABLE VALUES (1, 'MICHAEL');
INSERT INTO NEWTABLE VALUES(2, 'JACKSON');
COMMIT TRANSACTION LabelA;
END
Snowflake SQL ¶
CREATE OR REPLACE PROCEDURE TestTransaction ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
DROP TABLE IF EXISTS NEWTABLE;
CREATE OR REPLACE TABLE NEWTABLE (
COL1 INT,
COL2 VARCHAR
);
BEGIN TRANSACTION;
INSERT INTO NEWTABLE VALUES (1, 'MICHAEL');
INSERT INTO NEWTABLE VALUES(2, 'JACKSON');
COMMIT;
END;
$$;
CREATE OR REPLACE PROCEDURE TestTransaction ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
DROP TABLE IF EXISTS NEWTABLE;
CREATE OR REPLACE TABLE NEWTABLE (
COL1 INT,
COL2 VARCHAR
);
BEGIN TRANSACTION
!!!RESOLVE EWI!!! /*** SSC-EWI-0101 - COMMENTED OUT TRANSACTION LABEL NAME BECAUSE IS NOT APPLICABLE IN SNOWFLAKE ***/!!!
LabelA;
INSERT INTO NEWTABLE VALUES (1, 'MICHAEL');
INSERT INTO NEWTABLE VALUES(2, 'JACKSON');
COMMIT;
END;
$$;
Bekannte Probleme¶
Verschachtelte Transaktionen werden in Snowflake nicht unterstützt. Lesen Sie die folgende Dokumentation für weitere Informationen: https://docs.snowflake.com/en/sql-reference/transactions
CALL¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Beschreibung ¶
Die Anweisung CALL wird in Snowflake Scripting nicht unterstützt, da sie Teil der Anweisung ODBC API und nicht SQL ist, daher wird diese Anweisung nicht übersetzt.
CASE¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Beschreibung¶
Transact-SQL hat zwei mögliche Formate für den CASE-Ausdruck. Beide dienen der Auswertung von Ausdrücken und der bedingten Gewinnung von Ergebnissen. Die erste bezieht sich auf einen Simple CASE-Ausdruck, der auswertet, ob ein input_expression mit einem oder mehreren when_expression übereinstimmt. Der zweite wertet jeden booleschen Ausdruck unabhängig aus. Die ELSE-Klausel wird in beiden Formaten unterstützt.
Laut der offiziellen Transact-SQL Case-Dokumentation:
CASE kann in jeder Anweisung oder Klausel verwendet werden, die einen gültigen Ausdruck erlaubt. Zum Beispiel können Sie CASE in Anweisungen wie SELECT, UPDATE, DELETE und SET und in Klauseln wie select_list, IN, WHERE, ORDER BY und HAVING verwenden.
Weitere Informationen zu Transact-SQL Case finden Sie hier.
-- Simple CASE expression:
CASE input_expression
WHEN when_expression THEN result_expression [ ...n ]
[ ELSE else_result_expression ]
END
-- Searched CASE expression:
CASE
WHEN boolean_expression THEN result_expression [ ...n ]
[ ELSE else_result_expression ]
END
Anmerkung: Transact-SQL erlaubt es, input_expression und boolean_expression optional in Klammern zu kapseln; Snowflake Scripting ebenfalls.
Beispielhafte Quellcode-Muster ¶
Die folgenden Beispiele beschreiben zwei Szenarien, in denen der CASE-Ausdruck verwendet werden kann, sowie die Unterschiede zu Snowflake Scripting.
Nach Case auswählen¶
Transact-SQL¶
CREATE OR ALTER PROCEDURE SelectCaseDemoProcedure
AS
SELECT TOP 10
LOGINID,
CASE (MARITALSTATUS)
WHEN 'S' THEN 'SINGLE'
WHEN 'M' THEN 'MARIED'
ELSE 'OTHER'
END AS status
FROM HUMANRESOURCES.EMPLOYEE;
GO
EXEC SelectCaseDemoProcedure;
CREATE OR ALTER PROCEDURE SelectCaseDemoProcedure
AS
SELECT TOP 10
LOGINID,
CASE
WHEN MARITALSTATUS = 'S' THEN 'SINGLE'
WHEN MARITALSTATUS = 'M' THEN 'MARIED'
ELSE 'OTHER'
END AS status
FROM HUMANRESOURCES.EMPLOYEE;
GO
EXEC SelectCaseDemoProcedure;
sqlLOGINID |status|
------------------------+------+
adventure-works\ken0 |SINGLE|
adventure-works\terri0 |SINGLE|
adventure-works\roberto0|MARIED|
adventure-works\rob0 |SINGLE|
adventure-works\gail0 |MARIED|
adventure-works\jossef0 |MARIED|
adventure-works\dylan0 |MARIED|
adventure-works\diane1 |SINGLE|
adventure-works\gigi0 |MARIED|
adventure-works\michael6|MARIED|
Snowflake Scripting ¶
Beachten Sie, dass es in diesem Szenario keine Unterschiede in Bezug auf den CASE-Ausdruck selbst gibt.
Warnung
Die Deklaration und Zuweisung der res
-Variablen dient dazu, die Funktionsäquivalenz zwischen beiden Sprachen zu demonstrieren. Sie erscheint nicht in der eigentlichen Ausgabe.
CREATE OR REPLACE PROCEDURE SelectCaseDemoProcedure ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
ProcedureResultSet RESULTSET;
BEGIN
ProcedureResultSet := (
SELECT TOP 10
LOGINID,
CASE (MARITALSTATUS)
WHEN 'S' THEN 'SINGLE'
WHEN 'M' THEN 'MARIED'
ELSE 'OTHER'
END AS status
FROM
HUMANRESOURCES.EMPLOYEE);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL SelectCaseDemoProcedure();
CREATE OR REPLACE PROCEDURE SelectCaseDemoProcedure ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
ProcedureResultSet RESULTSET;
BEGIN
ProcedureResultSet := (
SELECT TOP 10
LOGINID,
CASE
WHEN MARITALSTATUS = 'S' THEN 'SINGLE'
WHEN MARITALSTATUS = 'M' THEN 'MARIED'
ELSE 'OTHER'
END AS status
FROM
HUMANRESOURCES.EMPLOYEE);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL SelectCaseDemoProcedure();
LOGINID |STATUS|
-----------------------+------+
adventure-worksken0 |SINGLE|
adventure-works erri0 |SINGLE|
adventure-worksoberto0 |MARIED|
adventure-worksob0 |SINGLE|
adventure-worksgail0 |MARIED|
adventure-worksjossef0 |MARIED|
adventure-worksdylan0 |MARIED|
adventure-worksdiane1 |SINGLE|
adventure-worksgigi0 |MARIED|
adventure-worksmichael6|MARIED|
Mit Case einstellen¶
Die Datenbank AdventureWorks2019 wurde in beiden Sprachen verwendet, um die gleichen Ergebnisse zu erzielen.
Transact-SQL¶
CREATE OR ALTER PROCEDURE SetCaseDemoProcedure
AS
DECLARE @value INT;
DECLARE @result INT;
SET @value = 5;
SET @result =
CASE @value
WHEN 1 THEN @value * 10
WHEN 3 THEN @value * 20
WHEN 5 THEN @value * 30
WHEN 7 THEN @value * 40
ELSE -1
END;
RETURN @result
GO
DECLARE @result INT;
EXEC @result = SetCaseDemoProcedure;
PRINT @result;
CREATE OR ALTER PROCEDURE SetCaseDemoProcedure
AS
DECLARE @value INT;
DECLARE @result INT;
SET @value = 5;
SET @result =
CASE
WHEN @value = 1 THEN @value * 10
WHEN @value = 3 THEN @value * 20
WHEN @value = 5 THEN @value * 30
WHEN @value = 7 THEN @value * 40
ELSE -1
END;
RETURN @result
GO
DECLARE @result INT;
EXEC @result = SetCaseDemoProcedure;
PRINT @result;
|result|
|------|
|150 |
Snowflake Scripting ¶
Warnung
Snowflake Scripting erlaubt es nicht, einen CASE-Ausdruck direkt auf eine Variable zu setzen. Beide Transact-SQL CASE-Ausdruckformate entsprechen der folgenden Grammatik in Snowflake Scripting.
CREATE OR REPLACE PROCEDURE SetCaseDemoProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
VALUE INT;
RESULT INT;
BEGIN
VALUE := 5;
CASE (:VALUE)
WHEN 1 THEN
RESULT := :VALUE * 10;
WHEN 3 THEN
RESULT := :VALUE * 20;
WHEN 5 THEN
RESULT := :VALUE * 30;
WHEN 7 THEN
RESULT := :VALUE * 40;
ELSE
RESULT := -1;
END;
RETURN :RESULT;
END;
$$;
DECLARE
RESULT INT;
BEGIN
CALL SetCaseDemoProcedure();
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Print' NODE ***/!!!
PRINT @result;
END;
CREATE OR REPLACE PROCEDURE SetCaseDemoProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
VALUE INT;
RESULT INT;
BEGIN
VALUE := 5;
CASE
WHEN :VALUE = 1 THEN
RESULT := :VALUE * 10;
WHEN :VALUE = 3 THEN
RESULT := :VALUE * 20;
WHEN :VALUE = 5 THEN
RESULT := :VALUE * 30;
WHEN :VALUE = 7 THEN
RESULT := :VALUE * 40;
ELSE
RESULT := -1;
END;
RETURN :RESULT;
END;
$$;
DECLARE
RESULT INT;
BEGIN
CALL SetCaseDemoProcedure();
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Print' NODE ***/!!!
PRINT @result;
END;
|result|
|------|
|150 |
Bekannte Probleme¶
Es wurden keine Probleme gefunden.
Zugehörige EWIs¶
[SSC-EWI-0073](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0073): Überprüfung der Funktionsäquivalenz ausstehend.
CREATE PROCEDURE¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Beschreibung¶
Die CREATE PROCEDURE-Anweisung ermöglicht die Erstellung von gespeicherten Prozeduren, die Folgendes können:
Eingabeparameter akzeptieren und mehrere Werte in Form von Ausgabeparametern an die aufrufende Prozedur oder den Batch zurückgeben.
Programmieranweisungen enthalten, die Operationen in der Datenbank durchführen, einschließlich des Aufrufs anderer Prozeduren.
Einen Statuswert an eine aufrufende Prozedur oder einen Batch zurückgeben, um Erfolg oder Misserfolg (und den Grund für den Misserfolg) anzuzeigen.
Weitere Informationen zu Transact-SQL CREATE PROCEDURE finden Sie hier.
CREATE [ OR ALTER ] { PROC | PROCEDURE }
[schema_name.] procedure_name [ ; number ]
[ { @parameter [ type_schema_name. ] data_type }
[ VARYING ] [ = default ] [ OUT | OUTPUT | [READONLY]
] [ ,...n ]
[ WITH <procedure_option> [ ,...n ] ]
[ FOR REPLICATION ]
AS { [ BEGIN ] sql_statement [;] [ ...n ] [ END ] }
[;]
Beispielhafte Quellcode-Muster¶
Gespeicherte Prozedur ohne Body¶
Eine gespeicherte Prozedur ohne Body ist ein ungewöhnliches Szenario, das in Transact-SQL erlaubt ist. Snowflake Scripting erlaubt es nicht, Prozeduren ohne Body zu definieren, aber das folgende Beispiel zeigt die Gleichwertigkeit.
Transact-SQL¶
CREATE PROC SampleProcedure AS;
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE SampleProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
RETURN '';
END;
$$;
Grundlegende gespeicherte Prozedur¶
Das folgende Beispiel zeigt eine einfache gespeicherte Prozedur, mit der eine neue Datenschutzabteilung in die Datenbank AdventureWorks2019 aufgenommen wird.
Transact-SQL¶
CREATE OR ALTER PROCEDURE Add_Privacy_Department
AS
EXECUTE ('INSERT INTO HumanResources.Department VALUES (''Privacy'', ''Executive General and Administration'', default)');
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE Add_Privacy_Department ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE 'INSERT INTO HumanResources.Department VALUES ('Privacy', 'Executive General and Administration', default);';
END;
$$;
Alter-Prozedur¶
Die Transformation für die Prozedur ALTER entspricht der Basisprozedur.
Transact-SQL¶
ALTER PROCEDURE procedureName
AS
SELECT 1 AS ThisDB;
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE procedureName ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
ProcedureResultSet RESULTSET;
BEGIN
ProcedureResultSet := (
SELECT 1 AS ThisDB);
RETURN TABLE(ProcedureResultSet);
END;
$$;
Parameter verwenden¶
Sie können Parameter verwenden, um Ihre Logik zu steuern oder dynamische SQL Anweisungen innerhalb Ihrer gespeicherten Prozedur zu konstruieren. Im folgenden Beispiel wird eine einfache gespeicherte Prozedur SetNewPrice konstruiert, die einen neuen Produktpreis auf der Grundlage der vom Aufrufer gesendeten Argumente festlegt.
Transact-SQL¶
CREATE OR ALTER PROCEDURE SetNewPrice @ProductID INT, @NewPrice MONEY
AS
BEGIN
DECLARE @dynSqlStatement AS VARCHAR(300);
SET @dynSqlStatement = 'UPDATE Production.ProductListPriceHistory SET ListPrice = ' + CAST(@NewPrice AS VARCHAR(10)) + ' WHERE ProductID = ' + CAST(@ProductID AS VARCHAR(10)) + ' AND EndDate IS NULL';
EXECUTE (@dynSqlStatement);
END;
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE SetNewPrice (PRODUCTID INT, NEWPRICE NUMBER(38, 4))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
DYNSQLSTATEMENT VARCHAR(300);
BEGIN
DYNSQLSTATEMENT := 'UPDATE Production.ProductListPriceHistory
SET
ListPrice = ' || CAST(:NEWPRICE AS VARCHAR(10)) || '
WHERE
ProductID = ' || CAST(:PRODUCTID AS VARCHAR(10)) || '
AND EndDate IS NULL;';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE :DYNSQLSTATEMENT;
END;
$$;
Ausgabeparameter¶
Das Transact-SQL-Ausgabeschlüsselwort zeigt an, dass der Parameter ein Ausgabeparameter ist, dessen Wert an den Aufrufer der gespeicherten Prozedur zurückgegeben wird. Die folgende Prozedur gibt zum Beispiel die Anzahl der Urlaubsstunden eines bestimmten Mitarbeiters zurück.
Transact-SQL¶
CREATE PROCEDURE GetVacationHours
@employeeId INT,
@vacationHours INT OUTPUT
AS
BEGIN
SELECT @vacationHours = VacationHours
FROM HumanResources.Employee
WHERE NationalIDNumber = @employeeID
END;
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE GetVacationHours (EMPLOYEEID INT, VACATIONHOURS INT)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
SELECT
VacationHours
INTO
:VACATIONHOURS
FROM
HumanResources.Employee
WHERE
NationalIDNumber = :EMPLOYEEID;
RETURN VACATIONHOURS;
END;
$$;
Warnung
Von einer gespeicherten Snowflake Skripting-Prozedur kann nur 1 Ausgabeparameter zurückgegeben werden.
Optionale Parameter¶
Ein Parameter gilt als optional, wenn bei der Deklaration des Parameters ein Standardwert angegeben wurde. Es ist nicht notwendig, einen Wert für einen optionalen Parameter in einem Prozeduraufruf anzugeben.
Transact-SQL¶
CREATE PROCEDURE OPTIONAL_PARAMETER @VAR1 INT = 1, @VAR2 INT = 2
AS
BEGIN
RETURN NULL;
END
GO
EXEC OPTIONAL_PARAMETER @VAR2 = 4
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE OPTIONAL_PARAMETER (VAR1 INT DEFAULT 1, VAR2 INT DEFAULT 2)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
RETURN NULL;
END;
$$;
CALL OPTIONAL_PARAMETER(VAR2 => 4);
EXECUTE AS¶
Die EXECUTE AS-Klausel von Transact-SQL definiert den Ausführungskontext der gespeicherten Prozedur und gibt an, welches Benutzerkonto die Datenbank-Engine verwendet, um die Berechtigungen für Objekte zu überprüfen, auf die innerhalb der Prozedur verwiesen wird. Wir können zum Beispiel die vorherige GetVacationHours-Prozedur ändern, um verschiedene Ausführungskontexte zu definieren.
Eigentümer (Standard in Snowflake Scripting)
Transact-SQL¶
CREATE OR ALTER PROCEDURE GetVacationHours
@employeeId INT,
@vacationHours INT OUTPUT
WITH EXECUTE AS OWNER
AS
BEGIN
SELECT @vacationHours = VacationHours
FROM HumanResources.Employee
WHERE NationalIDNumber = @employeeID
END;
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE GetVacationHours (EMPLOYEEID INT, VACATIONHOURS INT)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS OWNER
AS
$$
BEGIN
SELECT
VacationHours
INTO
:VACATIONHOURS
FROM
HumanResources.Employee
WHERE
NationalIDNumber = :EMPLOYEEID;
RETURN VACATIONHOURS;
END;
$$;
Aufrufer
Transact-SQL¶
CREATE OR ALTER PROCEDURE GetVacationHours
@employeeId INT,
@vacationHours INT OUTPUT
WITH EXECUTE AS CALLER
AS
BEGIN
SELECT @vacationHours = VacationHours
FROM HumanResources.Employee
WHERE NationalIDNumber = @employeeID
END;
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE GetVacationHours (EMPLOYEEID INT, VACATIONHOURS INT)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
SELECT
VacationHours
INTO
:VACATIONHOURS
FROM
HumanResources.Employee
WHERE
NationalIDNumber = :EMPLOYEEID;
RETURN VACATIONHOURS;
END;
$$;
Warnung
SELF und spezifische Benutzer (user_name)-Ausführungskontexte werden in Snowflake Scripting nicht unterstützt.
READONLY AND VARYING PARAMETERS¶
Snowflake unterstützt die Parametertypen READONLY
und VARYING
nicht, stattdessen wird ein FDM hinzugefügt.
Transact-SQL¶
CREATE OR ALTER PROCEDURE GetVacationHours
@Param1 INT READONLY,
@Param2 INT VARYING
AS
BEGIN
SELECT * FROM Table1;
END;
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE GetVacationHours (PARAM1 INT !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'READONLY PARAMETERS' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!, PARAM2 INT !!!RESOLVE EWI!!! /*** SSC-EWI-0058 - FUNCTIONALITY FOR 'VARYING PARAMETERS' IS NOT CURRENTLY SUPPORTED BY SNOWFLAKE SCRIPTING ***/!!!)
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
ProcedureResultSet RESULTSET;
BEGIN
ProcedureResultSet := (
SELECT
*
FROM
Table1);
RETURN TABLE(ProcedureResultSet);
END;
$$;
Bekannte Probleme¶
Nicht unterstützte optionale Argumente¶
[VARYING] Gilt nur für Cursor-Parameter. Gibt das Resultset an, das als Ausgabeparameter unterstützt wird. Dieser Parameter wird von der Prozedur dynamisch erstellt und sein Inhalt kann variieren. Snowflake Scripting unterstützt CURSOR nicht als gültigen Rückgabedatentyp.
[= default] Macht einen Parameter durch die Definition eines Standardwertes optional. Snowflake Scripting unterstützt von Haus aus keine Standardparameterwerte.
[READONLY] Zeigt an, dass der Parameter im Body der Prozedur nicht aktualisiert oder geändert werden kann. Derzeit in Snowflake Scripting nicht unterstützt.
[WITH RECOMPILE] Zwingt die Datenbankmaschine, den Abfrageplan der gespeicherten Prozedur bei jeder Ausführung zu kompilieren. Derzeit in Snowflake Scripting nicht unterstützt.
[WITH ENCRYPTION] Wird verwendet, um den Text einer gespeicherten Prozedur zu verschlüsseln. Nur Benutzer mit Zugriff auf Systemtabellen oder Datenbankdateien (z. B. Sysadmin-Benutzer) können nach der Erstellung auf den Prozedurtext zugreifen. Derzeit in Snowflake Scripting nicht unterstützt.
[FOR REPLICATION] Schränkt die gespeicherte Prozedur so ein, dass sie nur während der Replikation ausgeführt wird. Derzeit in Snowflake Scripting nicht unterstützt.
Zugehörige EWIS¶
[SSC-EWI-0030](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0030): Die nachstehende Anweisung enthält Verwendungen von dynamischen SQL.
[SSC-EWI-0058](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0058): Die Funktionalität wird derzeit nicht von Snowflake Scripting unterstützt.
CURSOR¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Beschreibung¶
Transact SQL-Anweisungen erzeugen ein komplettes Resultset, aber es gibt Zeiten, in denen die Ergebnisse am besten Zeile für Zeile verarbeitet werden. Wenn Sie einen Cursor auf ein Resultset öffnen, können Sie das Resultset zeilenweise bearbeiten. Sie können einen Cursor einer Variablen oder einem Parameter mit dem Datentyp Cursor zuweisen. Weitere Informationen finden Sie hier.
//ISO Syntax
DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR
FOR select_statement
[ FOR { READ ONLY | UPDATE [ OF column_name [ ,...n ] ] } ]
[;]
//Transact-SQL Extended Syntax
DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ]
[ FORWARD_ONLY | SCROLL ]
[ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
[ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
[ TYPE_WARNING ]
FOR select_statement
[ FOR UPDATE [ OF column_name [ ,...n ] ] ]
[;]
FETCH
[ [ NEXT | PRIOR | FIRST | LAST
| ABSOLUTE { n | @nvar }
| RELATIVE { n | @nvar }
]
FROM
]
{ { [ GLOBAL ] cursor_name } | @cursor_variable_name }
[ INTO @variable_name [ ,...n ] ]
OPEN { { [ GLOBAL ] cursor_name } | cursor_variable_name }
CLOSE { { [ GLOBAL ] cursor_name } | cursor_variable_name }
DEALLOCATE { { [ GLOBAL ] cursor_name } | @cursor_variable_name }
Beispielhafte Quellcode-Muster¶
Transact-SQL¶
Beachten Sie, dass die folgenden Parameter bereits von Snowflake Scripting unterstützt werden.
[LOCAL].
[FORWARD_ONLY].
[FAST_FORWARD] Gibt ein FORWARD\_ONLY (nurFETCH NEXT) und READ_ONLY an
[READ_ONLY] die WHERE CURRENT OF existiert nicht in Snowflake Scripting.
CREATE TABLE vEmployee (
PersonID INT,
LastName VARCHAR(255),
FirstName VARCHAR(255),
);
INSERT INTO vEmployee(PersonID, LastName, FirstName)
VALUES
(1, 'AA', 'A'),
(2, 'BB', 'B'),
(3, 'CC', 'C'),
(4, 'DD', 'D'),
(5, 'EE', 'E'),
(6, 'FF', 'F'),
(7, 'GG', 'G');
CREATE OR ALTER PROCEDURE CursorExample
AS
DECLARE
@CursorVar CURSOR,
@firstName VARCHAR;
SET @CursorVar = CURSOR LOCAL FORWARD_ONLY STATIC READ_ONLY
FOR
SELECT FirstName
FROM vEmployee;
OPEN @CursorVar;
FETCH NEXT FROM @CursorVar INTO @firstName;
FETCH NEXT FROM @CursorVar INTO @firstName;
CLOSE @CursorVar;
SELECT @firstName;
GO
B
Snowflake Scripting¶
CREATE OR REPLACE TABLE vEmployee (
PersonID INT,
LastName VARCHAR(255),
FirstName VARCHAR(255)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
;
INSERT INTO vEmployee (PersonID, LastName, FirstName)
VALUES
(1, 'AA', 'A'),
(2, 'BB', 'B'),
(3, 'CC', 'C'),
(4, 'DD', 'D'),
(5, 'EE', 'E'),
(6, 'FF', 'F'),
(7, 'GG', 'G');
CREATE OR REPLACE PROCEDURE CursorExample ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
CURSORVAR CURSOR
FOR
SELECT FirstName
FROM vEmployee;
FIRSTNAME VARCHAR;
ProcedureResultSet RESULTSET;
BEGIN
OPEN CURSORVAR;
FETCH
CURSORVAR
INTO
:FIRSTNAME;
FETCH
CURSORVAR
INTO
:FIRSTNAME;
CLOSE CURSORVAR;
ProcedureResultSet := (
SELECT
:FIRSTNAME);
RETURN TABLE(ProcedureResultSet);
END;
$$;
B
Bekannte Probleme¶
Die folgenden Parameter werden nicht unterstützt:
DECLARE CURSOR
\ GLOBAL ] Ermöglicht den Verweis auf den Cursornamen in jeder gespeicherten Prozedur oder jedem Batch, der von der Verbindung ausgeführt wird. Snowflake Scripting erlaubt die Verwendung des Cursors nur lokal.
[ SCROLL ] Snowflake Scripting unterstützt nur FETCH NEXT.
[ KEYSET | DYNAMIC ] Wenn nach dem Öffnen eines Cursors eine Aktualisierung an der Tabelle vorgenommen wird, können diese Optionen einige der Änderungen beim Abrufen des Cursors anzeigen. Snowflake Scripting unterstützt nur STATIC, d.h. nach dem Öffnen des Cursors werden die Änderungen an der Tabelle vom Cursor nicht erkannt.
[SCROLL_LOCKS] Gibt an, dass positionierte Aktualisierungen oder Löschungen, die über den Cursor vorgenommen werden, garantiert erfolgreich sind. Snowflake Scripting kann dies nicht garantieren.
[OPTIMISTIC] Wenn eine Aktualisierung oder Löschung über den Cursor erfolgt, werden Vergleiche von Zeitstempelspaltenwerten oder ein Prüfsummenwert verwendet, wenn die Tabelle keine Zeitstempelspalte hat, um festzustellen, ob die Zeile geändert wurde, nachdem sie in den Cursor eingelesen wurde. Snowflake Scripting verfügt nicht über einen internen Prozess zur Replikation.
[TYPE_WARNING]
FETCH
[PRIOR | FIRST | LAST] Snowscripting unterstützt nur NEXT.
[ABSOLUTE] Snowflake Scripting unterstützt nur NEXT, aber die Verhaltensweise kann repliziert werden.
[RELATIVE] Snowflake Scripting, aber die Verhaltensweise kann repliziert werden.
\ GLOBAL ] Ermöglicht den Verweis auf den Cursornamen in jeder gespeicherten Prozedur oder jedem Batch, der von der Verbindung ausgeführt wird. Snowflake Scripting erlaubt die Verwendung des Cursors nur lokal.
FETCH ohne INTO wird nicht unterstützt.
Wenn sich die Anweisung FETCH innerhalb einer Schleife befindet, wird dies als komplexes Muster betrachtet, da es sich auf die Leistung des von Snowflake übersetzten Codes auswirken kann. Weitere Informationen finden Sie im Abschnitt „Verwandte Themen“.
Beispiel innerhalb der Schleife abrufen¶
CREATE OR ALTER PROCEDURE cursor_procedure1
AS
BEGIN
DECLARE cursor1 CURSOR FOR SELECT col1 FROM my_table;
WHILE 1=0
BEGIN
FETCH NEXT FROM @cursor1 INTO @variable1;
END
END;
CREATE OR REPLACE PROCEDURE cursor_procedure1 ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
--** SSC-FDM-TS0013 - SNOWFLAKE SCRIPTING CURSOR ROWS ARE NOT MODIFIABLE **
cursor1 CURSOR
FOR
SELECT
col1
FROM
my_table;
BEGIN
WHILE (1=0) LOOP
--** SSC-PRF-0003 - FETCH INSIDE A LOOP IS CONSIDERED A COMPLEX PATTERN, THIS COULD DEGRADE SNOWFLAKE PERFORMANCE. **
FETCH
CURSOR1
INTO
:VARIABLE1;
END LOOP;
END;
$$;
OPEN
\ GLOBAL ] Ermöglicht den Verweis auf den Cursornamen in jeder gespeicherten Prozedur oder jedem Batch, der von der Verbindung ausgeführt wird. Snowflake Scripting erlaubt die Verwendung des Cursors nur lokal.
CLOSE
\ GLOBAL ] Ermöglicht den Verweis auf den Cursornamen in jeder gespeicherten Prozedur oder jedem Batch, der von der Verbindung ausgeführt wird. Snowflake Scripting erlaubt die Verwendung des Cursors nur lokal.
DEALLOCATED entfernt eine Cursor-Referenz und es gibt keine Entsprechung in Snowflake Scripting.
WHERE CURRENT OF: Die Verwendung dieser Anweisung wird nicht unterstützt, zum Beispiel:
CREATE OR ALTER PROCEDURE CursorWithCurrent
AS
DECLARE
@CursorVar CURSOR;
SET @CursorVar = CURSOR
FOR
SELECT FirstName
FROM vEmployee;
OPEN @CursorVar;
FETCH NEXT FROM @CursorVar;
FETCH NEXT FROM @CursorVar;
UPDATE vEmployee SET LastName = 'Changed' WHERE CURRENT OF @CursorVar;
CLOSE @CursorVar;
GO
Umgebungsvariablen
@@CURSOR_ROWS
@@FETCH_STATUS
Zugehörige EWIs¶
[SSC-FDM-TS0013](../../general/technical-documentation/issues-and-troubleshooting/functional-difference/sqlServerFDM. md#ssc-fdm-ts0013): Snowflake Scripting Cursor-Zeilen sind nicht änderbar.
[SSC-PRF-0003](../../general/technical-documentation/issues-and-troubleshooting/performance-review/README. md#ssc-prf-0003): Fetch innerhalb einer Schleife wird als komplexes Muster betrachtet, was die Leistung von Snowflake beeinträchtigen kann.
DECLARE¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Beschreibung¶
Die Transact SQL DECLARE-Anweisung ermöglicht die Erstellung von Variablen, die im Rahmen des Batches oder einer gespeicherten Prozedur verwendet werden können. Weitere Informationen zu Transact-SQL DECLARE finden Sie hier.
-- Syntax for SQL Server and Azure SQL Database
DECLARE
{
{ @local_variable [AS] data_type [ = value ] }
| { @cursor_variable_name CURSOR }
} [,...n]
| { @table_variable_name [AS] <table_type_definition> }
<table_type_definition> ::=
TABLE ( { <column_definition> | <table_constraint> } [ ,...n] )
<column_definition> ::=
column_name { scalar_data_type | AS computed_column_expression }
[ COLLATE collation_name ]
[ [ DEFAULT constant_expression ] | IDENTITY [ (seed ,increment ) ] ]
[ ROWGUIDCOL ]
[ <column_constraint> ]
<column_constraint> ::=
{ [ NULL | NOT NULL ]
| [ PRIMARY KEY | UNIQUE ]
| CHECK ( logical_expression )
| WITH ( <index_option > )
}
<table_constraint> ::=
{ { PRIMARY KEY | UNIQUE } ( column_name [ ,...n] )
| CHECK ( search_condition )
}
Beispielhafte Quellcode-Muster¶
Variablen deklarieren¶
Variablen können auf unterschiedliche Weise erstellt werden. Variablen können einen Standardwert haben oder nicht und es können mehrere Variablen in derselben Zeile deklariert werden.
Beachten Sie, dass Snowflake Scripting nicht erlaubt, mehr als eine Variable pro Zeile zu erstellen.
Transact-SQL¶
DECLARE @find VARCHAR(30);
DECLARE @find2 VARCHAR(30) = 'Default';
DECLARE @var VARCHAR(5), @var2 varchar(5);
Snowflake Scripting
DECLARE
FIND VARCHAR(30);
FIND2 VARCHAR(30) := 'Default';
VAR VARCHAR(5);
VAR2 VARCHAR(5);
BEGIN
RETURN '';
END;
Deklarieren Sie Tabellenvariablen¶
Transact-SQL ermöglicht die Erstellung von Tabellenvariablen, die als reguläre Tabellen verwendet werden können. Snowflake Scripting unterstützt dies nicht. Stattdessen kann eine Tabelle erstellt und dann am Ende der Prozedur gelöscht werden.
Transact-SQL¶
DECLARE @MyTableVar TABLE(
column1 varchar(10));
Snowflake Scripting
BEGIN
DECLARE
T_MYTABLEVAR TABLE(
column1 VARCHAR(10));
END;
DECLARE-Anweisung außerhalb von Routinen (Funktionen und Prozeduren)¶
Im Gegensatz zu Transact-SQL unterstützt Snowflake nicht die Ausführung von isolierten Anweisungen wie DECLARE außerhalb von Routinen wie Funktionen oder Prozeduren. In diesem Szenario sollte die Anweisung in einem anonymen Block gekapselt werden, wie in den folgenden Beispielen gezeigt. Diese Anweisung wird normalerweise vor einem SET STATEMENT
verwendet.
Transact-SQL¶
DECLARE @Group nvarchar(50), @Sales MONEY;
SET @Group = N'North America';
SET @Sales = 2000000;
Snowflake Scripting
DECLARE
_GROUP VARCHAR(50);
SALES NUMBER(38, 4);
BEGIN
_GROUP := 'North America';
SALES := 2000000;
END;
Wenn es ein Szenario mit nur DECLARE-Anweisungen gibt, sollte der BEGIN…END-Block eine RETURN NULL-Anweisung enthalten, um Fehler zu vermeiden, da dieser Block nicht leer sein kann.
Transact-SQL¶
DECLARE @Group nvarchar(50), @Sales MONEY;
Snowflake Scripting
DECLARE
_GROUP VARCHAR(50);
SALES NUMBER(38, 4);
BEGIN
RETURN '';
END;
Bekannte Probleme¶
Es wurden keine Probleme gefunden.
Zugehörige EWIs¶
Keine zugehörigen EWIs.
EXECUTE¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Beschreibung¶
Die Anweisung Transact-SQL EXECUTE ermöglicht die Ausführung einer Befehls- oder Zeichenfolge innerhalb eines Transact-SQL Batches, einer skalarwertigen benutzerdefinierten Funktion oder einer gespeicherten Prozedur. Weitere Informationen zu Transact-SQL EXECUTE finden Sie hier.
-- Execute a character string
{ EXEC | EXECUTE }
( { @string_variable | [ N ]'tsql_string' } [ + ...n ] )
[ AS { LOGIN | USER } = ' name ' ]
[;]
-- Execute a stored procedure or function
[ { EXEC | EXECUTE } ]
{
[ @return_status = ]
{ module_name [ ;number ] | @module_name_var }
[ [ @parameter = ] { value
| @variable [ OUTPUT ]
| [ DEFAULT ]
}
]
[ ,...n ]
[ WITH <execute_option> [ ,...n ] ]
}
[;]
Beispielhafte Quellcode-Muster¶
Ausführung einer Zeichenfolge¶
EXECUTE kann verwendet werden, um SQL-Operationen durchzuführen, die direkt als Literale übergeben werden. Im folgenden Beispiel wird sie innerhalb einer gespeicherten Prozedur verwendet, die eine neue Datenschutzabteilung in die Datenbank AdventureWorks2019 einfügt.
Transact-SQL¶
CREATE OR ALTER PROCEDURE AddPrivacyDepartment
AS
EXECUTE ('INSERT INTO HumanResources.Department VALUES (''Privacy'', ''Executive General and Administration'', default)');
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE AddPrivacyDepartment ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE 'INSERT INTO HumanResources.Department VALUES ('Privacy', 'Executive General and Administration', default);';
END;
$$;
Ausführung einer gespeicherten Prozedur¶
EXECUTE kann auch verwendet werden, um eine vorhandene gespeicherte Prozedur aufzurufen. Das folgende Beispiel ruft die AddPrivacyDepartment-Prozedur auf, die oben erstellt wurde. Anschließend wird eine SELECT ausgeführt, um zu überprüfen, ob die neue Abteilung erfolgreich aufgenommen wurde.
Transact-SQL¶
EXECUTE AddPrivacyDepartment;
SELECT DepartmentID, Name, GroupName FROM HumanResources.Department;
DepartmentID|Name |GroupName |ModifiedDate |
------------+--------------------------+------------------------------------+-----------------------+
1|Engineering |Research and Development |2008-04-30 00:00:00.000|
2|Tool Design |Research and Development |2008-04-30 00:00:00.000|
3|Sales |Sales and Marketing |2008-04-30 00:00:00.000|
4|Marketing |Sales and Marketing |2008-04-30 00:00:00.000|
5|Purchasing |Inventory Management |2008-04-30 00:00:00.000|
6|Research and Development |Research and Development |2008-04-30 00:00:00.000|
7|Production |Manufacturing |2008-04-30 00:00:00.000|
8|Production Control |Manufacturing |2008-04-30 00:00:00.000|
9|Human Resources |Executive General and Administration|2008-04-30 00:00:00.000|
10|Finance |Executive General and Administration|2008-04-30 00:00:00.000|
11|Information Services |Executive General and Administration|2008-04-30 00:00:00.000|
12|Document Control |Quality Assurance |2008-04-30 00:00:00.000|
13|Quality Assurance |Quality Assurance |2008-04-30 00:00:00.000|
14|Facilities and Maintenance|Executive General and Administration|2008-04-30 00:00:00.000|
15|Shipping and Receiving |Inventory Management |2008-04-30 00:00:00.000|
16|Executive |Executive General and Administration|2008-04-30 00:00:00.000|
17|Privacy |Executive General and Administration|2021-11-17 12:42:54.640|
Snowflake Scripting¶
CALL AddPrivacyDepartment();
SELECT
DepartmentID,
Name,
GroupName
FROM
HumanResources.Department;
DEPARTMENTID|NAME |GROUPNAME |MODIFIEDDATE |
------------+--------------------------+------------------------------------+-----------------------+
1|Engineering |Research and Development |2021-11-17 10:29:36.963|
2|Tool Design |Research and Development |2021-11-17 10:29:37.463|
3|Sales |Sales and Marketing |2021-11-17 10:29:38.192|
4|Marketing |Sales and Marketing |2021-11-17 10:29:38.733|
5|Purchasing |Inventory Management |2021-11-17 10:29:39.298|
6|Research and Development |Research and Development |2021-11-17 10:31:53.770|
7|Production |Manufacturing |2021-11-17 10:31:55.082|
8|Production Control |Manufacturing |2021-11-17 10:31:56.638|
9|Human Resources |Executive General and Administration|2021-11-17 10:31:57.507|
10|Finance |Executive General and Administration|2021-11-17 10:31:58.473|
11|Information Services |Executive General and Administration|2021-11-17 10:34:35.200|
12|Document Control |Quality Assurance |2021-11-17 10:34:35.741|
13|Quality Assurance |Quality Assurance |2021-11-17 10:34:36.277|
14|Facilities and Maintenance|Executive General and Administration|2021-11-17 10:34:36.832|
15|Shipping and Receiving |Inventory Management |2021-11-17 10:34:37.373|
16|Executive |Executive General and Administration|2021-11-17 10:34:37.918|
17|Privacy |Executive General and Administration|2021-11-17 10:46:43.345|
Ausführung von lokalen Variablen und Verwendung von Parametern¶
Ein häufiger Anwendungsfall für die Anweisung EXECUTE ist, wenn dynamische SQL Anweisungen benötigt werden. In diesem Fall könnte die Anweisung anstelle der Ausführung eines Zeichenfolgenliterals dynamisch konstruiert und einer lokalen Variablen zugewiesen werden, die dann ausgeführt wird. Eine Reihe von Argumenten kann an die aufgerufene gespeicherte Prozedur gesendet werden, um den dynamischen SQL-Befehl zu erstellen.
Im folgenden Beispiel wird eine einfache gespeicherte Prozedur SetNewPrice konstruiert, die die Anweisung EXECUTE verwendet, um einen neuen Produktpreis auf der Grundlage der vom Aufrufer gesendeten Argumente festzulegen. Zum Schluss wird ein SELECT durchgeführt, um den neuen Produktpreis zu bestätigen.
Transact-SQL¶
CREATE OR ALTER PROCEDURE SetNewPrice @ProductID INT, @NewPrice MONEY
AS
DECLARE @dynSqlStatement AS VARCHAR(300);
SET @dynSqlStatement = 'UPDATE Production.ProductListPriceHistory SET ListPrice = ' + CAST(@NewPrice AS VARCHAR(10)) + ' WHERE ProductID = ' + CAST(@ProductID AS VARCHAR(10)) + ' AND EndDate IS NULL';
EXECUTE (@dynSqlStatement);
GO
EXECUTE Set_New_Price @ProductID = 707, @NewPrice = 34.99;
SELECT ListPrice FROM Production.ProductListPriceHistory WHERE ProductID = 707 AND EndDate IS NULL;
ListPrice|
---------+
34.9900|
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE SetNewPrice (PRODUCTID INT, NEWPRICE NUMBER(38, 4))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
DYNSQLSTATEMENT VARCHAR(300);
BEGIN
DYNSQLSTATEMENT := 'UPDATE Production.ProductListPriceHistory
SET
ListPrice = ' || CAST(:NEWPRICE AS VARCHAR(10)) || '
WHERE
ProductID = ' || CAST(:PRODUCTID AS VARCHAR(10)) || '
AND EndDate IS NULL;';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE :DYNSQLSTATEMENT;
END;
$$;
CALL Set_New_Price(707, 34.99);
SELECT
ListPrice
FROM
Production.ProductListPriceHistory
WHERE
ProductID = 707 AND EndDate IS NULL;
LISTPRICE|
---------+
34.9900|
Bekannte Probleme¶
Rückgabecodes verwenden¶
Die Transact-SQL EXECUTE-Syntax enthält das optionale Argument @return_status, mit dem Sie eine skalare Variable erstellen können, um den Rückgabestatus einer skalarwertigen benutzerdefinierten Funktion zu speichern.
Sie kann auch in gespeicherten Prozeduren verwendet werden, obwohl der zurückgegebene Status auf den Datentyp Ganzzahl beschränkt ist.
Um diese Funktionalität darzustellen, könnten wir das obige Beispiel leicht abändern und eine benutzerdefinierte Funktion erstellen, die den neuen Produktpreis als Durchschnitt der historischen Preise berechnet. Anstatt ihn an die gespeicherte Prozedur zu übergeben, könnten wir nun die Funktion CalculateAveragePrice aufrufen, um den neuen Preis zu erhalten, und ihn in der Rückgabevariablen speichern, um die dynamische SQL zu erstellen.
Transact-SQL¶
CREATE OR ALTER FUNCTION CalculateAveragePrice(@pid INT)
RETURNS MONEY
AS
BEGIN
DECLARE @average AS MONEY;
SELECT @average = AVG(LISTPRICE) FROM Production.ProductListPriceHistory WHERE ProductID = @pid;
RETURN @average;
END;
GO
CREATE OR ALTER PROCEDURE SetNewPrice @ProductID INT
AS
DECLARE @averageHistoricalPrice MONEY;
EXECUTE @averageHistoricalPrice = [dbo].Calculate_Average_Price @pid=@ProductID;
UPDATE Production.ProductListPriceHistory SET ListPrice = @averageHistoricalPrice WHERE ProductID = @ProductID AND EndDate IS NULL;
GO
EXECUTE Set_New_Price @ProductID = 707;
SELECT ListPrice FROM Production.ProductListPriceHistory WHERE ProductID = 707 AND EndDate IS NULL;
ListPrice|
---------+
34.0928|
Snowflake Scripting¶
CREATE OR REPLACE FUNCTION CalculateAveragePrice (PID INT)
RETURNS NUMBER(38, 4)
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
AS
$$
WITH CTE1 AS
(
SELECT
AVG(LISTPRICE) AS AVERAGE FROM
Production.ProductListPriceHistory
WHERE
ProductID = PID
)
SELECT
AVERAGE
FROM
CTE1
$$;
CREATE OR REPLACE PROCEDURE SetNewPrice (PRODUCTID INT)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
AVERAGEHISTORICALPRICE NUMBER(38, 4);
BEGIN
CALL dbo.Calculate_Average_Price(:PRODUCTID);
UPDATE Production.ProductListPriceHistory
SET
ListPrice = :AVERAGEHISTORICALPRICE
WHERE
ProductID = :PRODUCTID
AND EndDate IS NULL;
END;
$$;
CALL Set_New_Price(707);
SELECT
ListPrice
FROM
Production.ProductListPriceHistory
WHERE
ProductID = 707 AND EndDate IS NULL;
Nicht unterstützte optionale Argumente¶
@return_status
;number
@module__name_v_ar
WITH RECOMPILE, WITH RESULT SETS NONE, WITH <result set definition>
Zugehörige EWIs¶
[SSC-EWI-0030](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0030): Die nachstehende Anweisung enthält Verwendungen von dynamischen SQL.
IF¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Beschreibung ¶
Die IF-Klausel ermöglicht die bedingte Ausführung einer SQL-Anweisung oder eines Anweisungsblocks, solange der boolesche Ausdruck „true“ ist; andernfalls werden die Anweisungen in der optionalen ELSE-Klausel ausgeführt. Transact-SQL unterstützt auch die Einbettung mehrerer IF… ELSE-Klauseln, falls mehrere Bedingungen erforderlich sind, oder die CASE-Klausel kann ebenfalls verwendet werden.
Weitere Informationen zu Transact-SQL IF…ELSE, finden Sie hier.
IF Boolean_expression
{ sql_statement | statement_block }
[ ELSE
{ sql_statement | statement_block } ]
Anmerkung: Um einen Anweisungsblock zu definieren, verwenden Sie die Control-of-Flow-Schlüsselwörter BEGIN
und END
.
Beispielhafte Quellcode-Muster ¶
Transact-SQL¶
Der folgende Code verweist auf eine IF… ELSE in Transact-SQL, die die Variable @value daraufhin überprüft, ob sie kleiner als 5 ist, ob sie zwischen 5 und 10 liegt oder ob sie einen anderen Wert hat. Da @Wert mit 7 initialisiert ist, muss die zweite Bedingung „true“ sein und das Ergebnis muss 200 sein.
CREATE OR ALTER PROCEDURE IfElseDemoProcedure
AS
DECLARE @value INT;
SET @value = 7;
IF @value < 5
SET @value = 100;
ELSE IF @value >= 5 AND @value < 10
BEGIN
SET @value = 300;
SET @value = @value - 100;
END;
ELSE
SET @value = -1;
RETURN @value
GO
DECLARE @result INT;
EXEC @result = IfElseDemoProcedure;
PRINT @result;
|result|
|------|
|200 |
Snowflake Scripting ¶
Bemerkung
Beachten Sie, dass in Snowflake Scripting die eingebettete IF… ELSE-Bedingung ELSEIF genannt wird.
Außerdem ist die boolesche Bedingung in Klammern eingeschlossen und die Klausel endet immer mit dem Ausdruck END IF.
Außerdem ist es in Snowflake Scripting nicht notwendig, die Schlüsselwörter BEGIN und END zu verwenden, um einen Anweisungsblock zu definieren, aber es kann bei Bedarf verwendet werden.
CREATE OR REPLACE PROCEDURE IfElseDemoProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
VALUE INT;
BEGIN
VALUE := 7;
IF (:VALUE < 5) THEN
VALUE := 100;
ELSEIF (:VALUE >= 5 AND :VALUE < 10) THEN
BEGIN
VALUE := 300;
VALUE := :VALUE - 100;
END;
ELSE
VALUE := -1;
END IF;
RETURN :VALUE;
END;
$$;
DECLARE
RESULT INT;
BEGIN
CALL IfElseDemoProcedure();
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Print' NODE ***/!!!
PRINT @result;
END;
|result|
|------|
|200 |
IF-Anweisung außerhalb von Routinen (Funktionen und Prozeduren)¶
Im Gegensatz zu Transact-SQL unterstützt Snowflake nicht die Ausführung von isolierten Anweisungen wie IF…ELSE außerhalb von Routinen wie Funktionen oder Prozeduren. In diesem Szenario sollte die Anweisung in einem anonymen Block gekapselt werden, wie im folgenden Beispiel gezeigt. Mehr darüber, wie Sie die Ausgabewerte korrekt zurückgeben, erfahren Sie im Abschnitt SELECT .
Transact-SQL¶
DECLARE @maxWeight FLOAT, @productKey INTEGER
SET @maxWeight = 100.00
SET @productKey = 424
IF @maxWeight <= 99
SELECT @productKey, 'This product is too heavy to ship and is only available for pickup.'
ELSE
SELECT @productKey, 'This product is available for shipping or pickup.'
Snowflake Scripting
DECLARE
MAXWEIGHT FLOAT;
PRODUCTKEY INTEGER;
BlockResultSet1 VARCHAR;
BlockResultSet2 VARCHAR;
return_arr ARRAY := array_construct();
BEGIN
MAXWEIGHT := 100.00;
PRODUCTKEY := 424;
IF (:MAXWEIGHT <= 99) THEN
BlockResultSet1 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:BlockResultSet1) AS
SELECT
:PRODUCTKEY, 'This product is too heavy to ship and is only available for pickup.';
return_arr := array_append(return_arr, :BlockResultSet1);
ELSE
BlockResultSet2 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:BlockResultSet2) AS
SELECT
:PRODUCTKEY, 'This product is available for shipping or pickup.';
return_arr := array_append(return_arr, :BlockResultSet2);
END IF;
--** SSC-FDM-0020 - MULTIPLE RESULT SETS ARE RETURNED IN TEMPORARY TABLES **
RETURN return_arr;
END;
Bekannte Probleme¶
Es wurden keine Probleme gefunden.
Zugehörige EWIs¶
[SSC-EWI-0073](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0073): Überprüfung der Funktionsäquivalenz ausstehend.
[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.
LABEL und GOTO¶
Applies to
[x] SQL Server
Beschreibung¶
Snowflake SQL unterstützt keine GOTO LABEL-Anweisungen. Derzeit werden LABELS kommentiert und es wird eine Warnung für alle Vorkommnisse hinzugefügt.
Beispielhafte Quellcode-Muster ¶
Die folgenden Beispiele zeigen die Transaktionsanweisungen BEGIN und COMMIT.
Transact-SQL ¶
CREATE PROCEDURE GoToProcedure
AS
BEGIN
DECLARE @TotalMaarks INT
SET @TotalMaarks = 49;
IF @TotalMaarks >= 50
GOTO Pass
IF @TotalMaarks < 50
GOTO Fail
Pass:
SELECT 1;
RETURN 1;
Fail:
SELECT 2;
RETURN 2;
END
Snowflake SQL ¶
CREATE OR REPLACE PROCEDURE GoToProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
TOTALMAARKS INT;
BEGIN
TOTALMAARKS := 49;
IF (:TOTALMAARKS >= 50) THEN
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'GOTO' NODE ***/!!!
GOTO Pass
END IF;
IF (:TOTALMAARKS < 50) THEN
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'GOTO' NODE ***/!!!
GOTO Fail
END IF;
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0045 - LABELED STATEMENT IS NOT SUPPORTED IN SNOWFLAKE SCRIPTING ***/!!!
Pass:
SELECT 1;
RETURN 1;
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0045 - LABELED STATEMENT IS NOT SUPPORTED IN SNOWFLAKE SCRIPTING ***/!!!
Fail:
SELECT 2;
RETURN 2;
END;
$$;
LABEL- und GOTO-Anweisung außerhalb von Routinen (Funktionen und Prozeduren)¶
Transact-SQL
CREATE TABLE T12(COL1 INT);
GOTO SecondStat
FirstStat:
INSERT INTO T12 VALUES (1);
SecondStat:
INSERT INTO T12 VALUES (2);
Snowflake Scripting
BEGIN
CREATE OR REPLACE TABLE T12 (
COL1 INT
);
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Goto' NODE ***/!!!
GOTO SecondStat;
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0045 - LABELED STATEMENT IS NOT SUPPORTED IN SNOWFLAKE SCRIPTING ***/!!!
FirstStat:
INSERT INTO T12 VALUES (1);
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0045 - LABELED STATEMENT IS NOT SUPPORTED IN SNOWFLAKE SCRIPTING ***/!!!
SecondStat:
INSERT INTO T12 VALUES (2);
END;
Bekannte Probleme¶
Es wurden keine Probleme gefunden.
Zugehörige EWIs¶
[SSC-EWI-TS0045](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/sqlServerEWI. md#ssc-ewi-ts0045): LABELED-Anweisung wird in Snowflake Scripting nicht unterstützt.
[SSC-EWI-0073](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0073): Überprüfung der Funktionsäquivalenz ausstehend.
OUTPUT PARAMETERS¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Beschreibung¶
Ein Ausgabeparameter ist ein Parameter, dessen Wert aus der gespeicherten Prozedur heraus an den aufrufenden SQL Block zurückgegeben wird. Da die Ausgabeparameter von Snowflake Scripting nicht unterstützt werden, wurde eine Lösung implementiert, um ihre Funktionalität zu emulieren.
Beispielhafte Quellcode-Muster¶
Einzelner OUT-Parameter¶
Das einfachste Szenario für OUT ist, wenn die Prozedur nur einen Parameter hat. In diesem Fall geben wir einfach den Parameter OUT am Ende des Bodys der Prozedur zurück.
Die Prozedur EXEC muss ebenfalls übersetzt werden. Dazu wird eine CALL erstellt, die Parameter werden ohne Modifikator übergeben (OUT wird entfernt) und anschließend wird eine Zuweisung vorgenommen, damit der Parameter mit dem entsprechenden Ergebniswert verknüpft wird.
Transact-SQL¶
-- Procedure with output parameter
CREATE PROCEDURE dbo.outmain
@name VARCHAR (255) OUTPUT
AS
SET @name = 'Jane';
-- Auxiliary procedure that calls the main procedure
CREATE PROCEDURE dbo.outaux
AS
DECLARE @name VARCHAR (255);
EXEC dbo.outmain
@name = @name OUTPUT;
Snowflake Scripting¶
-- Procedure with output parameter
CREATE OR REPLACE PROCEDURE dbo.outmain (NAME STRING)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
NAME := 'Jane';
-- Auxiliary procedure that calls the main procedure
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'CREATE PROCEDURE' NODE ***/!!!
CREATE PROCEDURE dbo.outaux
AS
DECLARE @name VARCHAR (255);
EXEC dbo.outmain
@name = @name OUTPUT;
RETURN NAME;
END;
$$;
Mehrere OUT-Parameter¶
Wenn mehr als ein OUT-Parameter gefunden wird, ändert sich die RETURNS-Klausel der Prozedur in VARIANT. Dies dient dazu, OBJECT_CONSTRUCT unterzubringen, die zum Speichern der Werte der OUT-Parameter verwendet werden soll.
Außerdem wird am Ende des Bodys der Prozedur die Anweisung RETURN eingefügt. Hier wird OBJECT_COSNTRUCT erstellt und alle OUT-Parameterwerte werden darin gespeichert. Dieses Objekt wird dann vom Aufrufer verwendet, um den Parameterwert dem entsprechenden Ergebnis zuzuordnen.
Transact-SQL¶
CREATE OR ALTER PROCEDURE basicProc (
@col1 INT OUT,
@col2 VARCHAR(10) OUT
) AS
BEGIN
SET @col1 = 4;
SET @col2 = 'test';
END;
CREATE OR ALTER PROCEDURE basicProcCall AS
BEGIN
DECLARE @var1 INT = 0;
DECLARE @var2 VARCHAR(10) = 'EMPTY';
EXEC basicProc @var1 OUT, @var2 OUT;
INSERT INTO TABLE1(col1, col2) VALUES (@var1, @var2);
END;
EXEC basicProcCall;
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE basicProc (COL1 INT, COL2 STRING)
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
BEGIN
COL1 := 4;
COL2 := 'test';
END;
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'CREATE PROCEDURE' NODE ***/!!!
CREATE OR ALTER PROCEDURE basicProcCall AS
BEGIN
DECLARE @var1 INT = 0;
DECLARE @var2 VARCHAR(10) = 'EMPTY';
EXEC basicProc @var1 OUT, @var2 OUT;
INSERT INTO TABLE1(col1, col2) VALUES (@var1, @var2);
END;
EXEC basicProcCall;
RETURN OBJECT_CONSTRUCT('COL1', :COL1, 'COL2', :COL2);
END;
$$;
OUT-parameter und Rückgabewerte¶
Transact-SQL erlaubt Prozeduren, Rückgabewerte zu haben. Wenn eine Prozedur sowohl einen Rückgabewert als auch einen oder mehrere OUT-Parameter hat, wird ein ähnlicher Ansatz wie bei Mehrere OUT-Parameter verfolgt. Der ursprüngliche Rückgabewert wird so behandelt, wie ein OUT-Parameter behandelt werden würde, d.h. er wird in OBJECT_CONSTRUCT gespeichert und innerhalb der Aufrufer-Prozedur extrahiert.
Transact-SQL¶
-- Procedure with multiple output parameters
CREATE PROCEDURE dbo.outmain
@name VARCHAR (255) OUTPUT
AS
SET @name = 'Jane';
RETURN 0;
-- Auxiliary procedure that calls the main procedure
CREATE PROCEDURE dbo.outaux
AS
DECLARE @name VARCHAR (255);
DECLARE @returnValue INT;
EXEC @returnValue = dbo.outmain
@name = @name OUTPUT;
Snowflake Scripting¶
-- Procedure with multiple output parameters
CREATE OR REPLACE PROCEDURE dbo.outmain (NAME STRING)
RETURNS VARIANT
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
NAME := 'Jane';
RETURN OBJECT_CONSTRUCT('SC_RET_VALUE', 0, 'NAME', :NAME);
-- Auxiliary procedure that calls the main procedure
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'CREATE PROCEDURE' NODE ***/!!!
CREATE PROCEDURE dbo.outaux
AS
DECLARE @name VARCHAR (255);
DECLARE @returnValue INT;
EXEC @returnValue = dbo.outmain
@name = @name OUTPUT;
END;
$$;
Kundendatentyp OUT-Parameter¶
Wenn der Ausgabeparameter ein Kundentyp ist, ist der Prozess ähnlich wie bei einem regulären Datentyp.
Transact-SQL¶
CREATE PROCEDURE procedure_udtype_out_params(
@p_employee_id INT,
@p_phone [dbo].[PhoneNumber] OUTPUT
) AS
BEGIN
SELECT @p_phone = phone
FROM employees
WHERE employee_id = @p_employee_id;
END;
Snowflake Scripting¶
CREATE OR REPLACE PROCEDURE procedure_udtype_out_params (P_EMPLOYEE_ID INT, P_PHONE VARIANT /*** SSC-FDM-TS0015 - DATA TYPE DBO.PHONENUMBER IS NOT SUPPORTED IN SNOWFLAKE ***/)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
SELECT
phone
INTO
:P_PHONE
FROM
employees
WHERE
employee_id = :P_EMPLOYEE_ID;
RETURN P_PHONE;
END;
$$;
Bekannte Probleme ¶
Es wurden keine Probleme gefunden.
Zugehörige EWIs¶
[SSC-EWI-0073](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0073): Überprüfung der Funktionsäquivalenz ausstehend.
[SSC-FDM-TS0015](../../general/technical-documentation/issues-and-troubleshooting/functional-difference/sqlServerFDM. md#ssc-fdm-ts0015): Datentyp wird in Snowflake nicht unterstützt.
SET¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Beschreibung¶
Setzt die angegebene lokale Variable, die zuvor mit der Anweisung DECLARE @local_variable erstellt wurde, auf den angegebenen Wert. Weitere Informationen zu Transact-SQL SET finden Sie hier.
Es gibt vier SET-Fälle, die folgenden sind:
SET
{ @local_variable
[ . { property_name | field_name } ] = { expression | udt_name { . | :: } method_name }
}
|
{ @SQLCLR_local_variable.mutator_method
}
|
{ @local_variable
{+= | -= | *= | /= | %= | &= | ^= | |= } expression
}
|
{ @cursor_variable =
{ @cursor_variable | cursor_name
| { CURSOR [ FORWARD_ONLY | SCROLL ]
[ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
[ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
[ TYPE_WARNING ]
FOR select_statement
[ FOR { READ ONLY | UPDATE [ OF column_name [ ,...n ] ] } ]
}
}
}
Beispielhafte Quellcode-Muster ¶
Transact-SQL¶
CREATE OR ALTER PROCEDURE SetProcedure
AS
DECLARE @MyCounter INT;
DECLARE @FloatCounter FLOAT;
--Numerical operators
SET @MyCounter = 3;
SET @MyCounter += 1; --@MyCounter has 4
SET @MyCounter -= 1; --@MyCounter has 3
SET @MyCounter *= 2; --@MyCounter has 6
SET @MyCounter /= 3; --@MyCounter has 2
SET @MyCounter = 6;
SET @MyCounter /= 5; --@MyCounter has 1
SET @MyCounter = 6;
SET @MyCounter /= 7; --@MyCounter has 0
SET @FloatCounter = 10;
SET @FloatCounter /= 4; --@FloatCounter has 2.5
SET @MyCounter = 6;
SET @MyCounter %= 4; --@MyCounter has 2
--Logical operators
SET @MyCounter &= 3; --@MyCounter has 2
SET @MyCounter ^= 2; --@MyCounter has 0
SET @MyCounter |= 0; --@MyCounter has 0
RETURN @MyCounter;
GO
DECLARE @result INT;
EXEC @result = SetProcedure;
PRINT @result;
CREATE TABLE vEmployee (
PersonID int,
LastName varchar(255),
FirstName varchar(255)
);
CREATE OR ALTER PROCEDURE SetCursor
AS
DECLARE @CursorVar CURSOR;
SET @CursorVar = CURSOR SCROLL DYNAMIC
FOR
SELECT LastName, FirstName
FROM vEmployee
WHERE LastName like 'B%';
GO
|Result |
|---------|
|0 |
Snowflake Scripting ¶
CREATE OR REPLACE PROCEDURE SetProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
MYCOUNTER INT;
FLOATCOUNTER FLOAT;
BEGIN
--Numerical operators
MYCOUNTER := 3;
MYCOUNTER := MYCOUNTER + 1; --@MyCounter has 4
MYCOUNTER := MYCOUNTER - 1; --@MyCounter has 3
MYCOUNTER := MYCOUNTER * 2; --@MyCounter has 6
MYCOUNTER := TRUNC(MYCOUNTER / 3); --@MyCounter has 2
MYCOUNTER := 6;
MYCOUNTER := TRUNC(MYCOUNTER / 5); --@MyCounter has 1
MYCOUNTER := 6;
MYCOUNTER := TRUNC(MYCOUNTER / 7); --@MyCounter has 0
FLOATCOUNTER := 10;
FLOATCOUNTER := FLOATCOUNTER / 4; --@FloatCounter has 2.5
MYCOUNTER := 6;
MYCOUNTER := MYCOUNTER % 4; --@MyCounter has 2
--Logical operators
MYCOUNTER := BITAND(MYCOUNTER, 3); --@MyCounter has 2
MYCOUNTER := BITXOR(MYCOUNTER, 2); --@MyCounter has 0
MYCOUNTER := BITOR(MYCOUNTER, 0); --@MyCounter has 0
RETURN :MYCOUNTER;
END;
$$;
DECLARE
RESULT INT;
BEGIN
CALL SetProcedure();
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Print' NODE ***/!!!
PRINT @result;
END;
CREATE OR REPLACE TABLE vEmployee (
PersonID INT,
LastName VARCHAR(255),
FirstName VARCHAR(255)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
;
CREATE OR REPLACE PROCEDURE SetCursor ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0037 - SNOWFLAKE SCRIPTING CURSORS ARE NON-SCROLLABLE, ONLY FETCH NEXT IS SUPPORTED ***/!!!
--** SSC-FDM-TS0013 - SNOWFLAKE SCRIPTING CURSOR ROWS ARE NOT MODIFIABLE **
CURSORVAR CURSOR
FOR
SELECT LastName, FirstName
FROM vEmployee
WHERE LastName like 'B%';
BEGIN
RETURN '';
END;
$$;
|Result |
|---------|
|0 |
SET-Anweisung außerhalb von Routinen (Funktionen und Prozeduren)¶
Im Gegensatz zu Transact-SQL unterstützt Snowflake nicht die Ausführung von isolierten Anweisungen wie SET außerhalb von Routinen wie Funktionen oder Prozeduren. In diesem Szenario sollte die Anweisung in einem anonymen Block gekapselt werden, wie in den folgenden Beispielen gezeigt. Diese Anweisung wird normalerweise nach einer DECLARE STATEMENT-Anweisung verwendet.
Transact-SQL¶
DECLARE @Group nvarchar(50), @Sales MONEY;
SET @Group = N'North America';
SET @Sales = 2000000;
Snowflake Scripting
DECLARE
_GROUP VARCHAR(50);
SALES NUMBER(38, 4);
BEGIN
_GROUP := 'North America';
SALES := 2000000;
END;
Wenn es ein Szenario mit nur SET-Anweisungen gibt, ist der DECLARE-Block nicht notwendig. Wahrscheinlich führt dieses Szenario zu Laufzeitfehlern, wenn versucht wird, einen Wert für eine nicht deklarierte Variable zu setzen.
Transact-SQL¶
SET @Group = N'North America';
Snowflake Scripting
BEGIN
_GROUP := 'North America';
END;
Bekannte Probleme¶
1. SET of a local variable with property name¶
Diese Art von Set wird derzeit von Snowflake Scripting nicht unterstützt.
// TSQL custom data type with properties example
DECLARE @p Point;
SET @p.X = @p.X + 1.1;
2. SET of a local variable with mutator method¶
Diese Art von Set wird derzeit von Snowflake Scripting nicht unterstützt.
// TSQL custom data type with mutator method
SET @p.SetXY(22, 23);
Zugehörige EWIs¶
[SSC-EWI-TS0037](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/sqlServerEWI. md#ssc-ewi-ts0037): Snowflake Scripting Cursors sind nicht scrollbar.
[SSC-EWI-0073](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0073): Überprüfung der Funktionsäquivalenz ausstehend.
[SSC-FDM-TS0013](../../general/technical-documentation/issues-and-troubleshooting/functional-difference/sqlServerFDM. md#ssc-fdm-ts0013): Snowflake Scripting Cursor-Zeilen sind nicht änderbar.
TRY CATCH¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Beschreibung¶
Implementiert die Fehlerbehandlung für Transact-SQL. Eine Gruppe von Transact-SQL-Anweisungen kann in einen TRY-Block eingeschlossen werden. Wenn im TRY-Block ein Fehler auftritt, wird die Kontrolle normalerweise an eine andere Gruppe von Anweisungen übergeben, die in einem CATCH-Block eingeschlossen ist.
Beispielhafte Quellcode-Muster ¶
Das folgende Beispiel beschreibt die Transformation für TRY CATCH innerhalb von Prozeduren.
Transact-SQL ¶
CREATE PROCEDURE ERROR_HANDLING_PROC
AS
BEGIN
BEGIN TRY
-- Generate divide-by-zero error.
SELECT 1/0;
END TRY
BEGIN CATCH
-- Execute error retrieval routine.
SELECT 'error';
END CATCH;
END;
|error |
Snowflake SQL ¶
CREATE OR REPLACE PROCEDURE ERROR_HANDLING_PROC ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
BEGIN
BEGIN
-- Generate divide-by-zero error.
SELECT
TRUNC( 1/0);
EXCEPTION
WHEN OTHER THEN
-- Execute error retrieval routine.
SELECT 'error';
END;
END;
$$;
|error |
Versuchen Sie außerhalb von Routinen (Funktionen und Prozeduren) zu fangen¶
Transact-SQL
BEGIN TRY
SELECT 1/0;
END TRY
BEGIN CATCH
SELECT 'error';
END CATCH;
Snowflake Scripting
DECLARE
BlockResultSet1 VARCHAR;
BlockResultSet2 VARCHAR;
return_arr ARRAY := array_construct();
BEGIN
BEGIN
BlockResultSet1 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:BlockResultSet1) AS
SELECT
TRUNC( 1/0);
return_arr := array_append(return_arr, :BlockResultSet1);
EXCEPTION
WHEN OTHER THEN
BlockResultSet2 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:BlockResultSet2) AS
SELECT 'error';
return_arr := array_append(return_arr, :BlockResultSet2);
END;
--** SSC-FDM-0020 - MULTIPLE RESULT SETS ARE RETURNED IN TEMPORARY TABLES **
RETURN return_arr;
END;
Bekannte Probleme¶
Es wurden keine Probleme gefunden.
Zugehörige EWIs¶
[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.
WHILE¶
Applies to
[x] SQL Server
[x] Azure Synapse Analytics
Beschreibung ¶
Die WHILE-Anweisung ermöglicht die wiederholte Ausführung einer SQL-Anweisung oder eines Anweisungsblocks, solange die angegebene Bedingung „true“ ist. Die Ausführung von Anweisungen in der WHILE-Schleife kann innerhalb der Schleife mit den Schlüsselwörtern BREAK
und CONTINUE
gesteuert werden.
Weitere Informationen zu Transact-SQL finden Sie hier.
WHILE Boolean_expression
{ sql_statement | statement_block | BREAK | CONTINUE }
Anmerkung: Um einen Anweisungsblock zu definieren, verwenden Sie die Control-of-Flow-Schlüsselwörter BEGIN
und END
.
Beispielhafte Quellcode-Muster ¶
Muster für grundlegenden Quellcode¶
Transact-SQL ¶
Der folgende Code bezieht sich auf eine While-Schleife in Transact-SQL, die die Variable @Iteration iteriert und den Ablauf der Schleife so steuert, dass sie beendet wird, wenn der Wert von @Iteration gleich 10 ist.
Bemerkung
Anweisungen nach dem Schlüsselwort CONTINUE
werden nicht ausgeführt.
CREATE OR ALTER PROCEDURE WhileDemoProcedure
AS
DECLARE @iteration INT;
SET @iteration = 1;
WHILE @iteration < 100
BEGIN
IF @iteration = 10
BREAK;
ELSE
BEGIN
SET @iteration = @iteration + 1;
CONTINUE;
SET @iteration = 2 * @iteration;
END;
END;
RETURN @iteration;
GO
DECLARE @result INT;
EXEC @result = WhileDemoProcedure;
PRINT @result;
|iteration|
|---------|
|10 |
Snowflake Scripting ¶
Bemerkung
Wie bei Transact-SQL werden auch bei Snowflake Scripting die Anweisungen nach dem Schlüsselwort CONTINUE
nicht ausgeführt.
Beachten Sie, dass es in Snowflake Scripting nicht notwendig ist, die Schlüsselwörter BEGIN und END zu verwenden, um einen Anweisungsblock zu definieren, aber eine Verwendung ist bei Bedarf möglich.
CREATE OR REPLACE PROCEDURE WhileDemoProcedure ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
ITERATION INT;
BEGIN
ITERATION := 1;
WHILE (:ITERATION < 100) LOOP
IF (:ITERATION = 10) THEN
BREAK;
ELSE
BEGIN
ITERATION := :ITERATION + 1;
CONTINUE;
ITERATION := 2 * :ITERATION;
END;
END IF;
END LOOP;
RETURN :ITERATION;
END;
$$;
DECLARE
RESULT INT;
BEGIN
CALL WhileDemoProcedure();
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'Print' NODE ***/!!!
PRINT @result;
END;
Snowflake Scripting erlaubt es, das Schlüsselwort LOOP
anstelle von DO
und den Ausdruck END LOOP
anstelle von END WHILE
zu verwenden.
WHILE (Boolean_expression) LOOP
-- statement or statement block
END LOOP;
|Iteration|
|---------|
|10 |
Quellcode-Muster „While“ mit leerem Body¶
Transact-SQL ¶
Bemerkung
Bitte beachten Sie, dass dieses Beispiel geschrieben wurde, als die Anweisung IF ELSE noch nicht unterstützt wurde. Die Unterschiede in den Ergebnissen sollten verschwinden, wenn die Unterstützung für die Anweisung implementiert wird.
CREATE OR ALTER PROCEDURE WhileEmptyBodyProc
AS
BEGIN
DECLARE @MyVar INT;
SET @MyVar = 1;
WHILE (@MyVar < 100)
BEGIN
IF @MyVar < 50
SET @MyVar *= 5;
ELSE
SET @MyVar *= 3;
END;
RETURN @MyVar;
END;
DECLARE @result INT;
EXEC @result = WhileEmptyBodyProc;
PRINT @result;
|result|
|------|
|125 |
Snowflake Scripting¶
Diese Anweisung kann in Snowflake Scripting keinen leeren Text-Body haben. Um diesen Fall zu lösen, wird eine Standardanweisung BREAK hinzugefügt, wenn ein leerer Text-Body erkannt wird.
CREATE OR REPLACE PROCEDURE WhileEmptyBodyProc ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
DECLARE
MYVAR INT;
RESULT INT;
BEGIN
BEGIN
MYVAR := 1;
WHILE (:MYVAR < 100) LOOP
IF (:MYVAR < 50) THEN
MYVAR := MYVAR * 5;
ELSE
MYVAR := MYVAR * 3;
END IF;
END LOOP;
RETURN :MYVAR;
END;
CALL WhileEmptyBodyProc();
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'PRINT' NODE ***/!!!
PRINT @result;
END;
$$;
|result|
|------|
|1 |
WHILE-Anweisung außerhalb von Routinen (Funktionen und Prozeduren)¶
Im Gegensatz zu Transact-SQL unterstützt Snowflake nicht die Ausführung von isolierten Anweisungen wie WHILE außerhalb von Routinen wie Funktionen oder Prozeduren. In diesem Szenario sollte die Anweisung in einem anonymen Block gekapselt werden, wie im folgenden Beispiel gezeigt.
Transact-SQL ¶
DECLARE @iteration INT;
SET @iteration = 1;
WHILE @iteration < 100
BEGIN
IF @iteration = 10
BREAK;
ELSE
BEGIN
SET @iteration = @iteration + 1;
CONTINUE;
SET @iteration = 2 * @iteration;
END;
END;
Snowflake Scripting
DECLARE
ITERATION INT;
BEGIN
ITERATION := 1;
WHILE (:ITERATION < 100) LOOP
IF (:ITERATION = 10) THEN
BREAK;
ELSE
BEGIN
ITERATION := :ITERATION + 1;
CONTINUE;
ITERATION := 2 * :ITERATION;
END;
END IF;
END LOOP;
END;
Bekannte Probleme¶
Es wurden keine Probleme gefunden.
Zugehörige EWIs¶
[SSC-EWI-0073](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0073): Überprüfung der Funktionsäquivalenz ausstehend.