Utilisation des variables¶

Dans Exécution de scripts Snowflake, vous pouvez utiliser des variables dans des expressions, des instructions Exécution de scripts Snowflake et des instructions SQL.

DĂ©claration d’une variable¶

Avant de pouvoir utiliser une variable, vous devez la dĂ©clarer. Lorsque vous dĂ©clarez une variable, vous devez spĂ©cifier le type de la variable de plusieurs façons :

Vous pouvez dĂ©clarer une variable des maniĂšres suivantes :

  • Dans la section DECLARE du bloc, en utilisant l’une des mĂ©thodes suivantes :

    <variable_name> <type> ;
    
    <variable_name> DEFAULT <expression> ;
    
    <variable_name> <type> DEFAULT <expression> ;
    
    Copy
  • Dans la section BEGIN 
 END du bloc (avant d’utiliser la variable) en utilisant la commande LET de l’une des maniĂšres suivantes :

    LET <variable_name> <type> { DEFAULT | := } <expression> ;
    
    LET <variable_name> { DEFAULT | := } <expression> ;
    
    Copy

OĂč :

variable_name

Nom de la variable. Le nom doit suivre les rĂšgles de dĂ©nomination pour Identificateurs d’objet.

type

Le type de donnĂ©es de la variable. Le type de donnĂ©es peut ĂȘtre l’un des suivants :

DEFAULT expression ou . := expression

Affecte la valeur de expression Ă  la variable.

Si type et expression sont tous deux spĂ©cifiĂ©s, l’expression doit correspondre Ă  un type de donnĂ©es correspondant. Si les types ne correspondent pas, vous pouvez convertir la valeur vers le type spĂ©cifiĂ©.

L’exemple suivant dĂ©clare des variables dans la section DECLARE et dans la section BEGIN 
 END du bloc :

DECLARE
  profit number(38, 2) DEFAULT 0.0;
BEGIN
  LET cost number(38, 2) := 100.0;
  LET revenue number(38, 2) DEFAULT 110.0;

  profit := revenue - cost;
  RETURN profit;
END;
Copy

Remarque : Si vous utilisez Snowflake CLI, SnowSQL, Classic Console, ou la mĂ©thode execute_stream ou execute_string dans le code Connecteur Python, utilisez cet exemple Ă  la place (voir Utilisation de Snowflake Scripting dans Snowflake CLI, SnowSQL, le Classic Console et le connecteur Python) :

EXECUTE IMMEDIATE 
$$
DECLARE
  profit number(38, 2) DEFAULT 0.0;
BEGIN
  LET cost number(38, 2) := 100.0;
  LET revenue number(38, 2) DEFAULT 110.0;

  profit := revenue - cost;
  RETURN profit;
END;
$$
;
Copy
+-----------------+
| anonymous block |
|-----------------|
|           10.00 |
+-----------------+

Les sections suivantes expliquent comment le type de donnĂ©es et le scope d’une variable sont dĂ©terminĂ©s :

Pour plus d’informations sur l’attribution d’une valeur Ă  une variable, voir Attribution d’une valeur Ă  une variable dĂ©clarĂ©e.

Comment ExĂ©cution de scripts Snowflake dĂ©duit le type de donnĂ©es d’une variable¶

Lorsque vous dĂ©clarez une variable sans spĂ©cifier explicitement le type de donnĂ©es, ExĂ©cution de scripts Snowflake dĂ©duit le type de donnĂ©es de l’expression que vous attribuez Ă  la variable.

