Opérateurs de flux

Les opérateurs de flux enchaînent les instructions SQL, les résultats d’une instruction servant d’entrée à une autre instruction. Actuellement, l’opérateur de canal (->>) est le seul opérateur de flux pris en charge par Snowflake.

Canal

Les opérateurs de canal sont similaires aux canaux Unix (|) sur la ligne de commande, mais pour les instructions SQL au lieu des commandes Unix. Pour utiliser l’opérateur de canal, spécifiez une série d’instructions SQL séparées par l’opérateur. Vous pouvez spécifier n’importe quelle instruction SQL valide, telle que SHOW, SELECT, CREATE, INSERT, etc. Après la première instruction SQL, chaque instruction suivante peut prendre en entrée les résultats de n’importe quelle instruction précédente. Dans la clause FROM, une instruction SQL antérieure est référencée par un paramètre comportant le signe du dollar ($) et le numéro de canal, qui est la position relative de l’instruction dans la chaîne à compter de l’instruction actuelle.

L’opérateur de canal enchaîne la série suivante d’instructions SQL, et les commentaires indiquent les numéros de référence relatifs de chaque instruction :

first_st -- Referenced as $4 in last_st, $3 in fourth_st, $2 in third_st, and $1 in second_st
  ->> second_st -- Referenced as $3 in last_st, $2 in fourth_st, and $1 in third_st
  ->> third_st  -- Referenced as $2 in last_st and $1 in fourth_st
  ->> fourth_st -- Referenced as $1 in last_st
  ->> last_st;
Copy

Par exemple, cette série d’instructions SQL comporte une référence à un numéro de canal dans trois instructions SELECT, et chacune d’entre elles prend en entrée les résultats de la première instruction SELECT :

SELECT ...
  ->> SELECT ... FROM $1
  ->> SELECT ... FROM $2
  ->> SELECT ... FROM $3;
Copy

Comme indiqué, vous mettez fin à la chaîne d’instructions SQL en plaçant un point-virgule après la dernière instruction. Ne placez pas de point-virgule après les instructions précédentes de la chaîne. La sortie de l’ensemble de la chaîne est le résultat final de la dernière instruction SQL. Les outils clients, tels que SnowSQL, traitent la chaîne d’instructions comme une instruction unique.

L’opérateur de canal offre les avantages suivants :

  • Simplifie l’exécution des instructions SQL dépendantes.

  • Améliore la lisibilité et la flexibilité des opérations complexes SQL.

Syntaxe

<sql_statement_1> ->> <sql_statement_2> [ ->> <sql_statement_n> ... ]
Copy

Notes sur l’utilisation

  • Chaque instruction produit un résultat qui ne peut être consommé que par une instruction suivante dans la chaîne.

  • Les instructions sont exécutées dans l’ordre spécifié. Contrairement à RESULT_SCAN(LAST_QUERY_ID()), le numéro de canal renvoie au bon jeu de résultats dans la chaîne, que d’autres requêtes aient été exécutées simultanément en dehors de la chaîne ou non.

  • Lorsqu’une instruction consomme les résultats d’une instruction précédente, le jeu de résultats consommés est équivalent au jeu de résultats renvoyés par la fonction RESULT_SCAN à laquelle a été transmise l’ID de la requête de l’instruction précédente.

    Par exemple, ces instructions limitent la sortie de la commande SHOW WAREHOUSES à des colonnes spécifiques :

    SHOW WAREHOUSES;
    
    SELECT "name", "state", "type", "size"
      FROM TABLE(RESULT_SCAN(LAST_QUERY_ID(-1)));
    
    Copy

    Cette instruction utilise l’opérateur de canal pour produire les mêmes opérations :

    SHOW WAREHOUSES
      ->> SELECT "name", "state", "type", "size" FROM $1;
    
    Copy
  • Il n’est pas garantit qu’une requête qui utilise l’opérateur de canal renvoie les lignes dans le même ordre que le jeu de résultats d’entrée d’une requête précédente dans la chaîne. Vous pouvez inclure une clause ORDER BY dans la requête pour spécifier l’ordre.

  • Une erreur soulevée par une instruction SQL interrompt l’exécution de la chaîne et cette erreur est renvoyée au client.

  • Le résultat de la dernière instruction est renvoyé au client.

  • Les instructions sont exécutées sous la forme d’un bloc anonyme Snowflake Scripting.

