Construction d’instructions SQL au moment de l’exécution¶
Snowflake prend en charge plusieurs techniques différentes pour construire des chaînes d’instructions SQL de manière dynamique au moment de l’exécution. En utilisant ces techniques, vous pouvez spécifier des chaînes SQL plus générales et plus flexibles pour les cas d’utilisation où le texte intégral des instructions SQL est inconnu jusqu’au moment de l’exécution.
Une procédure stockée ou une application peut accepter une entrée utilisateur, puis utiliser cette entrée dans une instruction SQL. Par exemple, une table peut stocker des informations sur les commandes client. Une application ou une procédure stockée peut accepter un ID de commande en entrée et exécuter une requête qui renvoie uniquement les résultats de cette commande spécifique.
Un développeur peut écrire du code de procédure stockée ou du code d’application avec des instructions SQL qui contiennent des espaces réservés, puis lier des variables à ces espaces réservés dans le code. Ces espaces réservés sont appelés variables de liaison. Un développeur peut également écrire du code qui construit des instructions SQL à partir d’une chaîne d’entrée (par exemple, en concaténant des chaînes contenant une commande SQL, des paramètres et des valeurs).
Les techniques suivantes sont disponibles pour construire des instructions SQL dynamiquement au moment de l’exécution :
Fonction TO_QUERY - Cette fonction prend une chaîne SQL avec des paramètres facultatifs en entrée.
Instruction SQL dynamique - Le code d’une procédure stockée ou d’une application prend une entrée et construit une instruction SQL dynamique avec cette entrée. Le code peut faire partie d’une procédure stockée Snowflake Scripting ou Javascript ou d’un bloc anonyme Snowflake Scripting. Vous pouvez également utiliser cette technique dans votre code d’application qui utilise un pilote Snowflake ou le API REST SQL Snowflake.
Note
Lorsque les programmes construisent des instructions SQL avec saisie utilisateur, il existe des risques de sécurité potentiels, comme l’injection SQL. Si les entrées effectuées dans les instructions SQL proviennent de sources externes, assurez-vous qu’elles sont validées. Pour plus d’informations, voir injection SQL.
Utilisation de la fonction TO_QUERY¶
Vous pouvez utiliser la fonction TO_QUERY dans le code pour les procédures stockées et les applications qui construisent des instructions SQL de manière dynamique. Cette fonction de table prend une chaîne SQL en entrée. La chaîne SQL peut également contenir des paramètres et vous pouvez spécifier les arguments à transmettre aux paramètres en tant que variables de liaison.
Voici un exemple simple d’appel de la fonction :
SELECT COUNT(*) FROM TABLE(TO_QUERY('SELECT 1'));
+----------+
| COUNT(*) |
|----------|
| 1 |
+----------+
L’exemple suivant utilise la fonction TO_QUERY dans une procédure stockée :
CREATE OR REPLACE PROCEDURE get_num_results_tq(query VARCHAR)
RETURNS TABLE ()
LANGUAGE SQL
AS
DECLARE
res RESULTSET DEFAULT (SELECT COUNT(*) FROM TABLE(TO_QUERY(:query)));
BEGIN
RETURN TABLE(res);
END;
Remarque : si vous utilisez SnowSQL, Classic Console, ou la méthode execute_stream
ou execute_string
dans le code Python Connector, utilisez cet exemple à la place (voir Utilisation d’Exécution de scripts Snowflake dans SnowSQL, Classic Console, et le connecteur Python) :
CREATE OR REPLACE PROCEDURE get_num_results_tq(query VARCHAR)
RETURNS TABLE ()
LANGUAGE SQL
AS
$$
DECLARE
res RESULTSET DEFAULT (SELECT COUNT(*) FROM TABLE(TO_QUERY(:query)));
BEGIN
RETURN TABLE(res);
END;
$$
;
Appelez la procédure stockée :
CALL get_num_results_tq('SELECT 1');
+----------+
| COUNT(*) |
|----------|
| 1 |
+----------+
Utilisation de l’instruction SQL dynamique dans les procédures stockées et les applications¶
Pour construire des instructions SQL qui prennent en compte la saisie de l’utilisateur, vous pouvez utiliser une instruction SQL dynamique dans une procédure stockée Snowflake Scripting ou Javascript ou dans un bloc anonyme Snowflake Scripting. Vous pouvez également utiliser l’instruction SQL dynamique dans votre code d’application qui utilise un pilote Snowflake ou le API REST SQL Snowflake.
Cet exemple crée une procédure stockée avec Snowflake Scripting. La procédure stockée prend le texte SQL en entrée et construit une chaîne contenant une instruction SQL en y ajoutant le texte. L’instruction SQL dynamique est ensuite exécutée à l’aide de la commande EXECUTE IMMEDIATE.
CREATE OR REPLACE PROCEDURE get_num_results(query VARCHAR)
RETURNS INTEGER
LANGUAGE SQL
AS
DECLARE
row_count INTEGER DEFAULT 0;
stmt VARCHAR DEFAULT 'SELECT COUNT(*) FROM (' || query || ')';
res RESULTSET DEFAULT (EXECUTE IMMEDIATE :stmt);
cur CURSOR FOR res;
BEGIN
OPEN cur;
FETCH cur INTO row_count;
RETURN row_count;
END;
Remarque : si vous utilisez SnowSQL, Classic Console, ou la méthode execute_stream
ou execute_string
dans le code Python Connector, utilisez cet exemple à la place (voir Utilisation d’Exécution de scripts Snowflake dans SnowSQL, Classic Console, et le connecteur Python) :
CREATE OR REPLACE PROCEDURE get_num_results(query VARCHAR)
RETURNS INTEGER
LANGUAGE SQL
AS
$$
DECLARE
row_count INTEGER DEFAULT 0;
stmt VARCHAR DEFAULT 'SELECT COUNT(*) FROM (' || query || ')';
res RESULTSET DEFAULT (EXECUTE IMMEDIATE :stmt);
cur CURSOR FOR res;
BEGIN
OPEN cur;
FETCH cur INTO row_count;
RETURN row_count;
END;
$$
;
L’exemple suivant appelle la procédure :
CALL get_num_results('SELECT 1');
+-----------------+
| GET_NUM_RESULTS |
|-----------------|
| 1 |
+-----------------+
L’instruction SQL dynamique prend en charge les variables de liaison. L’exemple de Snowflake Scripting suivant utilise des variables de liaison représentées par les espaces réservés ?
pour construire des instructions SQL de manière dynamique au moment de l’exécution. Ce bloc sélectionne des données à partir de la table invoices
suivante :
CREATE OR REPLACE TABLE invoices (price NUMBER(12, 2));
INSERT INTO invoices (price) VALUES
(11.11),
(22.22);
Exécuter le bloc anonyme :
DECLARE
rs RESULTSET;
query VARCHAR DEFAULT 'SELECT * FROM invoices WHERE price > ? AND price < ?';
minimum_price NUMBER(12,2) DEFAULT 20.00;
maximum_price NUMBER(12,2) DEFAULT 30.00;
BEGIN
rs := (EXECUTE IMMEDIATE :query USING (minimum_price, maximum_price));
RETURN TABLE(rs);
END;
Remarque : si vous utilisez SnowSQL, Classic Console, ou la méthode execute_stream
ou execute_string
dans le code Python Connector, utilisez cet exemple à la place (voir Utilisation d’Exécution de scripts Snowflake dans SnowSQL, Classic Console, et le connecteur Python) :
EXECUTE IMMEDIATE $$
DECLARE
rs RESULTSET;
query VARCHAR DEFAULT 'SELECT * FROM invoices WHERE price > ? AND price < ?';
minimum_price NUMBER(12,2) DEFAULT 20.00;
maximum_price NUMBER(12,2) DEFAULT 30.00;
BEGIN
rs := (EXECUTE IMMEDIATE :query USING (minimum_price, maximum_price));
RETURN TABLE(rs);
END;
$$
;
+-------+
| PRICE |
|-------|
| 22.22 |
+-------+
Comparaison des techniques de construction d’instructions SQL de manière dynamique¶
Le tableau suivant décrit les avantages et les inconvénients des techniques de construction d’instructions SQL de manière dynamique.
Technique |
Avantages |
Inconvénients |
---|---|---|
Fonction TO_QUERY |
|
|
Instruction SQL dynamique |
|
|