SnowConvert : Snowflake Scripting

Transaction BEGIN et COMMIT

Applies to
  • [x] SQL Server

  • [x] Azure Synapse Analytics

Description

Snowflake SQL, une transaction peut être lancée explicitement par l’exécution d’une instruction BEGIN. Snowflake prend en charge les synonymes BEGINWORK et BEGINTRANSACTION. Snowflake recommande d’utiliser BEGINTRANSACTION.

Il est possible de mettre fin à une transaction de manière explicite en exécutant COMMIT. Pour en savoir plus sur les transactions Snowflake , cliquez ici.

Échantillons de modèles de sources

Les exemples suivants détaillent les instructions de transaction BEGIN et 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

Problèmes connus

  1. Les transactions imbriquées ne sont pas prises en charge par Snowflake. Pour plus d’informations, consultez la documentation suivante : https://docs.snowflake.com/en/sql-reference/transactions

CALL

Applies to
  • [x] SQL Server

  • [x] Azure Synapse Analytics

Description

L’instruction CALL n’est pas prise en charge dans Snowflake Scripting car elle fait partie de l’instruction ODBC API et n’est pas une instruction SQL. Cette instruction n’est donc pas traduite.

CASE

Applies to
  • [x] SQL Server

  • [x] Azure Synapse Analytics

Note

Certaines parties du code de sortie sont omises pour des raisons de clarté.

Description

Transact-SQL propose deux formats possibles pour l’expression Case, tous deux destinés à l’évaluation d’expressions et à l’obtention conditionnelle de résultats. La première fait référence à une expression Case simple qui sera évaluée si une expression d’entrée correspond à une ou plusieurs expressions de sortie. La seconde évaluera chaque expression booléenne indépendamment. La clause else est prise en charge dans les deux formats.

Selon la documentation officielle du cas Transact-SQL:

CASE peut être utilisé dans toute instruction ou clause qui autorise une expression valide. Par exemple, vous pouvez utiliser CASE dans des instructions telles que SELECT, UPDATE, DELETE et SET, et dans des clauses telles que select_list, IN, WHERE, ORDER BY et HAVING.

Pour plus d’informations sur le casse Transact-SQL, cliquez ici.

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

Remarque : Transact-SQL permet d’encapsuler facultativement l’expression d’entrée et l’expression booléenne entre parenthèses ; Snowflake Scripting également.

Échantillons de modèles de sources

Les exemples suivants détaillent deux scénarios dans lesquels l’expression Case peut être utilisée et leurs différences par rapport à Snowflake Scripting.

Sélectionner à l’aide de Case

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

Notez que dans ce scénario, il n’y a aucune différence concernant l’expression Case elle-même.

Avertissement

La déclaration et l’affectation de la variable res visent à démontrer l’équivalence fonctionnelle entre les deux langues. Elle n’apparaît pas dans la sortie réelle.

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

Définir avec Case

La base de données AdventureWorks2019 a été utilisée dans les deux langues pour obtenir les mêmes résultats.

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

Avertissement

Snowflake Scripting ne permet pas de définir une expression Case directement à une variable. Les deux formats d’expression Transact-SQL Case se traduisent par la grammaire suivante dans 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

Problèmes connus

Aucun problème n’a été constaté.

EWIs connexes

  1. SSC-EWI-0073 : En attente de l’examen de l’équivalence fonctionnelle.

CREATE PROCEDURE

Applies to
  • [x] SQL Server

  • [x] Azure Synapse Analytics

Note

Certaines parties du code de sortie sont omises pour des raisons de clarté.

Description

L’instruction create procedure permet de créer des procédures stockées qui peuvent :

  • Accepter des paramètres d’entrée et renvoyer des valeurs multiples sous la forme de paramètres de sortie à la procédure ou au lot appelant.

  • Contenir des instructions de programmation qui effectuent des opérations dans la base de données, y compris l’appel d’autres procédures.

  • Renvoyer une valeur de statut à une procédure ou à un lot appelant pour indiquer le succès ou l’échec (et la raison de l’échec).

Pour plus d’informations sur Transact-SQL CREATE PROCEDURE, cliquez ici.

 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

Modèles d’échantillons de sources

Procédure stockée sans corps

Une procédure stockée sans corps est un scénario inhabituel autorisé dans Transact-SQL. Snowflake Scripting ne permet pas de définir des procédures sans corps, mais l’exemple suivant montre l’équivalence.