Si vous choisissez d’omettre le type de donnĂ©es dans la dĂ©claration, notez ce qui suit :

  • Si l’expression peut se rĂ©soudre en diffĂ©rents types de donnĂ©es de tailles diffĂ©rentes, Snowflake choisit gĂ©nĂ©ralement le type qui est flexible (par exemple, FLOAT plutĂŽt que NUMBER(3, 1)) et qui a une grande capacitĂ© de stockage (par exemple, VARCHAR plutĂŽt que VARCHAR(4)).

    Par exemple, si vous attribuez Ă  une variable la valeur 12.3, Snowflake peut choisir l’un des nombreux types de donnĂ©es pour cette variable, notamment :

    • NUMBER(3, 1)

    • NUMBER(38, 1)

    • FLOAT

    Dans cet exemple, Snowflake choisit FLOAT.

    Si vous avez besoin d’un type de donnĂ©es spĂ©cifique pour une variable (en particulier un type numĂ©rique ou d’horodatage), Snowflake vous recommande de spĂ©cifier le type de donnĂ©es explicitement, mĂȘme si vous fournissez une valeur initiale.

  • Si Snowflake est incapable de dĂ©duire le type de donnĂ©es prĂ©vu, Snowflake signale une erreur de compilation SQL.

    Par exemple, le code suivant dĂ©clare une variable sans spĂ©cifier explicitement le type de donnĂ©es. Le code dĂ©finit la variable sur la valeur d’un curseur.

    ...
    FOR current_row IN cursor_1 DO:
      LET price := current_row.price_column;
      ...
    
    Copy

    Lorsque le bloc Snowflake Scripting est compilĂ© (par exemple, lorsque la commande CREATE PROCEDURE est exĂ©cutĂ©e), le curseur n’a pas Ă©tĂ© ouvert et le type de donnĂ©es de la colonne dans le curseur est inconnu. En consĂ©quence, Snowflake signale une erreur de compilation SQL :

    092228 (P0000): SQL compilation error:
      error line 7 at position 4 variable 'PRICE' cannot have its type inferred from initializer
    
    Copy

Comprendre la portée des déclarations¶

ExĂ©cution de scripts Snowflake utilise la portĂ©e lexicale. Lorsqu’une variable pour une valeur, un jeu de rĂ©sultats, un curseur ou une exception est dĂ©clarĂ©e dans la section DECLARE d’un bloc, la portĂ©e (ou visibilitĂ©) de l’objet dĂ©clarĂ© est ce bloc et tous les blocs imbriquĂ©s dans ce bloc.

Si un bloc dĂ©clare un objet portant le mĂȘme nom qu’un objet dĂ©clarĂ© dans un bloc externe, dans le bloc interne (et dans tous les blocs Ă  l’intĂ©rieur de ce bloc), seul l’objet du bloc interne est dans la portĂ©e. Lorsqu’un nom d’objet est rĂ©fĂ©rencĂ©, Snowflake recherche l’objet portant ce nom en commençant d’abord par le bloc actuel, puis en allant vers l’extĂ©rieur, un bloc Ă  la fois, jusqu’à ce qu’un objet portant le mĂȘme nom soit trouvĂ©.

Par exemple, si une exception est dĂ©clarĂ©e dans une procĂ©dure stockĂ©e, la portĂ©e de l’exception est limitĂ©e Ă  cette procĂ©dure stockĂ©e. Les procĂ©dures stockĂ©es appelĂ©es par cette procĂ©dure stockĂ©e ne peuvent pas lever (ou traiter) cette exception. Les procĂ©dures stockĂ©es qui appellent cette procĂ©dure ne peuvent pas gĂ©rer (ou lever) cette exception.

Attribution d’une valeur Ă  une variable dĂ©clarĂ©e¶

Pour attribuer une valeur Ă  une variable qui a dĂ©jĂ  Ă©tĂ© dĂ©clarĂ©e, utilisez l’opĂ©rateur := :

<variable_name> := <expression> ;
Copy

OĂč :

variable_name

Nom de la variable. Le nom doit suivre les rĂšgles de dĂ©nomination pour Identificateurs d’objet.

expression

L’expression est Ă©valuĂ©e et la valeur rĂ©sultante est affectĂ©e Ă  la variable.

L’expression doit ĂȘtre Ă©valuĂ©e Ă  un type de donnĂ©es qui correspond au type de la variable. Si l’expression ne correspond pas au type, vous pouvez convertir la valeur au type de la variable.

Dans l’expression, vous pouvez utiliser des fonctions, y compris les fonctions SQL intĂ©grĂ©es et les UDFs (fonctions dĂ©finies par l’utilisateur).

Utilisation d’une variable¶

Vous pouvez utiliser des variables dans des expressions et avec des Ă©lĂ©ments du langage ExĂ©cution de scripts Snowflake (comme RETURN). Par exemple, le code ci-dessous utilise les variables revenue et cost dans une expression et la variable profit dans une instruction RETURN :

DECLARE
  profit NUMBER(38, 2);
  revenue NUMBER(38, 2);
  cost NUMBER(38, 2);
BEGIN
  ...
  profit := revenue - cost;
  ...
RETURN profit;
Copy