Limitations

  • Le paramètre $n n’est valable que dans la clause FROM d’une instruction SQL.

  • Chaque instruction SQL produit un résultat qui ne peut être consommé que par une instruction suivante dans la chaîne de canaux. Les résultats ne peuvent pas être consommés en dehors de la chaîne de canaux, à l’exception des résultats de la dernière instruction.

  • Les variables de liaison positionnelles ne sont pas prises en charge.

Exemples

Les exemples suivants utilisent l’opérateur canal :

Sélectionner une liste de colonnes pour la sortie d’une commande SHOW

Exécutez une commande SHOW TABLES et utilisez l’opérateur de canaux pour limiter la sortie aux colonnes created_on, name et owner pour les tables créées après le 15 avril 2025.

SHOW TABLES
  ->> SELECT "created_on" AS creation_date,
             "name" AS table_name,
             "owner" AS table_owner
        FROM $1
        WHERE creation_date > '2025-04-15'::DATE;
Copy
+-------------------------------+-------------+--------------+
| CREATION_DATE                 | TABLE_NAME  | TABLE_OWNER  |
|-------------------------------+-------------+--------------|
| 2025-04-16 08:46:16.130 -0700 | TEST_TABLE1 | ACCOUNTADMIN |
| 2025-04-16 09:44:13.701 -0700 | MYTABLE1    | USER_ROLE    |
| 2025-04-16 08:46:32.092 -0700 | MYTABLE2    | USER_ROLE    |
+-------------------------------+-------------+--------------+

Exécuter les requêtes dont les entrées proviennent de requêtes sur plusieurs tables

Créez d’abord une table dept_pipe_demo et une table emp_pipe_demo, puis insérez des données dans chacune d’elles :

CREATE OR REPLACE TABLE dept_pipe_demo (
  deptno NUMBER(2),
  dname VARCHAR(14),
  loc VARCHAR(13)
  ) AS SELECT * FROM VALUES
     (10, 'ACCOUNTING', 'NEW YORK'),
     (20, 'RESEARCH', 'DALLAS'),
     (30, 'SALES', 'CHICAGO'),
     (40, 'OPERATIONS', 'BOSTON');

CREATE OR REPLACE TABLE emp_pipe_demo (
  empno NUMBER(4),
  ename VARCHAR(10),
  sal NUMBER(7,2),
  deptno NUMBER(2)
  ) AS SELECT * FROM VALUES
    (7369, 'SMITH', 800, 20),
    (7499, 'ALLEN', 1600, 30),
    (7521, 'WARD', 1250, 30),
    (7698, 'BLAKE', 2850, 30),
    (7782, 'CLARK', 2450, 10);
Copy

L’exemple suivant utilise l’opérateur de canaux pour une chaîne d’instructions SQL qui effectuent les opérations suivantes :

  1. Interrogez la table dept_pipe_demo pour renvoyer les lignes où dname est égal à SALES.

  2. Interrogez la table emp_pipe_demo pour trouver les employés dont le salaire est supérieur à 1500 dans le département SALES, en utilisant les résultats de la requête précédente comme entrée et en spécifiant $1 dans la condition WHERE d’une clause FROM.

  3. Exécutez une requête qui renvoie les valeurs ename et sal en utilisant les résultats de la requête précédente comme entrée en spécifiant $1 dans la clause FROM.

SELECT * FROM dept_pipe_demo WHERE dname = 'SALES'
  ->> SELECT * FROM emp_pipe_demo WHERE sal > 1500 AND deptno IN (SELECT deptno FROM $1)
  ->> SELECT ename, sal FROM $1 ORDER BY 2 DESC;
Copy
+-------+---------+
| ENAME |     SAL |
|-------+---------|
| BLAKE | 2850.00 |
| ALLEN | 1600.00 |
+-------+---------+

