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
Copy
 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
Copy
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;
$$;
Copy
 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;
$$;
Copy

Bekannte Probleme

  1. 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
Copy

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;
Copy
 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;
Copy
 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|
Copy
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();
Copy
 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();
Copy
 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|
Copy

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;
Copy
 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;
Copy
 |result|
|------|
|150   |
Copy
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;
Copy
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;
Copy
 |result|
|------|
|150   |
Copy

Bekannte Probleme

Es wurden keine Probleme gefunden.

Zugehörige EWIs

  1. [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 ] }
[;]
Copy

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;
Copy
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;
$$;
Copy

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)');
Copy
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;
$$;
Copy

Alter-Prozedur

Die Transformation für die Prozedur ALTER entspricht der Basisprozedur.

Transact-SQL
 ALTER PROCEDURE procedureName
AS
SELECT 1 AS ThisDB;
Copy
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;
$$;
Copy

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;
Copy
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;
$$;
Copy

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;
Copy
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;
$$;
Copy

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
Copy
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);
Copy

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;
Copy
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;
$$;
Copy
  • 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;
Copy
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;
$$;
Copy

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;
Copy
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;
$$;
Copy

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

  1. [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.

  2. [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 ] ] ]  
[;]  
Copy
 FETCH   
          [ [ NEXT | PRIOR | FIRST | LAST   
                    | ABSOLUTE { n | @nvar }   
                    | RELATIVE { n | @nvar }   
               ]   
               FROM   
          ]   
{ { [ GLOBAL ] cursor_name } | @cursor_variable_name }   
[ INTO @variable_name [ ,...n ] ] 
Copy
 OPEN { { [ GLOBAL ] cursor_name } | cursor_variable_name }  
Copy
 CLOSE { { [ GLOBAL ] cursor_name } | cursor_variable_name }
Copy
 DEALLOCATE { { [ GLOBAL ] cursor_name } | @cursor_variable_name }  
Copy

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
Copy
B

Copy
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;
$$;
Copy
B

Copy

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;
Copy
 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;
$$;
Copy

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
Copy

Umgebungsvariablen

  • @@CURSOR_ROWS

  • @@FETCH_STATUS

Zugehörige EWIs

  1. [SSC-FDM-TS0013](../../general/technical-documentation/issues-and-troubleshooting/functional-difference/sqlServerFDM. md#ssc-fdm-ts0013): Snowflake Scripting Cursor-Zeilen sind nicht änderbar.

  2. [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 )   
     }
Copy

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);
Copy

Snowflake Scripting

 DECLARE
FIND VARCHAR(30);
FIND2 VARCHAR(30) := 'Default';
VAR VARCHAR(5);
VAR2 VARCHAR(5);
BEGIN
RETURN '';
END;
Copy

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));
Copy

Snowflake Scripting

 BEGIN
    DECLARE
        T_MYTABLEVAR TABLE(
            column1 VARCHAR(10));
END;
Copy

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;
Copy

Snowflake Scripting

 DECLARE
_GROUP VARCHAR(50);
SALES NUMBER(38, 4);
BEGIN
_GROUP := 'North America';
SALES := 2000000;
END;
Copy

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;
Copy

Snowflake Scripting

 DECLARE
_GROUP VARCHAR(50);
SALES NUMBER(38, 4);
BEGIN
RETURN '';
END;
Copy

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 ] ]  
    }  
[;]  
Copy

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)');
Copy
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;
$$;
Copy

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; 
Copy
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|

Copy
Snowflake Scripting
 CALL AddPrivacyDepartment();

SELECT
DepartmentID,
Name,
GroupName
FROM
HumanResources.Department;
Copy
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|

Copy

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;
Copy
ListPrice|
---------+
  34.9900|

Copy
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;
Copy
LISTPRICE|
---------+
  34.9900|

Copy

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;
Copy
ListPrice|
---------+
  34.0928|

Copy
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;
Copy

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

  1. [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 } ]   
Copy

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;
Copy
 |result|
|------|
|200   |
Copy
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;
Copy
|result|
|------|
|200   |

Copy

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.' 
Copy

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;
Copy

Bekannte Probleme

Es wurden keine Probleme gefunden.

Zugehörige EWIs

  1. [SSC-EWI-0073](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0073): Überprüfung der Funktionsäquivalenz ausstehend.

  2. [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
Copy
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;
$$;
Copy

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);
Copy

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;
Copy

Bekannte Probleme

Es wurden keine Probleme gefunden.

Zugehörige EWIs

  1. [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.

  2. [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;
Copy
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;
$$;
Copy

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;
Copy
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;
$$;
Copy

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;
Copy
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;
$$;
Copy

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;
Copy
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;
$$;
Copy

Bekannte Probleme

Es wurden keine Probleme gefunden.

Zugehörige EWIs

  1. [SSC-EWI-0073](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0073): Überprüfung der Funktionsäquivalenz ausstehend.

  2. [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 ] ] } ]   
      }   
    }  
}
Copy

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;
Copy
 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	
Copy
|Result   |
|---------|
|0        |

Copy
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;
Copy
 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;
$$;
Copy
|Result   |
|---------|
|0        |

Copy

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;
Copy

Snowflake Scripting

 DECLARE
_GROUP VARCHAR(50);
SALES NUMBER(38, 4);
BEGIN
_GROUP := 'North America';
SALES := 2000000;
END;
Copy

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';
Copy

Snowflake Scripting

 BEGIN
_GROUP := 'North America';
END;
Copy

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;  
Copy
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);   
Copy

Zugehörige EWIs

  1. [SSC-EWI-TS0037](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/sqlServerEWI. md#ssc-ewi-ts0037): Snowflake Scripting Cursors sind nicht scrollbar.

  2. [SSC-EWI-0073](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0073): Überprüfung der Funktionsäquivalenz ausstehend.

  3. [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;
Copy
|error    |

Copy
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;
$$;
Copy
|error    |

Copy

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;
Copy

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;
Copy

Bekannte Probleme

Es wurden keine Probleme gefunden.

Zugehörige EWIs

  1. [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 }
Copy

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;
Copy
|iteration|
|---------|
|10       |

Copy
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 &#x3C; 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;
Copy

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;
Copy
|Iteration|
|---------|
|10       |

Copy

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;
Copy
|result|
|------|
|125   |

Copy
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;
$$;
Copy
|result|
|------|
|1     |

Copy

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;
Copy

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;
Copy

Bekannte Probleme

Es wurden keine Probleme gefunden.

Zugehörige EWIs

  1. [SSC-EWI-0073](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0073): Überprüfung der Funktionsäquivalenz ausstehend.