Pour utiliser une variable dans un gestionnaire d’exceptions (la section EXCEPTION d’un bloc), la variable doit ĂȘtre dĂ©clarĂ©e dans la section DECLARE ou transmise en argument Ă  une procĂ©dure stockĂ©e. Elle ne peut pas ĂȘtre dĂ©clarĂ©e dans la section BEGIN. .. END. Pour plus d’informations, voir Passer des variables Ă  un gestionnaire d’exceptions.

Astuce

Vous pouvez Ă©galement utiliser et dĂ©finir des variables SQL (session) dans les blocs anonymes de Snowflake Scripting et dans les procĂ©dures stockĂ©es qui s’exĂ©cutent avec les droits de l’appelant. Pour plus d’informations, voir Utiliser et dĂ©finir des variables SQL dans une procĂ©dure stockĂ©e.

Utiliser une variable dans une instruction SQL (liaison)¶

Vous pouvez utiliser une variable dans une instruction SQL, ce qui est parfois appelĂ© variable de liaison. Pour ce faire, faites prĂ©cĂ©der le nom de la variable d’un deux-points. Par exemple :

INSERT INTO my_table (x) VALUES (:my_variable)
Copy

Vous pouvez dĂ©velopper une variable de liaison qui reprĂ©sente un tableau dans une liste de valeurs individuelles en utilisant l’opĂ©rateur de diffusion (**). Pour plus d’informations, voir OpĂ©rateurs d’expansion.

Pour obtenir des informations sur la liaison de variables dans les procĂ©dures stockĂ©es de Snowflake Scripting, consultez Utilisation d’un argument dans une instruction SQL (liaison).

Si vous utilisez la variable comme nom d’un objet (par exemple, le nom d’une table dans la clause FROM d’une instruction SELECT), utilisez le mot-clĂ© IDENTIFIER pour indiquer que la variable reprĂ©sente un identificateur d’objet. Par exemple :

SELECT COUNT(*) FROM IDENTIFIER(:table_name)
Copy

Si vous utilisez une variable dans une expression ou avec un Ă©lĂ©ment du langage Snowflake Scripting (par exemple RETURN), vous n’avez pas besoin de prĂ©fixer la variable par deux points.

Par exemple, vous n’avez pas besoin du prĂ©fixe deux-points dans les cas suivants :

  • Vous utilisez la variable avec RETURN. Dans cet exemple, la variable profit est utilisĂ©e avec un Ă©lĂ©ment du langage ExĂ©cution de scripts Snowflake et n’a pas besoin du prĂ©fixe deux-points.

    RETURN profit;
    
    Copy
  • Vous construisez une chaĂźne contenant une instruction SQL Ă  exĂ©cuter. Dans cet exemple, la variable id_variable est utilisĂ©e dans une expression et n’a pas besoin du prĂ©fixe deux-points.

    LET select_statement := 'SELECT * FROM invoices WHERE id = ' || id_variable;
    
    Copy

En outre, la fonction TO_QUERY fournit une syntaxe simple pour accepter une chaĂźne SQL directement dans la clause FROM d’une instruction SELECT. Pour une comparaison entre la fonction TO_QUERY et le SQL dynamique, voir Construction d’instructions SQL au moment de l’exĂ©cution.

DĂ©finir des variables en fonction des rĂ©sultats d’une instruction SELECT¶

Dans un bloc Snowflake Scripting, vous pouvez utiliser la clause INTO pour dĂ©finir des variables sur les valeurs des expressions spĂ©cifiĂ©es dans une clause SELECT :

SELECT <expression1>, <expression2>, ... INTO :<variable1>, :<variable2>, ... FROM ... WHERE ...;
Copy

Lorsque vous utilisez cette syntaxe :

  • variable1 est dĂ©finie comme la valeur de l”expression1.

  • variable2 est dĂ©finie comme la valeur de l”expression2.

L’instruction SELECT doit retourner une seule ligne.

L’exemple suivant contient une instruction SELECT qui renvoie une seule ligne. L’exemple s’appuie sur les donnĂ©es de cette table :

CREATE OR REPLACE TABLE some_data (id INTEGER, name VARCHAR);
INSERT INTO some_data (id, name) VALUES
  (1, 'a'),
  (2, 'b');
Copy

L’exemple dĂ©finit les variables ExĂ©cution de scripts Snowflake id et name aux valeurs retournĂ©es pour les colonnes portant ces noms.

DECLARE
  id INTEGER;
  name VARCHAR;
BEGIN
  SELECT id, name INTO :id, :name FROM some_data WHERE id = 1;
  RETURN id || ' ' || name;
END;
Copy