Transact-SQL
 CREATE PROC SampleProcedure AS;
Copy
Exécution de scripts Snowflake
 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

Procédure stockée de base

L’exemple suivant détaille une procédure stockée simple qui inclura un nouveau service de protection de la vie privée dans la base de données AdventureWorks2019.

Transact-SQL
 CREATE OR ALTER PROCEDURE Add_Privacy_Department
AS
  EXECUTE ('INSERT INTO HumanResources.Department VALUES (''Privacy'', ''Executive General and Administration'', default)');
Copy
Exécution de scripts Snowflake
 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

Procédure Alter

La transformation de la procédure ALTER est équivalente à la procédure de base.

Transact-SQL
 ALTER PROCEDURE procedureName
AS
SELECT 1 AS ThisDB;
Copy
Exécution de scripts Snowflake
 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

Utilisation de paramètres

Vous pouvez utiliser des paramètres pour piloter votre logique ou construire des instructions SQL dynamiques à l’intérieur de votre procédure stockée. L’exemple suivant présente une procédure stockée SetNewPrice simple qui définit le prix d’un nouveau produit sur la base des arguments envoyés par l’appelant.

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
Exécution de scripts Snowflake
 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

Paramètres de sortie

Le mot-clé de sortie Transact-SQL output indique que le paramètre est un paramètre de sortie, dont la valeur sera retournée à l’appelant de la procédure stockée. Par exemple, la procédure suivante renvoie le nombre d’heures de vacances d’un employé spécifique.

Transact-SQL
 CREATE PROCEDURE GetVacationHours  
   @employeeId INT,  
   @vacationHours INT OUTPUT  
AS  
BEGIN  
   SELECT @vacationHours = VacationHours 
   FROM HumanResources.Employee
   WHERE NationalIDNumber = @employeeID
END;
Copy
Exécution de scripts Snowflake
 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

Avertissement

1 seul paramètre de sortie peut être renvoyé par une procédure stockée de Snowflake Scripting.

Paramètres facultatifs

Un paramètre est considéré comme facultatif si le paramètre a une valeur par défaut spécifiée lors de sa déclaration. Il n’est pas nécessaire de fournir une valeur pour un paramètre facultatif dans un appel de procédure.

Transact-SQL
 CREATE PROCEDURE OPTIONAL_PARAMETER @VAR1 INT = 1, @VAR2 INT = 2
AS
    BEGIN
        RETURN NULL;
    END

GO

EXEC OPTIONAL_PARAMETER @VAR2 = 4
Copy
Exécution de scripts Snowflake
 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

