CALL (avec procédure anonyme)¶
Crée et appelle une procédure anonyme qui est comme une procédure stockée mais qui n’est pas stockée pour une utilisation ultérieure.
Avec cette commande, vous créez une procédure anonyme définie par des paramètres dans la clause WITH et vous appelez cette procédure.
Il n’est pas nécessaire d’avoir un rôle avec des privilèges de schéma CREATE PROCEDURE pour cette commande.
La procédure s’exécute avec les droits de l’appelant, ce qui signifie que la procédure s’exécute avec les privilèges de l’appelant, utilise le contexte de session actuel et a accès aux variables et paramètres de session de l’appelant.
- Voir aussi :
Syntaxe¶
Java et Scala¶
WITH <name> AS PROCEDURE ([ <arg_name> <arg_data_type> ]) [ , ... ] )
RETURNS { <result_data_type> [ [ NOT ] NULL ] | TABLE ( [ <col_name> <col_data_type> [ , ... ] ] ) }
LANGUAGE { SCALA | JAVA }
RUNTIME_VERSION = '<scala_or_java_runtime_version>'
PACKAGES = ( 'com.snowflake:snowpark:<version>' [, '<package_name_and_version>' ...] )
[ IMPORTS = ( '<stage_path_and_file_name_to_read>' [, '<stage_path_and_file_name_to_read>' ...] ) ]
HANDLER = '<fully_qualified_method_name>'
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
[ AS '<procedure_definition>' ]
[ , <cte_nameN> [ ( <cte_column_list> ) ] AS ( SELECT ... ) ]
CALL <name> ( [ [ <arg_name> => ] <arg> , ... ] )
[ INTO :<snowflake_scripting_variable> ]
Pour les procédures Java et Scala avec des gestionnaires en zone de préparation, utilisez la syntaxe suivante :
WITH <name> AS PROCEDURE ([ <arg_name> <arg_data_type> ]) [ , ... ] )
RETURNS { <result_data_type> [ [ NOT ] NULL ] | TABLE ( [ <col_name> <col_data_type> [ , ... ] ] ) }
LANGUAGE { SCALA | JAVA }
RUNTIME_VERSION = '<scala_or_java_runtime_version>'
PACKAGES = ( 'com.snowflake:snowpark:<version>' [, '<package_name_and_version>' ...] )
[ IMPORTS = ( '<stage_path_and_file_name_to_read>' [, '<stage_path_and_file_name_to_read>' ...] ) ]
HANDLER = '<fully_qualified_method_name>'
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
[ , <cte_nameN> [ ( <cte_column_list> ) ] AS ( SELECT ... ) ]
CALL <name> ( [ [ <arg_name> => ] <arg> , ... ] )
[ INTO :<snowflake_scripting_variable> ]
JavaScript¶
WITH <name> AS PROCEDURE ([ <arg_name> <arg_data_type> ]) [ , ... ] )
RETURNS <result_data_type> [ [ NOT ] NULL ]
LANGUAGE JAVASCRIPT
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
AS '<procedure_definition>'
[ , <cte_nameN> [ ( <cte_column_list> ) ] AS ( SELECT ... ) ]
CALL <name> ( [ [ <arg_name> => ] <arg> , ... ] )
[ INTO :<snowflake_scripting_variable> ]
Python¶
Pour les procédures en ligne, utilisez la syntaxe suivante :
WITH <name> AS PROCEDURE ( [ <arg_name> <arg_data_type> ] [ , ... ] )
RETURNS { <result_data_type> [ [ NOT ] NULL ] | TABLE ( [ <col_name> <col_data_type> [ , ... ] ] ) }
LANGUAGE PYTHON
RUNTIME_VERSION = '<python_version>'
PACKAGES = ( 'snowflake-snowpark-python[==<version>]'[, '<package_name>[==<version>]' ... ])
[ IMPORTS = ( '<stage_path_and_file_name_to_read>' [, '<stage_path_and_file_name_to_read>' ...] ) ]
HANDLER = '<function_name>'
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
[ , <cte_nameN> [ ( <cte_column_list> ) ] AS ( SELECT ... ) ]
AS '<procedure_definition>'
CALL <name> ( [ [ <arg_name> => ] <arg> , ... ] )
[ INTO :<snowflake_scripting_variable> ]
Pour une procédure stockée dans laquelle le code se trouve dans un fichier sur une zone de préparation, utilisez la syntaxe suivante :
WITH <name> AS PROCEDURE ( [ <arg_name> <arg_data_type> ] [ , ... ] )
RETURNS { <result_data_type> [ [ NOT ] NULL ] | TABLE ( [ <col_name> <col_data_type> [ , ... ] ] ) }
LANGUAGE PYTHON
RUNTIME_VERSION = '<python_version>'
PACKAGES = ( 'snowflake-snowpark-python[==<version>]'[, '<package_name>[==<version>]' ... ])
[ IMPORTS = ( '<stage_path_and_file_name_to_read>' [, '<stage_path_and_file_name_to_read>' ...] ) ]
HANDLER = '<module_file_name>.<function_name>'
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
[ , <cte_nameN> [ ( <cte_column_list> ) ] AS ( SELECT ... ) ]
CALL <name> ( [ [ <arg_name> => ] <arg> , ... ] )
[ INTO :<snowflake_scripting_variable> ]
Exécution de scripts Snowflake¶
WITH <name> AS PROCEDURE ([ <arg_name> <arg_data_type> ]) [ , ... ] )
RETURNS { <result_data_type> | TABLE ( [ <col_name> <col_data_type> [ , ... ] ] ) }
LANGUAGE SQL
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
AS '<procedure_definition>'
[ , <cte_nameN> [ ( <cte_column_list> ) ] AS ( SELECT ... ) ]
CALL <name> ( [ [ <arg_name> => ] <arg> , ... ] )
[ INTO :<snowflake_scripting_variable> ]
Paramètres requis¶
Toutes les langues¶
WITH name AS PROCEDURE ( [ arg_name arg_data_type ] [ , ... ] )
Spécifie l’identificateur (
name
) et tout argument d’entrée pour la procédure.Pour l’identificateur :
L’identificateur doit commencer par un caractère alphabétique et ne peut pas contenir d’espaces ou de caractères spéciaux à moins que toute la chaîne d’identificateur soit délimitée par des guillemets doubles (p. ex. « Mon objet »). Les identificateurs entre guillemets doubles sont également sensibles à la casse. Voir Exigences relatives à l’identificateur.
Pour les arguments d’entrée :
Pour
arg_name
, spécifiez le nom de l’argument d’entrée.Pour
arg_data_type
, utilisez le type de données Snowflake qui correspond au langage du gestionnaire que vous utilisez.Pour les procédures Java, voir Mappages de type de données SQL-Java.
Pour les procédures JavaScript, voir Mappage de type de données SQL et JavaScript.
Pour les procédures Python, voir Mappages des types de données SQL-Python.
Pour les procédures Scala, voir Mappages de type de données SQL-Scala.
Pour Exécution de scripts Snowflake, un type de données SQL.
Note
Pour les procédures que vous écrivez en Java, Python ou Scala (qui utilisent des APIs Snowpark), omettez l’argument pour l’objet Snowpark
Session
.L’argument
Session
n’est pas un paramètre formel que vous spécifiez dans. Lorsque vous exécutez cette commande, Snowflake crée automatiquement un objetSession
et le transmet à la fonction de gestionnaire de votre procédure stockée.
RETURNS result_data_type [ [ NOT ] NULL ]
Spécifie le type du résultat renvoyé par la procédure.
Utilisez NOT NULL pour spécifier que la procédure doit renvoyer uniquement des valeurs non nulles ; la valeur par défaut est NULL, ce qui signifie que la procédure peut renvoyer NULL.
Pour
result_data_type
, utilisez le type de données Snowflake qui correspond au type de langage que vous utilisez.Pour les procédures Java, voir Mappages de type de données SQL-Java.
Pour les procédures JavaScript, voir Mappage de type de données SQL et JavaScript.
Pour les procédures Python, voir Mappages des types de données SQL-Python.
Pour les procédures Scala, voir Mappages de type de données SQL-Scala.
Pour Exécution de scripts Snowflake, un type de données SQL.
Note
Les procédures que vous écrivez en Java ou Scala doivent avoir une valeur de retour. Dans Python, lorsqu’une procédure ne renvoie aucune valeur, on considère qu’elle renvoie
None
.Notez que, quel que soit le langage du gestionnaire, la clause WITH de cette commande doit inclure une clause RETURNS qui définit un type de retour, même si la procédure ne renvoie rien explicitement.
Pour
RETURNS TABLE ( [ col_name col_data_type [ , ... ] ] )
, si vous connaissez les types de données Snowflake des colonnes de la table renvoyée, spécifiez les noms et les types de colonnes :WITH get_top_sales() AS PROCEDURE RETURNS TABLE (sales_date DATE, quantity NUMBER) ... CALL get_top_sales();
Sinon (par exemple, si vous déterminez les types de colonnes pendant l’exécution), vous pouvez omettre les noms et les types de colonnes :
WITH get_top_sales() AS PROCEDURE ... RETURNS TABLE () CALL get_top_sales();
Note
Actuellement, dans la clause
RETURNS TABLE(...)
, vous ne pouvez pas spécifier GEOGRAPHY comme type de colonne. Ceci s’applique que vous créiez une procédure stockée ou anonyme.CREATE OR REPLACE PROCEDURE test_return_geography_table_1() RETURNS TABLE(g GEOGRAPHY) ...
WITH test_return_geography_table_1() AS PROCEDURE RETURNS TABLE(g GEOGRAPHY) ... CALL test_return_geography_table_1();
Si vous tentez de spécifier GEOGRAPHY comme type de colonne, l’appel de la procédure stockée entraîne une erreur :
Stored procedure execution error: data type of returned table does not match expected returned table type
Pour contourner ce problème, vous pouvez omettre les arguments et les types de colonnes dans
RETURNS TABLE()
.CREATE OR REPLACE PROCEDURE test_return_geography_table_1() RETURNS TABLE() ...
WITH test_return_geography_table_1() AS PROCEDURE RETURNS TABLE() ... CALL test_return_geography_table_1();
RETURNS TABLE(...)
est pris en charge uniquement lorsque le gestionnaire est écrit dans les langages suivants :
En pratique, en dehors d’un bloc Exécution de scripts Snowflake, la valeur renvoyée ne peut pas être utilisée, car l’appel ne peut pas faire partie d’une expression.
LANGUAGE language
Spécifie la langue du code du gestionnaire de la procédure.
Actuellement, les valeurs prises en charge pour
language
comprennent :JAVA
(pour Java).JAVASCRIPT
(pour JavaScript)PYTHON
(pour Python)SCALA
(pour Scala).SQL
(pour Exécution de scripts Snowflake)
AS procedure_definition
Définit le code exécuté par la procédure. La définition peut consister en n’importe quel code valide.
Remarques :
Pour les procédures dont le code n’est pas en ligne, omettez la clause AS. Cela inclut des procédures dont les gestionnaires sont dans une zone de préparation.
Utilisez plutôt la clause IMPORTS pour spécifier l’emplacement du fichier contenant le code de la procédure. Pour plus de détails, voir :
Vous devez utiliser les délimiteurs de littéral de chaîne (
'
ou$$
) autour de laprocedure definition
, même dans Exécution de scripts Snowflake.Pour les procédures en JavaScript et si vous écrivez une chaîne qui contient de nouvelles lignes, vous pouvez utiliser des guillemets (également appelés « backticks ») autour de la chaîne.
L’exemple ci-dessous d’une procédure JavaScript utilise
$$
et des guillemets, car le corps de la procédure stockée contient des guillemets simples et des guillemets doubles :WITH proc3 AS PROCEDURE () RETURNS VARCHAR LANGUAGE javascript AS $$ var rs = snowflake.execute( { sqlText: `INSERT INTO table1 ("column 1") SELECT 'value 1' AS "column 1" ;` } ); return 'Done.'; $$ CALL proc3();
Snowflake ne valide pas le code du gestionnaire. Cependant, un code de gestionnaire non valide entraînera des erreurs lorsque vous exécuterez la commande.
Pour plus de détails sur les procédures stockées, voir Travailler avec des procédures stockées.
CALL name ( [ [ arg_name => ] arg , ... ] )
Spécifie l’identificateur (
name
) pour la procédure à appeler et pour tout argument d’entrée.Vous pouvez spécifier les arguments d’entrée soit par leur nom (
arg_name => arg
) , soit par leur position (arg
).Remarques :
Vous devez spécifier tous les arguments soit par leur nom, soit par leur position. Vous ne pouvez pas spécifier certains arguments par leur nom et d’autres par leur position.
Lorsque vous spécifiez un argument par son nom, vous ne pouvez pas utiliser de guillemets doubles autour du nom de l’argument.
Si deux fonctions ou deux procédures ont le même nom, mais des types d’arguments différents, vous pouvez utiliser les noms des arguments pour spécifier la fonction ou la procédure à exécuter, si les noms des arguments sont différents. Reportez-vous à Surcharge de procédures et de fonctions.
Java, Python ou Scala¶
RUNTIME_VERSION = 'language_runtime_version'
Version de la runtime du langage à utiliser. Les versions prises en charge sont les suivantes :
Java : 11
Python :
3,8
3,9
3,10
3,11
Scala : 2.12
PACKAGES = ( 'snowpark_package_name' [, 'package_name' ...] )
Une liste, séparée par des virgules, des noms des paquets déployés dans Snowflake qui doivent être inclus dans l’environnement d’exécution du code du gestionnaire. Le package Snowpark est requis pour les procédures, il doit donc toujours être référencé dans la clause PACKAGES. Pour plus d’informations sur Snowpark, voir API Snowpark.
Par défaut, l’environnement dans lequel Snowflake exécute les procédures comprend un ensemble sélectionné de packages pour les langages pris en charge. Lorsque vous référencez ces paquets dans la clause PACKAGES, il n’est pas nécessaire de référencer un fichier contenant le paquet dans la clause IMPORTS car le paquet est déjà disponible dans Snowflake.
Pour obtenir la liste des packages et des versions pris en charge pour un langage particulier, interrogez la vue INFORMATION_SCHEMA.PACKAGES, en spécifiant le langage. Par exemple :
SELECT * FROM information_schema.packages WHERE language = '<language>';
où
language
estjava
,python
, ouscala
.La syntaxe pour faire référence à un package dans la clause PACKAGES varie selon le langage du package, comme décrit ci-dessous.
Java
Spécifiez le nom du paquet et le numéro de version en utilisant la forme suivante :
domain:package_name:version
Pour spécifier la dernière version, spécifiez
latest
pourversion
.Par exemple, pour inclure un paquet de la dernière bibliothèque Snowpark dans Snowflake, utilisez ce qui suit :
PACKAGES = ('com.snowflake:snowpark:latest')
Lorsque vous spécifiez un paquet de la bibliothèque Snowpark, vous devez spécifier la version 1.3.0 ou une version ultérieure.
Python
Snowflake comprend un grand nombre de paquets disponibles via Anaconda ; pour plus d’informations, voir Utilisation de paquets tiers.
Spécifiez le nom du paquet et le numéro de version en utilisant la forme suivante :
package_name[==version]
Pour spécifier la dernière version, omettez le numéro de version.
Par exemple, pour inclure la version du paquet spacy 2.3.5 (ainsi que la dernière version du paquet Snowpark requis), utilisez ce qui suit :
PACKAGES = ('snowflake-snowpark-python', 'spacy==2.3.5')
Lorsque vous spécifiez un paquet de la bibliothèque Snowpark, vous devez spécifier la version 0.4.0 ou une version ultérieure. Omettez le numéro de version pour utiliser la dernière version disponible dans Snowflake.
Scala
Spécifiez le nom du paquet et le numéro de version en utilisant la forme suivante :
domain:package_name:version
Pour spécifier la dernière version, spécifiez
latest
pourversion
.Par exemple, pour inclure un paquet de la dernière bibliothèque Snowpark dans Snowflake, utilisez ce qui suit :
PACKAGES = ('com.snowflake:snowpark:latest')
Snowflake prend en charge l’utilisation de Snowpark version 0.9.0 ou ultérieure dans une procédure Scala. Notez toutefois que ces versions présentent des limites. Par exemple, les versions antérieures à la version 1.1.0 ne prennent pas en charge l’utilisation de transactions dans une procédure.
HANDLER = 'fully_qualified_method_name'
Python
Utilisez le nom de la fonction ou de la méthode de la procédure. Cela peut varier selon que le code est en ligne ou référencé au niveau d’une zone de préparation.
Lorsque le code est en ligne, vous pouvez spécifier uniquement le nom de la fonction, comme dans l’exemple suivant :
WITH myproc AS PROCEDURE() ... HANDLER = 'run' AS $$ def run(session): ... $$ CALL myproc();
Lorsque le code est importé depuis une zone de préparation, spécifiez le nom de la fonction de gestionnaire entièrement qualifié sous la forme
<nom_module>.<nom_fonction>
.WITH myproc AS PROCEDURE() ... IMPORTS = ('@mystage/my_py_file.py') HANDLER = 'my_py_file.run' CALL myproc();
Java et Scala
Utilisez le nom complet de la méthode ou de la fonction pour la procédure. Ceci se présente généralement sous la forme suivante :
com.my_company.my_package.MyClass.myMethod
où :
com.my_company.my_package
correspond au paquet contenant l’objet ou la classe :
package com.my_company.my_package;
Paramètres facultatifs¶
Toutes les langues¶
CALLED ON NULL INPUT
ou .RETURNS NULL ON NULL INPUT | STRICT
Spécifie le comportement de la procédure lors d’un appel avec des entrées « null ». Contrairement aux fonctions définies par le système, qui retournent toujours la valeur « null » lorsqu’une entrée est nulle, les procédures peuvent gérer les entrées null, retournant des valeurs non nulles même lorsqu’une entrée est null :
CALLED ON NULL INPUT
appellera toujours la procédure avec des entrées null. Il appartient à la procédure de traiter ces valeurs de manière appropriée.RETURNS NULL ON NULL INPUT
(ou son synonymeSTRICT
) n’appelle pas la procédure si une entrée est null, ainsi les instructions contenues dans la procédure stockée ne seront pas exécutées. En revanche, une valeur null sera toujours retournée. Notez que la procédure peut toujours retourner une valeur null pour les entrées non null.
Par défaut :
CALLED ON NULL INPUT
INTO :snowflake_scripting_variable
Définit la variable Exécution de scripts Snowflake spécifiée dans la valeur de retour de la procédure stockée.
Java, Python ou Scala¶
IMPORTS = ( 'stage_path_and_file_name_to_read' [, 'stage_path_and_file_name_to_read' ...] )
L’emplacement (zone de préparation), le chemin et le nom du ou des fichiers à importer. Vous devez définir la clause
IMPORTS
pour inclure tous les fichiers dont dépend votre procédure :Si vous écrivez une procédure en ligne, vous pouvez omettre cette clause, sauf si votre code dépend de classes définies en dehors de la procédure ou de fichiers de ressources.
Java ou Scala : si vous écrivez une procédure dont le gestionnaire sera du code compilé, vous devez également inclure un chemin vers le fichier JAR contenant le gestionnaire de la procédure.
Python : si le code de votre procédure se trouve au niveau d’une zone de préparation, vous devez également inclure un chemin vers le fichier du module dans lequel se trouve votre code.
Chaque fichier de la clause
IMPORTS
doit avoir un nom unique, même si les fichiers se trouvent dans des sous-répertoires différents ou dans des zones de préparation différentes.
Notes sur l’utilisation¶
Utilisation générale¶
Les procédures ne sont pas atomiques ; si une instruction d’une procédure échoue, les autres instructions de la procédure ne sont pas nécessairement annulées. Pour des informations sur les procédures et les transactions, voir Gestion des transactions.
Une procédure ne peut renvoyer qu’une seule valeur, telle qu’une chaîne (par exemple, un indicateur de réussite/échec) ou un nombre (par exemple, un code d’erreur). Si vous devez renvoyer des informations plus détaillées, vous pouvez renvoyer un VARCHAR contenant des valeurs séparées par un délimiteur (tel qu’une virgule) ou un type de données semi-structuré, tel que VARIANT.
Concernant les métadonnées :
Attention
Les clients doivent s’assurer qu’aucune donnée personnelle (autre que pour un objet utilisateur), donnée sensible, donnée à exportation contrôlée ou autre donnée réglementée n’est saisie comme métadonnée lors de l’utilisation du service Snowflake. Pour plus d’informations, voir Champs de métadonnées dans Snowflake.
Syntaxe¶
Comme lorsqu’une clause WITH est utilisée avec une instruction SELECT, une clause WITH utilisée avec CALL permet de spécifier plusieurs CTEs séparés par des virgules, en plus de la définition de la procédure. Cependant, il n’est pas possible de transmettre des valeurs tabulaires produites par une clause WITH à la clause CALL.
Il est toutefois possible de spécifier une simple variable dont la valeur est assignée dans la clause WITH.
La clause CALL doit apparaître en dernier dans la syntaxe.
Privilèges¶
La création et l’appel d’une procédure avec cette commande ne nécessitent pas un rôle avec des privilèges de schéma CREATE PROCEDURE.
Le code du gestionnaire de la procédure ne pourra effectuer que les actions autorisées pour le rôle attribué à la personne qui a exécuté cette commande.
Langage spécifique¶
Pour les procédures Java, voir les limitations connues.
Pour les procédures Python, voir les limitations connues.
Pour les procédures Scala, voir les limitations connues.
Exemples¶
L’exemple suivant crée et appelle une procédure, en spécifiant les arguments par position :
WITH copy_to_table AS PROCEDURE (fromTable STRING, toTable STRING, count INT)
RETURNS STRING
LANGUAGE SCALA
RUNTIME_VERSION = '2.12'
PACKAGES = ('com.snowflake:snowpark:latest')
HANDLER = 'DataCopy.copyBetweenTables'
AS
$$
object DataCopy
{
def copyBetweenTables(session: com.snowflake.snowpark.Session, fromTable: String, toTable: String, count: Int): String =
{
session.table(fromTable).limit(count).write.saveAsTable(toTable)
return "Success"
}
}
$$
CALL copy_to_table('table_a', 'table_b', 5);
L’exemple suivant crée et appelle une procédure, en spécifiant les arguments par leur nom :
WITH copy_to_table AS PROCEDURE (fromTable STRING, toTable STRING, count INT)
RETURNS STRING
LANGUAGE SCALA
RUNTIME_VERSION = '2.12'
PACKAGES = ('com.snowflake:snowpark:latest')
HANDLER = 'DataCopy.copyBetweenTables'
AS
$$
object DataCopy
{
def copyBetweenTables(session: com.snowflake.snowpark.Session, fromTable: String, toTable: String, count: Int): String =
{
session.table(fromTable).limit(count).write.saveAsTable(toTable)
return "Success"
}
}
}
$$
CALL copy_to_table(
toTable => 'table_b',
count => 5,
fromTable => 'table_a');
Pour des exemples supplémentaires, reportez-vous aux rubriques suivantes :
Pour des exemples de procédures Java, voir Écriture de procédures stockées en Java.
Pour des exemples de procédures Python, voir Écriture de procédures stockées en Python.
Pour des exemples de procédures Scala, voir Écriture de procédures stockées en Scala.
Pour des exemples de procédures stockées Exécution de scripts Snowflake, voir Écriture de procédures stockées dans Exécution de scripts Snowflake.
Pour des exemples de procédures, voir Travailler avec des procédures stockées.