Remarque : Si vous utilisez Snowflake CLI, SnowSQL, Classic Console, ou la mĂ©thode execute_stream ou execute_string dans le code Connecteur Python, utilisez cet exemple Ă  la place (voir Utilisation de Snowflake Scripting dans Snowflake CLI, SnowSQL, le Classic Console et le connecteur Python) :

EXECUTE IMMEDIATE $$
DECLARE
  id INTEGER;
  name VARCHAR;
BEGIN
  SELECT id, name INTO :id, :name FROM some_data WHERE id = 1;
  RETURN :id || ' ' || :name;
END;
$$
;
Copy

L’exemple imprime l”id et le name de la ligne renvoyĂ©e par l’instruction SELECT.

+-----------------+
| anonymous block |
|-----------------|
| 1 a             |
+-----------------+
Copy

DĂ©finir une variable sur la valeur de retour d’une procĂ©dure stockĂ©e¶

Voir Utilisation de la valeur renvoyée depuis un appel de procédure stockée.

Exemples d’utilisation de variables¶

L’exemple suivant montre comment dĂ©clarer une variable, affecter une valeur ou une expression Ă  une variable, et convertir une valeur en type de donnĂ©es d’une variable :

DECLARE
  w INTEGER;
  x INTEGER DEFAULT 0;
  dt DATE;
  result_string VARCHAR;
BEGIN
  w := 1;                     -- Assign a value.
  w := 24 * 7;                -- Assign the result of an expression.
  dt := '2020-09-30'::DATE;   -- Explicit cast.
  dt := '2020-09-30';         -- Implicit cast.
  result_string := w::VARCHAR || ', ' || dt::VARCHAR;
  RETURN result_string;
END;
Copy

Remarque : Si vous utilisez Snowflake CLI, SnowSQL, Classic Console, ou la mĂ©thode execute_stream ou execute_string dans le code Connecteur Python, utilisez cet exemple Ă  la place (voir Utilisation de Snowflake Scripting dans Snowflake CLI, SnowSQL, le Classic Console et le connecteur Python) :

EXECUTE IMMEDIATE $$
DECLARE
    w INTEGER;
    x INTEGER DEFAULT 0;
    dt DATE;
    result_string VARCHAR;
BEGIN
    w := 1;                     -- Assign a value.
    w := 24 * 7;                -- Assign the result of an expression.
    dt := '2020-09-30'::DATE;   -- Explicit cast.
    dt := '2020-09-30';         -- Implicit cast.
    result_string := w::VARCHAR || ', ' || dt::VARCHAR;
    RETURN result_string;
END;
$$
;
Copy
+-----------------+
| anonymous block |
|-----------------|
| 168, 2020-09-30 |
+-----------------+

L’exemple suivant utilise une fonction SQL intĂ©grĂ©e dans l’expression :

my_variable := SQRT(variable_x);
Copy

La déclaration suivante spécifie implicitement les types de données des variables profit, cost et revenue en spécifiant une valeur initiale du type de données prévu pour chaque variable.

L’exemple montre Ă©galement comment utiliser l’instruction LET pour dĂ©clarer les variables cost et revenue en dehors de la partie DECLARE du bloc :

DECLARE
  profit number(38, 2) DEFAULT 0.0;
BEGIN
  LET cost number(38, 2) := 100.0;
  LET revenue number(38, 2) DEFAULT 110.0;

  profit := revenue - cost;
  RETURN profit;
END;
Copy

Remarque : Si vous utilisez Snowflake CLI, SnowSQL, Classic Console, ou la mĂ©thode execute_stream ou execute_string dans le code Connecteur Python, utilisez cet exemple Ă  la place (voir Utilisation de Snowflake Scripting dans Snowflake CLI, SnowSQL, le Classic Console et le connecteur Python) :

EXECUTE IMMEDIATE $$
DECLARE
    profit DEFAULT 0.0;
BEGIN
    LET cost := 100.0;
    LET revenue DEFAULT 110.0;
    profit := revenue - cost;
    RETURN profit;
END;
$$
;
Copy
+-----------------+
| anonymous block |
|-----------------|
|              10 |
+-----------------+

L’exemple suivant illustre le scope d’une variable. Cet exemple comprend deux variables et un paramĂštre qui ont tous le mĂȘme nom mais une portĂ©e diffĂ©rente.