La clause EXECUTE AS de Transact-SQL définit le contexte d’exécution de la procédure stockée, en spécifiant le compte utilisateur utilisé par le moteur de base de données pour valider les autorisations sur les objets référencés dans la procédure. Par exemple, nous pouvons modifier la procédure précédente GetVacationHours pour définir différents contextes d’exécution.

  • Propriétaire (par défaut dans 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
Exécution de scripts Snowflake
 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
  • Appelant

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
Exécution de scripts Snowflake
 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

Avertissement

SELF et les contextes d’exécution propres à un utilisateur (« user\name ») ne sont pas pris en charge dans Snowflake Scripting.

READONLY AND VARYING PARAMETERS

Snowflake ne prend pas en charge les types de paramètres READONLY et VARYING, un FDM est ajouté à la place.

Transact-SQL
 CREATE OR ALTER PROCEDURE GetVacationHours
   @Param1 INT READONLY,  
   @Param2 INT VARYING
AS
BEGIN  
   SELECT * FROM Table1;
END;
Copy
Exécution de scripts Snowflake
 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

Problèmes connus

Arguments facultatifs non pris en charge

  • [VARYING] S’applique uniquement aux paramètres de curseur. Spécifie le jeu de résultats pris en charge en tant que paramètre de sortie. Ce paramètre est construit dynamiquement par la procédure et son contenu peut varier. Snowflake Scripting ne prend pas en charge CURSOR comme type de données de retour valide.

  • [= default] Rend un paramètre facultatif par la définition d’une valeur par défaut. Snowflake Scripting ne prend pas en charge nativement les valeurs par défaut des paramètres.

  • [READONLY] Indique que le paramètre ne peut pas être mis à jour ou modifié dans le corps de la procédure. Actuellement non pris en charge dans Snowflake Scripting.

  • [WITH RECOMPILE] Force le moteur de la base de données à compiler le plan de requête de la procédure stockée à chaque exécution. Actuellement non pris en charge dans Snowflake Scripting.

  • [WITH ENCRYPTION] Utilisé pour chiffrer le texte d’une procédure stockée. Seuls les utilisateurs ayant accès aux tables du système ou aux fichiers de la base de données (tels que les utilisateurs sysadmin) pourront accéder au texte de la procédure après sa création. Actuellement non pris en charge dans Snowflake Scripting.

  • [FOR REPLICATION] Limite l’exécution de la procédure stockée à la seule période de réplication. Actuellement non pris en charge dans Snowflake Scripting.

connexesEWIS

  1. SSC-EWI-0030 : L’instruction ci-dessous a des utilisations de SQL dynamique.

  2. SSC-EWI-0058 : La fonctionnalité n’est pas prise en charge actuellement par Snowflake Scripting.

CURSOR

Applies to
  • [x] SQL Server

  • [x] Azure Synapse Analytics

Note

Certaines parties du code de sortie sont omises pour des raisons de clarté.

Description

Les instructions Transact-SQL produisent un jeu de résultats complet, mais il est parfois préférable de traiter les résultats une ligne à la fois. L’ouverture d’un curseur sur un jeu de résultats permet de traiter le jeu de résultats une ligne à la fois. Vous pouvez affecter un curseur à une variable ou à un paramètre avec un type de données curseur. Pour plus d’informations, cliquez ici.

 //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

Modèles d’échantillons de sources

Transact-SQL

Notez que les paramètres suivants sont intrinsèquement pris en charge par Snowflake Scripting.

  • [LOCAL].

  • [FORWARD_ONLY].

  • [FAST_FORWARD] Spécifie un FORWARD_ONLY (FETCH NEXT uniquement) et READ_ONLY

  • [READ_ONLY] le WHERE CURRENT OF n’existe pas dans 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
Exécution de scripts Snowflake
 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

Problèmes connus

Les paramètres suivants ne sont pas pris en charge :

DECLARE CURSOR

  • [ GLOBAL ] Permet de référencer le nom du curseur dans une procédure stockée ou un lot exécuté par la connexion. Snowflake Scripting ne permet d’utiliser le curseur que localement.

  • [ SCROLL ] Snowflake Scripting prend uniquement en charge FETCH NEXT.

  • [ KEYSET | DYNAMIC ] Si, après l’ouverture d’un curseur, une mise à jour de la table est effectuée, ces options peuvent afficher certaines des modifications lors de la recherche du curseur. Snowflake Scripting ne prend en charge que STATIC, en d’autres termes, après l’ouverture du curseur, les modifications apportées à la table ne sont pas détectées par le curseur.

  • [SCROLL_LOCKS] Spécifie que les mises à jour positionnées ou les suppressions effectuées par le curseur sont garanties de réussir, Snowflake Scripting ne peut pas le garantir.

  • [OPTIMISTIC] Lorsqu’une mise à jour ou une suppression est effectuée par le curseur, celui-ci utilise des comparaisons entre les valeurs des colonnes d’horodatage, ou une valeur de somme de contrôle si la table n’a pas de colonne d’horodatage, pour déterminer si la ligne a été modifiée après avoir été lue dans le curseur. Snowflake Scripting ne dispose pas d’un processus interne pour la réplication.

  • [TYPE_WARNING]

FETCH

  • [PRIOR | FIRST | LAST] Snowscripting prend uniquement en charge NEXT.

  • [ABSOLUTE] Snowflake Scripting ne prend en charge que NEXT mais le comportement peut être répliqué.

  • [RELATIVE] Snowflake Scripting mais le comportement peut être répliqué.

  • [ GLOBAL ] Permet de référencer le nom du curseur dans une procédure stockée ou un lot exécuté par la connexion. Snowflake Scripting ne permet d’utiliser le curseur que localement.

  • FETCH sans INTO n’est pas pris en charge.

  • Lorsque l’instruction FETCH est située à l’intérieur d’une boucle, elle est considérée comme un modèle complexe car elle peut avoir un impact sur les performances du code traduit par Snowflake. Consultez la section des problèmes connexes pour plus d’informations.

Fetch dans un échantillon de boucle

 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 ] Permet de référencer le nom du curseur dans une procédure stockée ou un lot exécuté par la connexion. Snowflake Scripting ne permet d’utiliser le curseur que localement.

