Utilisation des RESULTSETs¶
Cette rubrique explique comment utiliser des RESULTSET dans Exécution de scripts Snowflake.
Introduction¶
Dans Exécution de scripts Snowflake, un RESULTSET est un type de données SQL qui pointe vers le jeu de résultats d’une requête.
Étant donné qu’un RESULTSET n’est qu’un pointeur vers les résultats, vous devez effectuer l’une des opérations suivantes pour accéder aux résultats par le biais du RESULTSET :
Utilisez la syntaxe
TABLE(...)
pour récupérer les résultats sous forme de tableau.Itérez sur le RESULTSET avec un curseur.
Vous trouverez ci-dessous des exemples de ces deux types.
Comprendre les différences entre un curseur et un RESULTSET¶
Un RESULTSET et un curseur permettent tous deux d’accéder au jeu de résultats d’une requête. Toutefois, ces objets présentent les différences suivantes :
Le moment où la requête est exécutée.
Pour un curseur, la requête est exécutée lorsque vous exécutez la commande OPEN sur le curseur.
Pour un RESULTSET, la requête est exécutée lorsque vous l’assignez au RESULTSET (soit dans la section DECLARE, soit dans le bloc BEGIN … END).
Prise en charge de la liaison dans la commande OPEN.
Lorsque vous déclarez un curseur, vous pouvez spécifier des paramètres de liaison (caractères
?
). Plus tard, lorsque vous exécuterez la commande OPEN , vous pourrez lier des variables à ces paramètres dans la clause USING.RESULTSET ne prend pas en charge la commande OPEN. Toutefois, vous pouvez lier des variables dans les commandes SQL avant de renvoyer le jeu de résultats.
En général, il est plus simple d’utiliser RESULTSET lorsque vous souhaitez renvoyer une table contenant le jeu de résultats d’une requête. Cependant, vous pouvez également renvoyer une table à partir d’un bloc Exécution de scripts Snowflake avec un curseur. Pour ce faire, vous pouvez transmettre le curseur à RESULTSET_FROM_CURSOR(cursor)
pour obtenir un RESULTSET et passer ce RESULTSET dans TABLE(...)
. Voir Retourner une table pour un curseur.
Déclarer un RESULTSET¶
Vous pouvez déclarer un RESULTSET dans la section DECLARE d’un bloc ou dans la section BEGIN … END du bloc.
Dans la section DECLARE, utilisez la syntaxe décrite dans Syntaxe de la déclaration RESULTSET. Par exemple :
DECLARE ... res RESULTSET DEFAULT (SELECT col1 FROM mytable ORDER BY col1);
Dans le bloc BEGIN … END, utilisez la syntaxe décrite dans Syntaxe d’affectation de RESULTSET. Par exemple :
BEGIN ... LET res RESULTSET := (SELECT col1 FROM mytable ORDER BY col1);
Attribution d’une requête à un RESULTSET déclaré¶
Pour affecter le résultat d’une requête à un RESULTSET qui a déjà été déclaré, utilisez la syntaxe suivante :
<resultset_name> := [ ASYNC ] ( <query> ) ;
Où :
resultset_name
Nom de l” RESULTSET.
Le nom doit être unique dans le scope actuel.
Le nom doit suivre les règles de dénomination pour Identificateurs d’objet.
ASYNC
Exécute la requête en tant que tâche enfant asynchrone.
query
La requête à attribuer au RESULTSET.
Pour affecter une requête à un RESULTSET :
DECLARE
res RESULTSET;
BEGIN
res := (SELECT col1 FROM mytable ORDER BY col1);
...
Pour affecter une requête à un RESULTSET et exécuter la requête en tant que tâche enfant asynchrone :
DECLARE
res RESULTSET;
BEGIN
res := ASYNC (SELECT col1 FROM mytable ORDER BY col1);
...
Pour construire une chaîne SQL de manière dynamique pour la requête, définissez query
sur (EXECUTE IMMEDIATE string_of_sql)
. Par exemple :
DECLARE
res RESULTSET;
col_name VARCHAR;
select_statement VARCHAR;
BEGIN
col_name := 'col1';
select_statement := 'SELECT ' || col_name || ' FROM mytable';
res := (EXECUTE IMMEDIATE :select_statement);
RETURN TABLE(res);
END;
Bien que vous puissiez définir query
sur une instruction EXECUTE IMMEDIATE pour un RESULTSET, vous ne pouvez pas le faire pour un curseur.
Utiliser un RESULTSET¶
La requête pour un RESULTSET est exécutée lorsque l’objet est associé à cette requête. Par exemple :
Lorsque vous déclarez un RESULTSET et définissez la clause DEFAULT sur une requête, celle-ci est exécutée à ce moment précis.
Lorsque vous utilisez l’opérateur
:=
pour affecter une requête à un RESULTSET, la requête est exécutée à ce moment précis.
Note
Étant donné qu’un RESULTSET pointe vers le jeu de résultats d’une requête (et ne contient pas le jeu de résultats d’une requête), un RESULTSET n’est valide que tant que les résultats de la requête sont mis en cache (généralement 24 heures). Pour plus de détails sur la mise en cache des résultats des requêtes, voir Utilisation de résultats de requête persistants.
Une fois la requête exécutée, vous pouvez accéder aux résultats en utilisant un curseur. Vous pouvez également renvoyer les résultats sous forme de table à partir d’une procédure stockée.
Utilisation d’un curseur pour accéder à des données d’un RESULTSET¶
Pour utiliser un curseur afin d’accéder aux données d’un RESULTSET, déclarez le curseur sur l’objet. Par exemple :
DECLARE
...
res RESULTSET DEFAULT (SELECT col1 FROM mytable ORDER BY col1);
c1 CURSOR FOR res;
Notez que lorsque vous déclarez un curseur sur un RESULTSET, le curseur a accès aux données déjà présentes dans le RESULTSET. L’exécution de la commande OPEN sur le curseur n’exécute pas à nouveau la requête pour le RESULTSET.
Vous pouvez alors ouvrir le curseur et utiliser le curseur pour extraire les données.
Note
Si les résultats comprennent des valeurs GEOGRAPHY, vous devez convertir ces valeurs en type GEOGRAPHY avant de les transmettre à toute fonction qui attend des valeurs d’entrée GEOGRAPHY. Voir Utiliser un curseur pour récupérer une valeur GEOGRAPHY.
Retourner un RESULTSET comme une table¶
Si vous voulez retourner les résultats vers lesquels pointe le RESULTSET, passez le RESULTSET à TABLE(...)
. Par exemple :
CREATE PROCEDURE f()
RETURNS TABLE(column_1 INTEGER, column_2 VARCHAR)
...
RETURN TABLE(my_resultset_1);
...
C’est similaire à la façon dont TABLE(...)
est utilisé avec les fonctions de table (comme RESULT_SCAN)
Comme le montre l’exemple, si vous écrivez une procédure stockée qui renvoie une table, vous devez déclarer que la procédure stockée renvoie une table.
Note
Actuellement, la syntaxe TABLE(resultset_name)
n’est prise en charge que dans l’instruction RETURN.
Notez que même si vous avez utilisé un curseur pour extraire des lignes de RESULTSET, la table renvoyée par TABLE(resultset_name)
contient toujours toutes les lignes (et pas seulement celles qui commencent à partir du pointeur de ligne interne du curseur).
Limites du type de données RESULTSET¶
Bien que RESULTSET soit un type de données, Snowflake ne prend pas encore en charge :
Déclarer une colonne de type RESULTSET.
Déclarer un paramètre de type RESULTSET.
Déclarer le type de retour d’une procédure stockée comme un RESULTSET.
Snowflake prend en charge RESULTSET uniquement dans Exécution de scripts Snowflake.
En outre, vous ne pouvez pas utiliser un RESULTSET directement comme table. Par exemple, ce qui suit n’est pas valide :
SELECT * FROM my_result_set;
Exemples d’utilisation d’un RESULTSET¶
Les sections suivantes fournissent des exemples d’utilisation d’un RESULTSET :
Exemple : renvoyer une table à partir d’une procédure stockée
Exemple : déclarer une variable RESULTSET sans clause DEFAULT
Pour des exemples utilisant le mot-clé ASYNC pour exécuter des requêtes spécifiées pour RESULTSETs en tant que tâches enfants asynchrones, voir Exemples d’utilisation de tâches enfants asynchrones.
Configuration des données pour les exemples¶
Les exemples ci-dessous utilisent la table et les données présentées ci-dessous :
CREATE OR REPLACE TABLE t001 (a INTEGER, b VARCHAR);
INSERT INTO t001 (a, b) VALUES
(1, 'row1'),
(2, 'row2');
Exemple : renvoyer une table à partir d’une procédure stockée¶
Le code suivant montre comment déclarer un RESULTSET et renvoyer les résultats vers lesquels pointe le RESULTSET. La clause RETURNS de la commande CREATE PROCEDURE déclare que la procédure stockée renvoie une table, qui contient une colonne de type INTEGER.
L’instruction RETURN à l’intérieur du bloc utilise la syntaxe TABLE(...)
pour renvoyer les résultats sous forme de table.
Créez la procédure stockée :
CREATE OR REPLACE PROCEDURE test_sp()
RETURNS TABLE(a INTEGER)
LANGUAGE SQL
AS
DECLARE
res RESULTSET DEFAULT (SELECT a FROM t001 ORDER BY a);
BEGIN
RETURN TABLE(res);
END;
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 test_sp()
RETURNS TABLE(a INTEGER)
LANGUAGE SQL
AS
$$
DECLARE
res RESULTSET default (SELECT a FROM t001 ORDER BY a);
BEGIN
RETURN TABLE(res);
END;
$$;
Appelez la procédure stockée :
CALL test_sp();
+---+
| A |
|---|
| 1 |
| 2 |
+---+
Vous pouvez aussi utiliser la fonction RESULT_SCAN pour traiter les résultats de l’appel de la procédure stockée :
SELECT *
FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))
ORDER BY 1;
+---+
| A |
|---|
| 1 |
| 2 |
+---+
Exemple : construire l’instruction SQL dynamiquement¶
Vous pouvez construire le SQL de manière dynamique. L’exemple suivant exécute la même requête que la procédure stockée ci-dessus, mais utilise une instruction SQL construite dynamiquement :
CREATE OR REPLACE PROCEDURE test_sp_dynamic(table_name VARCHAR)
RETURNS TABLE(a INTEGER)
LANGUAGE SQL
AS
DECLARE
res RESULTSET;
query VARCHAR DEFAULT 'SELECT a FROM IDENTIFIER(?) ORDER BY a;';
BEGIN
res := (EXECUTE IMMEDIATE :query USING(table_name));
RETURN TABLE(res);
END;
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 test_sp_dynamic(table_name VARCHAR)
RETURNS TABLE(a INTEGER)
LANGUAGE SQL
AS
$$
DECLARE
res RESULTSET;
query VARCHAR DEFAULT 'SELECT a FROM IDENTIFIER(?) ORDER BY a;';
BEGIN
res := (EXECUTE IMMEDIATE :query USING(table_name));
RETURN TABLE(res);
END
$$
;
Pour exécuter l’exemple, appelez la procédure stockée et indiquez le nom de la table :
CALL test_sp_dynamic('t001');
+---+
| A |
|---|
| 1 |
| 2 |
+---+
Exemple : déclarer une variable RESULTSET sans clause DEFAULT¶
Le code suivant montre comment déclarer un RESULTSET sans clause DEFAULT (c’est-à-dire sans associer une requête à la RESULTSET), puis associer la RESULTSET à une requête ultérieurement.
CREATE OR REPLACE PROCEDURE test_sp_02()
RETURNS TABLE(a INTEGER)
LANGUAGE SQL
AS
DECLARE
res RESULTSET;
BEGIN
res := (SELECT a FROM t001 ORDER BY a);
RETURN TABLE(res);
END;
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 test_sp_02()
RETURNS TABLE(a INTEGER)
LANGUAGE SQL
AS
$$
DECLARE
res RESULTSET;
BEGIN
res := (SELECT a FROM t001 ORDER BY a);
RETURN TABLE(res);
END;
$$;
Pour exécuter l’exemple, appelez la procédure stockée :
CALL test_sp_02();
+---+
| A |
|---|
| 1 |
| 2 |
+---+
Exemple : utiliser un CURSOR avec un RESULTSET¶
Le code suivant montre comment utiliser un curseur pour itérer sur les lignes d’un RESULTSET :
Créez la procédure stockée :
CREATE OR REPLACE PROCEDURE test_sp_03()
RETURNS VARCHAR
LANGUAGE SQL
AS
DECLARE
accumulator INTEGER DEFAULT 0;
res1 RESULTSET DEFAULT (SELECT a FROM t001 ORDER BY a);
cur1 CURSOR FOR res1;
BEGIN
FOR row_variable IN cur1 DO
accumulator := accumulator + row_variable.a;
END FOR;
RETURN accumulator::VARCHAR;
END;
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 test_sp_03()
RETURNS INTEGER
LANGUAGE SQL
AS
$$
DECLARE
accumulator INTEGER DEFAULT 0;
res1 RESULTSET DEFAULT (SELECT a FROM t001 ORDER BY a);
cur1 CURSOR FOR res1;
BEGIN
FOR row_variable IN cur1 DO
accumulator := accumulator + row_variable.a;
END FOR;
RETURN accumulator;
END;
$$;
Appelez la procédure stockée et les résultats ajoutent les valeurs de a
dans la table (1 + 2) :
CALL test_sp_03();
+------------+
| TEST_SP_03 |
|------------|
| 3 |
+------------+
Autres exemples d’utilisation d’un RESULTSET¶
Voici d’autres exemples qui utilisent RESULTSET :
Utilisez une boucle basée sur RESULTSET FOR
Cet exemple vous montre comment utiliser une boucle FOR qui itère sur RESULTSET.
Renvoi d’une table pour un curseur
Cet exemple vous montre comment utiliser un curseur pour renvoyer une table de données dans un RESULTSET.
Mettre à jour les données d’une table à l’aide d’une entrée de l’utilisateur
Cet exemple vous montre comment utiliser des variables de liaison basées sur l’entrée de l’utilisateur pour mettre à jour les données d’une table. Il utilise une boucle FOR avec une logique conditionnelle pour parcourir les lignes d’un RESULTSET.
Filtrer et collecter les données
Cet exemple vous montre comment utiliser un RESULTSET pour collecter des données et les insérer dans une table afin de suivre les tendances historiques.