L’exemple contient trois blocs : le bloc le plus extĂ©rieur, le bloc central et le bloc le plus intĂ©rieur.

  • Dans le bloc le plus interne, PV_NAME se rĂ©sout en la variable dĂ©clarĂ©e et dĂ©finie dans ce bloc le plus interne (qui a pour valeur innermost block variable).

  • À l’intĂ©rieur du bloc central (et Ă  l’extĂ©rieur du bloc le plus intĂ©rieur), PV_NAME se rĂ©sout en la variable dĂ©clarĂ©e et dĂ©finie dans le bloc central (qui a pour valeur middle block variable).

  • Dans le bloc le plus externe (et Ă  l’extĂ©rieur de tout bloc imbriquĂ©), PV_NAME se rĂ©sout en le paramĂštre transmis Ă  la procĂ©dure stockĂ©e (qui est dĂ©fini comme parameter par l’instruction CALL).

L’exemple s’appuie sur cette table :

CREATE OR REPLACE TABLE names (v VARCHAR);
Copy

Dans cet exemple, l’attribution de la chaĂźne innermost block variable Ă  PV_NAME dans le bloc le plus Ă  l’intĂ©rieur n’impacte pas la valeur de la variable dans le bloc du milieu. La variable du bloc le plus Ă  l’intĂ©rieur est diffĂ©rente de celle du bloc du milieu, mĂȘme si les deux variables ont le mĂȘme nom.

CREATE OR REPLACE PROCEDURE duplicate_name(pv_name VARCHAR)
RETURNS VARCHAR
LANGUAGE SQL
AS
BEGIN
  DECLARE
    PV_NAME VARCHAR;
  BEGIN
    PV_NAME := 'middle block variable';
    DECLARE
      PV_NAME VARCHAR;
    BEGIN
      PV_NAME := 'innermost block variable';
      INSERT INTO names (v) VALUES (:PV_NAME);
    END;
    -- Because the innermost and middle blocks have separate variables
    -- named "pv_name", the INSERT below inserts the value
    -- 'middle block variable'.
    INSERT INTO names (v) VALUES (:PV_NAME);
  END;
  -- This inserts the value of the input parameter.
  INSERT INTO names (v) VALUES (:PV_NAME);
  RETURN 'Completed.';
END;
Copy

Remarque : Si vous utilisez Snowflake CLI, SnowSQL, Classic Console, ou la mĂ©thode execute_stream ou execute_string dans le code Connecteur Python, utilisez cet exemple Ă  la place (voir Utilisation de Snowflake Scripting dans Snowflake CLI, SnowSQL, le Classic Console et le connecteur Python) :

CREATE OR REPLACE PROCEDURE duplicate_name(pv_name VARCHAR)
RETURNS VARCHAR
LANGUAGE SQL
AS
$$
BEGIN
  DECLARE
    PV_NAME VARCHAR;
  BEGIN
    PV_NAME := 'middle block variable';
    DECLARE
    PV_NAME VARCHAR;
    BEGIN
      PV_NAME := 'innermost block variable';
      INSERT INTO names (v) VALUES (:PV_NAME);
    END;
    -- Because the innermost and middle blocks have separate variables
    -- named "pv_name", the INSERT below inserts the value
    -- 'middle block variable'.
    INSERT INTO names (v) VALUES (:PV_NAME);
  END;
  -- This inserts the value of the input parameter.
  INSERT INTO names (v) VALUES (:PV_NAME);
  RETURN 'Completed.';
END;
$$
;
Copy

Appelez la procĂ©dure stockĂ©e :

CALL duplicate_name('parameter');
Copy

VĂ©rifiez les valeurs dans la table :

SELECT *
    FROM names
    ORDER BY v;
Copy
+--------------------------+
| V                        |
|--------------------------|
| innermost block variable |
| middle block variable    |
| parameter                |
+--------------------------+

La sortie s’affiche :

  • Dans le bloc imbriquĂ© le plus Ă  l’intĂ©rieur (qui Ă©tait imbriquĂ© sur deux couches), la variable PV_NAME du bloc intĂ©rieur a Ă©tĂ© utilisĂ©e.

  • Dans le bloc du milieu (qui Ă©tait imbriquĂ© sur une couche), la variable PV_NAME de ce bloc Ă©tait utilisĂ©e.

  • Dans le bloc le plus extĂ©rieur, le paramĂštre a Ă©tĂ© utilisĂ©.

Pour un exemple de liaison d’une variable lors de l’ouverture d’un curseur, voir les exemples d’ouverture de curseurs.