CLOSE

  • [ GLOBAL ] Permet de référencer le nom du curseur dans une procédure stockée ou un lot exécuté par la connexion. Snowflake Scripting ne permet d’utiliser le curseur que localement.

DEALLOCATED Supprime une référence de curseur et il n’y a pas d’équivalent dans Snowflake Scripting.

WHERE CURRENT OF l’utilisation de cette instruction n’est pas prise en charge, par exemple :

 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

Variables d’environnement

  • @@CURSOR_ROWS

  • @@FETCH_STATUS

EWIs connexes

  1. SSC-FDM-TS0013 : Les lignes du curseur de Snowflake Scripting ne sont pas modifiables.

  2. SSC-PRF-0003 : Fetch à l’intérieur d’une boucle est considéré comme un modèle complexe, ce qui pourrait dégrader les performances de Snowflake.

DECLARE

Applies to
  • [x] SQL Server

  • [x] Azure Synapse Analytics

Description

L’instruction Transact-SQL DECLARE permet de créer des variables qui peuvent être utilisées dans le champ d’application du lot ou d’une procédure stockée. Pour plus d’informations sur Transact-SQL DECLARE, cliquez ici.

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

Modèles d’échantillons de sources

Déclarer des variables

Les variables peuvent être créées de différentes manières. Les variables peuvent avoir ou non une valeur par défaut et plusieurs variables peuvent être déclarées dans la même ligne.

Notez que Snowflake Scripting ne permet pas de créer plus d’une variable par ligne.

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

Déclarer les variables de table

Transact-SQL permet de créer des variables de table qui peuvent être utilisées comme des tables ordinaires. Snowflake Scripting ne prend pas en charge cette procédure. Au lieu de cela, une table peut être créée puis supprimée à la fin de la procédure.

Transact-SQL
 DECLARE @MyTableVar TABLE(  
    column1 varchar(10));
Copy

Snowflake Scripting

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

Instruction DECLARE en dehors des routines (fonctions et procédures)

Contrairement à Transact-SQL, Snowflake ne prend pas en charge l’exécution d’instructions isolées comme DECLARE en dehors de routines telles que des fonctions ou des procédures. Dans ce cas, l’instruction doit être encapsulée dans un bloc anonyme, comme le montrent les exemples suivants. Cette instruction est généralement utilisée avant un SET STATEMENT.

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

Si un scénario ne comporte que des instructions DECLARE, le bloc BEGIN…END doit comporter une instruction RETURN NULL pour éviter les erreurs, car ce bloc ne peut pas être vide.

Transact-SQL
 DECLARE @Group nvarchar(50), @Sales MONEY;
Copy

Snowflake Scripting

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

Problèmes connus

Aucun problème n’a été constaté.

EWIs connexes

Pas d’EWIs connexes.

EXECUTE

Applies to
  • [x] SQL Server

  • [x] Azure Synapse Analytics

Note

Certaines parties du code de sortie sont omises pour des raisons de clarté.

Description

L’instruction Transact-SQL EXECUTE permet l’exécution d’une chaîne de commande ou de caractères dans un lot Transact-SQL, une fonction définie par l’utilisateur à valeur scalaire ou une procédure stockée. Pour plus d’informations sur Transact-SQL EXECUTE, cliquez ici.

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

Modèles d’échantillons de sources

Exécution d’une chaîne de caractères

EXECUTE peut être utilisé pour effectuer les opérations SQL passées directement sous forme de littéraux. Dans l’exemple suivant, il est utilisé dans une procédure stockée qui insère un nouveau service de protection de la vie privée dans la base de données AdventureWorks2019.

Transact-SQL
 CREATE OR ALTER PROCEDURE AddPrivacyDepartment
AS 
EXECUTE ('INSERT INTO HumanResources.Department VALUES (''Privacy'', ''Executive General and Administration'', default)');
Copy
Exécution de scripts Snowflake
 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

Exécution de la procédure stockée

EXECUTE peut également être utilisée pour appeler une procédure stockée existante. L’exemple suivant appellera la procédure AddPrivacyDepartment qui a été créée ci-dessus. Il lancera ensuite une page SELECT pour vérifier que le nouveau département a bien été inclus.

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
Exécution de scripts Snowflake
 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

Exécution d’une variable locale et utilisation de paramètres