Note

L’objectif de cet exemple est de montrer comment combiner une série de requêtes à l’aide de l’opérateur de canaux. Cependant, la même sortie peut être obtenue avec une requête de jointures, et les requêtes de jointures sont généralement plus performantes que les requêtes combinées avec l’opérateur de canaux.

Renvoyer le nombre de lignes pour les opérations DML dans une transaction

Créez une table et insérez des lignes une par une. L’enchaînement de toutes les instructions vous permet d’utiliser l’opérateur de canaux pour examiner le résultat de chaque instruction INSERT, qui représente le nombre total de lignes insérées.

Dans chacune des instructions SELECT de l’exemple, le paramètre $1 de la liste SELECT est une référence abrégée pour la première colonne, et non un résultat précédent dans le canal. Le paramètre $n pour un numéro de canal n’est valable que dans la clause FROM.

CREATE OR REPLACE TABLE test_sql_pipe_dml (a INT, b INT)
  ->> INSERT INTO test_sql_pipe_dml VALUES (1, 2)
  ->> INSERT INTO test_sql_pipe_dml VALUES (3, 4)
  ->> INSERT INTO test_sql_pipe_dml VALUES (5, 6)
  ->> INSERT INTO test_sql_pipe_dml VALUES (7, 8)
  ->> SELECT (SELECT $1 FROM $4) +
             (SELECT $1 FROM $3) +
             (SELECT $1 FROM $2) +
             (SELECT $1 FROM $1)
        AS "Number of rows";
Copy
+----------------+
| Number of rows |
|----------------|
|              4 |
+----------------+

L’exemple suivant utilise l’opérateur de canaux pour une chaîne d’instructions SQL qui effectuent les opérations suivantes :

  1. Commencez une transaction.

  2. Insérez une ligne dans la table créée précédemment.

  3. Supprimez des lignes de la table.

  4. Mettez à jour les lignes de la table.

  5. Validez la transaction.

  6. Effectuez une requête sur le nombre de lignes affectées par chaque opération DML.

EXECUTE IMMEDIATE $$
BEGIN TRANSACTION
  ->> INSERT INTO test_sql_pipe_dml VALUES (1, 2)
  ->> DELETE FROM test_sql_pipe_dml WHERE a = 1
  ->> UPDATE test_sql_pipe_dml SET b = 2
  ->> COMMIT
  ->> SELECT
        (SELECT $1 FROM $4) AS "Inserted rows",
        (SELECT $1 FROM $3) AS "Deleted rows",
        (SELECT $1 FROM $2) AS "Updated rows";
$$;
Copy
+---------------+--------------+--------------+
| Inserted rows | Deleted rows | Updated rows |
|---------------+--------------+--------------|
|             1 |            2 |            3 |
+---------------+--------------+--------------+

Renvoyer les résultats des insertions dans une table qui est ensuite supprimée

Cet exemple utilise l’opérateur de canaux pour une chaîne d’instructions SQL qui effectuent les opérations suivantes :

  1. Créez une table avec une colonne IDENTITY.

  2. Insérez des lignes dans la table.

  3. Interrogez la table.

  4. Détruire la table.

  5. Effectuez une requête sur les résultats du canal numéro $2 (l’instruction SELECT).

L’ensemble des résultats consommés dans la dernière instruction SELECT est équivalent au jeu de résultats renvoyés par la fonction RESULT_SCAN pour l’ID de requête de l’instruction SELECT précédente.

CREATE OR REPLACE TABLE test_sql_pipe_drop (
    id INT IDENTITY START 10 INCREMENT 1,
    data VARCHAR)
  ->> INSERT INTO test_sql_pipe_drop (data) VALUES ('row1'), ('row2'), ('row3')
  ->> SELECT * FROM test_sql_pipe_drop
  ->> DROP TABLE test_sql_pipe_drop
  ->> SELECT COUNT(*) "Number of rows", MAX(id) AS "Last ID" FROM $2;
Copy
+----------------+---------+
| Number of rows | Last ID |
|----------------+---------|
|              3 |      12 |
+----------------+---------+