L’instruction EXECUTE est couramment utilisée lorsqu’il est nécessaire d’établir des instructions SQL dynamiques. Dans ce cas, au lieu d’exécuter une chaîne littérale, l’instruction peut être construite dynamiquement et assignée à une variable locale, qui sera ensuite exécutée. Un ensemble d’arguments peut être envoyé à la procédure stockée appelée pour construire la commande SQL dynamique.

L’exemple suivant présente une procédure stockée SetNewPrice simple, qui utilise l’instruction EXECUTE pour définir le prix d’un nouveau produit en fonction des arguments envoyés par l’appelant. Enfin, un SELECT est utilisé pour confirmer le prix du nouveau produit.

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
Exécution de scripts Snowflake
 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

Problèmes connus

Utilisation des codes de retour

La syntaxe Transact-SQL EXECUTE contient l’argument facultatif @return_status, qui permet de créer une variable scalaire pour stocker le statut de retour d’une fonction définie par l’utilisateur à valeur scalaire.

Elle peut également être utilisée dans les procédures stockées, bien que le statut renvoyé soit limité à un type de données entier.

Pour représenter cette fonctionnalité, nous pourrions modifier légèrement l’exemple ci-dessus et créer une fonction définie par l’utilisateur pour calculer le prix du nouveau produit comme une moyenne des prix historiques. Au lieu de le transmettre à la procédure stockée, nous pourrions maintenant appeler la fonction CalculateAveragePrice pour obtenir le nouveau prix et le stocker dans la variable de retour pour construire le SQL dynamique.

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
Exécution de scripts Snowflake
 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

Arguments facultatifs non pris en charge

  • @return_status

  • ;number

  • @module__name_v_ar

  • WITH RECOMPILE, WITH RESULT SETS NONE, WITH <définition du jeu de résultats>

EWIs connexes

  1. SSC-EWI-0030 : L’instruction ci-dessous a des utilisations de SQL dynamique.

IF

Applies to
  • [x] SQL Server

  • [x] Azure Synapse Analytics

Description

La clause IF permet l’exécution conditionnelle d’une instruction SQL ou d’un bloc d’instructions tant que l’expression booléenne est true ; dans le cas contraire, les instructions de la clause facultative ELSE seront exécutées. Transact-SQL permet également d’intégrer plusieurs clauses IF … ELSE dans le cas où plusieurs conditions sont requises, ou la clause CASE peut également être utilisée.

Pour plus d’informations sur Transact-SQL IF…ELSE, cliquez ici.

 IF Boolean_expression   
     { sql_statement | statement_block }   
[ ELSE   
     { sql_statement | statement_block } ]   
Copy

Remarque : Pour définir un bloc d’instructions, utilisez les mots-clés de contrôle du flux BEGIN et END.

Échantillons de modèles de sources

Transact-SQL

Le code suivant fait référence à un IF … ELSE dans Transact-SQL qui conditionne la variable @value pour déterminer si elle est inférieure à 5, si elle est comprise entre 5 et 10, ou si elle a une autre valeur. Puisque @value est initialisée à 7, la deuxième condition doit être vraie et le résultat doit être 200.

 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

Note

Remarquez que dans Snowflake Scripting, la condition intégrée IF … ELSE est appelée ELSEIF.

En outre, la condition booléenne est encapsulée entre parenthèses et la clause se termine toujours par l’expression END IF.

En outre, dans Snowflake Scripting, il n’est pas nécessaire d’utiliser les mots-clés BEGIN et END pour définir un bloc d’instructions, sauf s’il s’agit d’une exigence.

 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

Instruction IF en dehors des routines (fonctions et procédures)

Contrairement à Transact-SQL, Snowflake ne prend pas en charge l’exécution d’instructions isolées telles que IF…ELSE en dehors de routines telles que des fonctions ou des procédures. Pour ce scénario, l’instruction doit être encapsulée dans un bloc anonyme, comme le montre l’exemple suivant. Pour en savoir plus sur la manière de renvoyer correctement les valeurs de sortie, consultez la section 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

Problèmes connus

Aucun problème n’a été constaté.

EWIs connexes

  1. SSC-EWI-0073 : En attente de l’examen de l’équivalence fonctionnelle.

  2. SSC-FDM-0020 : Plusieurs jeux de résultats sont renvoyés dans des tables temporaires.

LABEL et GOTO

Applies to
  • [x] SQL Server

Description

Snowflake SQL ne prend pas en charge les instructions de GOTO LABEL. Actuellement, les LABELS sont commentés et un avertissement est ajouté pour toutes les occurrences.

Échantillons de modèles de sources

Les exemples suivants détaillent les instructions de transaction BEGIN et 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

Instruction LABEL et GOTO en dehors des routines (fonctions et procédures)

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

Problèmes connus

Aucun problème n’a été constaté.

EWIs connexes

  1. SSC-EWI-TS0045 : L’instruction étiquetée n’est pas prise en charge dans Snowflake Scripting.

  2. SSC-EWI-0073 : En attente de l’examen de l’équivalence fonctionnelle.

OUTPUT PARAMETERS

Applies to
  • [x] SQL Server

  • [x] Azure Synapse Analytics

Note

Certaines parties du code de sortie sont omises pour des raisons de clarté.

Description

Un paramètre de sortie est un paramètre dont la valeur est transmise à l’extérieur de la procédure stockée, en retour au bloc SQL appelant. Les paramètres de sortie n’étant pas pris en charge par le support Snowflake Scripting, une solution a été mise en œuvre afin d’émuler leur fonctionnalité.

Modèles d’échantillons de sources

Paramètre OUT unique

Le scénario le plus simple pour les paramètres OUT est celui où la procédure n’en a qu’un seul. Dans ce cas, nous renvoyons simplement le paramètre OUT à la fin du corps de la procédure.

La procédure EXEC doit également être traduite ; pour cela un CALL est créé, les paramètres sont passés sans aucun modificateur (« OUT » est supprimé), puis une affectation est faite pour que le paramètre soit associé à sa valeur résultante respective.

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
Exécution de scripts Snowflake
 -- 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

Paramètres OUT multiples

Lorsque plusieurs paramètres OUT sont trouvés, la clause RETURNS de la procédure devient VARIANT. En effet, cela permet alors d’utiliser OBJECT_CONSTRUCT pour stocker les valeurs des paramètres OUT.

En outre, une instruction RETURN est ajoutée à la fin du corps de la procédure. C’est ici qu’est créé le OBJECT_COSNTRUCT et que sont stockées toutes les valeurs de paramètres OUT. Cet objet sera ensuite utilisé par l’appelant pour affecter la valeur des paramètres au résultat correspondant.

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
Exécution de scripts Snowflake
 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

Paramètres OUT et valeurs de retour

Transact-SQL permet aux procédures d’avoir des valeurs de retour. Lorsqu’une procédure possède à la fois une valeur de retour et un ou des paramètres OUT, une approche similaire au scénario Paramètres OUT multiples est appliquée. La valeur de retour originale est traitée comme le serait un paramètre OUT, elle est donc stockée dans OBJECT_CONSTRUCT et extraite dans la procédure appelante.

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
Exécution de scripts Snowflake
 -- 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

Paramètres OUT du type de données de client

lorsque le paramètre de sortie est un type de client, le processus est similaire à celui d’un type de données ordinaire.

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
Exécution de scripts Snowflake
 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

Problèmes connus

Aucun problème n’a été constaté.

EWIs connexes

  1. SSC-EWI-0073 : En attente de l’examen de l’équivalence fonctionnelle.

  2. SSC-FDM-TS0015 : Le type de données n’est pas pris en charge par Snowflake.

SET

Applies to
  • [x] SQL Server

  • [x] Azure Synapse Analytics

Description

Définit la variable locale spécifiée, précédemment créée à l’aide de l’instruction DECLARE @local_variable., sur la valeur spécifiée. Pour plus d’informations sur Transact-SQL SET, cliquez ici.

Il y a quatre cas SET qui sont les suivants :

 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

Échantillons de modèles de sources

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

Instruction SET en dehors des routines (fonctions et procédures)

Contrairement à Transact-SQL, Snowflake ne prend pas en charge l’exécution d’instructions isolées comme SET en dehors de routines telles que des fonctions ou des procédures. Dans ce cas, l’instruction doit être encapsulée dans un bloc anonyme, comme le montrent les exemples suivants. Cette instruction est généralement utilisée après un DECLARE STATEMENT.

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

Si un scénario ne comporte que des instructions SET, le bloc DECLARE n’est pas nécessaire. Ce scénario produira probablement des erreurs d’environnement d’exécution si l’on tente d’attacher une valeur à une variable qui n’est pas déclarée.

Transact-SQL
 SET @Group = N'North America';
Copy

Snowflake Scripting

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

Problèmes connus

1. SET of a local variable with property name

Ce type de set n’est actuellement pas pris en charge par Snowflake Scripting.

 // 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

Ce type de set n’est actuellement pas pris en charge par Snowflake Scripting.

 // TSQL custom data type with mutator method
SET @p.SetXY(22, 23);   
Copy

EWIs connexes

  1. SSC-EWI-TS0037 : Les curseurs de Snowflake Scripting ne sont pas défilables.

  2. SSC-EWI-0073 : En attente de l’examen de l’équivalence fonctionnelle.

  3. SSC-FDM-TS0013 : Les lignes du curseur de Snowflake Scripting ne sont pas modifiables.

TRY CATCH

Applies to
  • [x] SQL Server

  • [x] Azure Synapse Analytics

Description

Met en œuvre la gestion des erreurs pour Transact SQL. Un groupe d’instructions Transact-SQL peut être inclus dans un bloc TRY. Si une erreur se produit dans le bloc TRY, le contrôle est généralement transféré à un autre groupe d’instructions inclus dans un bloc CATCH.

Échantillons de modèles de sources

L’exemple suivant détaille la transformation pour TRY CATCH à l’intérieur des procédures.

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

Routines extérieures Try Catch (fonctions et procédures)

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

Problèmes connus

Aucun problème n’a été constaté.

EWIs connexes

  1. SSC-FDM-0020 : Plusieurs jeux de résultats sont renvoyés dans des tables temporaires.

WHILE

Applies to
  • [x] SQL Server

  • [x] Azure Synapse Analytics

Description

L’instruction While permet à une instruction SQL ou à un bloc d’instructions d’être exécuté de manière répétée tant que la condition spécifiée est true. L’exécution des instructions dans la boucle WHILE peut être contrôlée depuis l’intérieur de la boucle à l’aide des mots-clés BREAK et CONTINUE.

Pour plus d’informations sur Transact-SQL While, cliquez ici.

 WHILE Boolean_expression   
     { sql_statement | statement_block | BREAK | CONTINUE }
Copy

Remarque : Pour définir un bloc d’instructions, utilisez les mots-clés de contrôle du flux BEGIN et END.

Échantillons de modèles de sources

Code source du modèle de base

Transact-SQL

Le code suivant fait référence à une boucle While dans Transact-SQL qui itère la variable @Iteration et contrôle le flux de la boucle pour qu’elle se termine lorsque la valeur de @Iteration est égale à 10.

Note

Les instructions qui suivent le mot-clé CONTINUE ne seront pas exécutées.

 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

Note

Tout comme Transact-SQL, dans Snowflake Scripting les instructions qui suivent le mot-clé CONTINUE ne seront pas exécutées.

Notez que dans Snowflake Scripting, il n’est pas nécessaire d’utiliser les mots-clés BEGIN et END pour définir un bloc d’instructions, sauf s’il s’agit d’une exigence.

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 permet d’utiliser le mot-clé LOOP au lieu de DO et l’expression END LOOP au lieu de END WHILE.

 WHILE (Boolean_expression) LOOP
    -- statement or statement block
END LOOP;
Copy
|Iteration|
|---------|
|10       |

Copy

While avec Modèle de source de corps vide

Transact-SQL

Note

Notez que cet exemple a été rédigé alors que l’instruction IF ELSE n’était pas prise en charge. Les différences dans les résultats devraient disparaître lorsque la prise en charge de l’instruction sera mise en œuvre.

 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
Exécution de scripts Snowflake

Cette instruction ne peut pas avoir un corps vide dans Snowflake Scripting, pour résoudre ce cas, une instruction par défaut BREAK est ajoutée lorsqu’un corps vide est détecté.

 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

Instruction WHILE en dehors des routines (fonctions et procédures)

Contrairement à Transact-SQL, Snowflake ne prend pas en charge l’exécution d’instructions isolées comme WHILE en dehors de routines telles que des fonctions ou des procédures. Pour ce scénario, l’instruction doit être encapsulée dans un bloc anonyme, comme le montre l’exemple suivant.

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

Problèmes connus

Aucun problème n’a été constaté.

EWIs connexes

  1. SSC-EWI-0073 : En attente de l’examen de l’équivalence fonctionnelle.