Utiliser des requêtes à plusieurs instructions
Ce document explique comment utiliser les requêtes multi-instructions dans BigQuery, en décrivant par exemple l'écriture de requêtes multi-instructions, l'utilisation de tables temporaires dans les requêtes multi-instructions, le référencement de variables dans les requêtes multi-instructions et le débogage de requêtes multi-instructions.
Une requête à plusieurs instructions est un ensemble d'instructions SQL que vous pouvez exécuter dans une seule requête. Avec les requêtes à plusieurs instructions, vous pouvez exécuter plusieurs instructions dans une séquence, avec un état partagé. Les requêtes à plusieurs instructions peuvent avoir des effets secondaires, comme l'ajout ou la modification de données de table.
Les requêtes multi-instructions sont souvent utilisées dans des procédures stockées et acceptent les instructions de langage procédural, qui vous permettent par exemple de définir des variables et de mettre en œuvre un flux de contrôle
Écrire, exécuter et enregistrer des requêtes à plusieurs instructions
Une requête à plusieurs instructions comprend une ou plusieurs instructions SQL séparées par un point-virgule. Toute instruction SQL valide peut être utilisée dans une requête à plusieurs instructions. Les requêtes à plusieurs instructions peuvent également inclure des instructions de langages procéduraux, qui vous permettent d'utiliser des variables ou de mettre en œuvre un flux de contrôle avec vos instructions SQL.
Écrire une requête à plusieurs instructions
Vous pouvez écrire une requête multi-instruction dans BigQuery. La requête multi-instruction suivante déclare une variable et utilise celle-ci dans une instruction IF
:
DECLARE day INT64;
SET day = (SELECT EXTRACT(DAYOFWEEK from CURRENT_DATE));
if day = 1 or day = 7 THEN
SELECT 'Weekend';
ELSE
SELECT 'Weekday';
END IF
BigQuery interprète toute requête comportant plusieurs instructions comme une requête à plusieurs instructions, sauf si elle est entièrement constituée d'instructions CREATE TEMP FUNCTION
suivies d'une seule instruction SELECT
.
Par exemple, la requête suivante n'est pas considérée comme une requête à plusieurs instructions :
CREATE TEMP FUNCTION Add(x INT64, y INT64) AS (x + y);
SELECT Add(3, 4);
Exécuter une requête multi-instruction
Vous pouvez exécuter une requête à plusieurs instructions de la même manière que toute autre requête, par exemple dans la console Google Cloud ou à l'aide de l'outil de ligne de commande bq.
Simuler une requête à plusieurs instructions
Pour estimer le nombre d'octets lus par une requête à plusieurs instructions, envisagez une simulation. La simulation d'une requête à plusieurs instructions est plus précise pour les requêtes qui ne contiennent que des instructions SELECT
.
Les simulations offrent une gestion particulière pour les types de requêtes et d'instructions suivants :
- Instructions
CALL
: la simulation vérifie que la procédure appelée existe et possède une signature correspondant aux arguments fournis. Le contenu de la procédure appelée et toutes les instructions après l'instructionCALL
ne sont pas validés. - Instructions LDD : la simulation valide la première instruction LDD, puis s'arrête. Toutes les instructions suivantes sont ignorées.
- Instructions LMD : la simulation valide l'instruction LMD, puis continue la validation des instructions suivantes. Dans ce cas, les estimations d'octets sont basées sur les tailles de table d'origine et ne tiennent pas compte du résultat de l'instruction LMD.
- Instructions
EXECUTE IMMEDIATE
: la simulation valide l'expression de requête, mais n'évalue pas la requête dynamique elle-même. Toutes les instructions qui suivent l'instructionEXECUTE IMMEDIATE
sont ignorées. - Requêtes utilisant des variables dans un filtre de partitionnement : la simulation valide la requête initiale et les instructions suivantes. Toutefois, la simulation ne peut pas calculer la valeur d'exécution des variables dans un filtre de partition. Cela affecte l'estimation des octets lus.
- Les requêtes qui utilisent des variables dans l'expression d'horodatage d'une clause
FOR SYSTEM TIME AS OF
: la simulation utilise le contenu actuel de la table et ignore la clauseFOR SYSTEM TIME AS OF
. Cela affecte l'estimation des octets lus en cas de différences de taille entre la table actuelle et l'itération précédente de la table. - Instructions de contrôle
FOR
,IF
etWHILE
: la simulation s'arrête immédiatement. Les expressions de condition, le corps de l'instruction de contrôle et toutes les instructions suivantes ne sont pas validés.
Les simulations fonctionnent de la façon la plus optimale possible et le processus sous-jacent est susceptible d'être modifié. Les simulations sont soumises aux exigences suivantes :
- Une requête qui effectue une simulation peut ne pas s'exécuter correctement. Par exemple, les requêtes peuvent échouer lors de l'exécution pour des raisons non détectées par les simulations.
- Une requête qui s'exécute correctement peut ne pas réussir la simulation. Par exemple, les requêtes peuvent échouer lors des simulations en raison de leur interception lors de l'exécution.
- Il n'est pas garanti que les simulations qui s'exécutent aujourd'hui s'exécutent toujours à l'avenir. Par exemple, les modifications apportées à la mise en œuvre de simulation peuvent détecter des erreurs dans une requête qui n'avaient pas encore été détectées.
Enregistrer une requête multi-instruction
Pour enregistrer une requête à plusieurs instructions, consultez la page Utiliser des requêtes enregistrées.
Utiliser des variables dans une requête multi-instruction
Une requête à plusieurs instructions peut contenir des variables créées par l'utilisateur et des variables système.
Vous pouvez déclarer des variables créées par l'utilisateur, leur attribuer des valeurs et les référencer tout au long de la requête.
Vous pouvez référencer des variables système dans une requête et attribuer des valeurs à certaines d'entre elles, mais contrairement aux variables définies par l'utilisateur, vous ne les déclarez pas. Les variables système sont intégrées à BigQuery.
Déclarer une variable créée par l'utilisateur
Vous devez déclarer les variables créées par l'utilisateur au début de la requête à plusieurs instructions ou au début d'un bloc BEGIN
. Les variables déclarées au début de la requête multi-instruction sont incluses dans le champ d'application pour l'ensemble de la requête. Les variables déclarées dans un bloc BEGIN
ont un champ d'application limité au bloc. Elles sont exclues du champ d'application après l'instruction END
correspondante. La taille maximale d'une variable est de 1 Mo, et la taille maximale de toutes les variables utilisées dans une requête à plusieurs instructions est de 10 Mo.
Vous pouvez déclarer une variable à l'aide de l'instruction procédurale DECLARE
, comme suit :
DECLARE x INT64;
BEGIN
DECLARE y INT64;
-- Here you can reference x and y
END;
-- Here you can reference x, but not y
Définir une variable créée par l'utilisateur
Après avoir déclaré une variable créée par l'utilisateur, vous pouvez lui attribuer une valeur à l'aide de l'instruction procédurale SET
, comme suit :
DECLARE x INT64 DEFAULT 0;
SET x = 10;
Définir une variable système
Vous ne créez pas de variables système, mais vous pouvez remplacer la valeur par défaut pour certaines d'entre elles, comme suit :
SET @@dataset_project_id = 'MyProject';
Vous pouvez également définir et utiliser implicitement une variable système dans une requête à plusieurs instructions. Par exemple, dans la requête suivante, vous devez inclure le projet chaque fois que vous souhaitez créer une table :
BEGIN
CREATE TABLE MyProject.MyDataset.MyTempTableA (id STRING);
CREATE TABLE MyProject.MyDataset.MyTempTableB (id STRING);
END;
Si vous ne souhaitez pas ajouter le projet aux chemins d'accès aux tables plusieurs fois, vous pouvez attribuer l'ID de projet MyProject
à la variable système @@dataset_project_id
dans la requête à plusieurs instructions. Cette attribution fait de MyProject
le projet par défaut pour le reste de la requête.
SET @@dataset_project_id = 'MyProject';
BEGIN
CREATE TABLE MyDataset.MyTempTableA (id STRING);
CREATE TABLE MyDataset.MyTempTableB (id STRING);
END;
De même, vous pouvez définir la variable système @@dataset_id
pour attribuer un ensemble de données par défaut à la requête. Par exemple :
SET @@dataset_project_id = 'MyProject';
SET @@dataset_id = 'MyDataset';
BEGIN
CREATE TABLE MyTempTableA (id STRING);
CREATE TABLE MyTempTableB (id STRING);
END;
Vous pouvez également référencer explicitement des variables système telles que @@dataset_id
dans de nombreuses parties d'une requête à plusieurs instructions. Pour en savoir plus, consultez la section Référencer une variable système.
Référencer une variable créée par l'utilisateur
Une fois que vous avez déclaré et défini une variable créée par l'utilisateur, vous pouvez la référencer dans une requête à plusieurs instructions. Si une variable et une colonne portent le même nom, la colonne est prioritaire.
Cette opération renvoie column x
+ column x
:
DECLARE x INT64 DEFAULT 0;
SET x = 10;
WITH Numbers AS (SELECT 50 AS x)
SELECT (x+x) AS result FROM Numbers;
+--------+
| result |
+--------+
| 100 |
+--------+
Cette opération renvoie column y
+ variable x
:
DECLARE x INT64 DEFAULT 0;
SET x = 10;
WITH Numbers AS (SELECT 50 AS y)
SELECT (y+x) AS result FROM Numbers;
+--------+
| result |
+--------+
| 60 |
+--------+
Référencer une variable système
Vous pouvez référencer une variable système dans une requête à plusieurs instructions.
La requête suivante renvoie le fuseau horaire par défaut :
BEGIN
SELECT @@time_zone AS default_time_zone;
END;
+-------------------+
| default_time_zone |
+-------------------+
| UTC |
+-------------------+
Vous pouvez utiliser des variables système avec des requêtes LDD et LMD.
Par exemple, voici quelques façons d'utiliser la variable système @@time_zone
lors de la création et de la mise à jour d'une table :
BEGIN
CREATE TEMP TABLE MyTempTable
AS SELECT @@time_zone AS default_time_zone;
END;
BEGIN
CREATE OR REPLACE TABLE MyDataset.MyTable(default_time_zone STRING)
OPTIONS (description = @@time_zone);
END;
BEGIN
UPDATE MyDataset.MyTable
SET default_time_zone = @@time_zone
WHERE TRUE;
END;
Il existe certains cas où les variables système ne peuvent pas être utilisées dans les requêtes LDD et LMD. Par exemple, vous ne pouvez pas utiliser une variable système en tant que nom de projet, ensemble de données ou nom de table. Cela génère une erreur lorsque vous essayez d'inclure la variable système @@dataset_id
dans un chemin de table :
BEGIN
CREATE TEMP TABLE @@dataset_id.MyTempTable (id STRING);
END;
Utiliser des tables temporaires dans une requête multi-instruction
Les tables temporaires vous permettent d'enregistrer les résultats intermédiaires dans une table. Les tables temporaires sont gérées par BigQuery. Vous n'avez donc pas besoin de les enregistrer ni de les conserver dans un ensemble de données. Le stockage de tables temporaires vous est facturé.
Vous pouvez créer et référencer une table temporaire dans une requête multi-instruction. Lorsque vous n'avez plus besoin de la table temporaire, vous pouvez la supprimer manuellement pour réduire les coûts de stockage ou attendre que BigQuery la supprime au bout de 24 heures.
Créer une table temporaire
Vous pouvez créer une table temporaire pour une requête multi-instruction à l'aide de l'instruction CREATE TABLE
.
L'exemple suivant crée une table temporaire pour stocker les résultats d'une requête et utilise la table temporaire dans une sous-requête :
-- Find the top 100 names from the year 2017.
CREATE TEMP TABLE top_names(name STRING)
AS
SELECT name
FROM `bigquery-public-data`.usa_names.usa_1910_current
WHERE year = 2017
ORDER BY number DESC LIMIT 100
;
-- Which names appear as words in Shakespeare's plays?
SELECT
name AS shakespeare_name
FROM top_names
WHERE name IN (
SELECT word
FROM `bigquery-public-data`.samples.shakespeare
);
À l'exception de l'utilisation de TEMP
ou de TEMPORARY
, la syntaxe est identique à la syntaxe CREATE TABLE
.
Lorsque vous créez une table temporaire, n'utilisez pas de qualificatif de projet ou d'ensemble de données dans le nom de la table. La table est automatiquement créée dans un ensemble de données spécial.
Référencer une table temporaire
Vous pouvez référencer une table temporaire par son nom pour la durée de la requête à plusieurs instructions en cours. Cela inclut les tables temporaires créées par une procédure au sein de la requête à plusieurs instructions. Vous ne pouvez pas partager des tables temporaires. Les tables temporaires se trouvent dans des ensembles de données _script%
masqués, portant des noms générés de manière aléatoire.
L'article Répertorier des ensembles de données explique comment répertorier des ensembles de données masqués.
Supprimer des tables temporaires
Vous pouvez supprimer explicitement une table temporaire avant la fin de la requête multi-instruction à l'aide de l'instruction DROP TABLE
:
CREATE TEMP TABLE table1(x INT64); SELECT * FROM table1; -- Succeeds DROP TABLE table1; SELECT * FROM table1; -- Results in an error
Une fois la requête à plusieurs instructions terminée, la table temporaire peut exister jusqu'à 24 heures.
Afficher les données d'une table temporaire
Après avoir créé une table temporaire, vous pouvez afficher sa structure et les données qu'elle contient. Procédez comme suit pour afficher la structure et les données d'une table :
Dans la console Google Cloud, accédez à la page Explorateur de BigQuery.
Cliquez sur Historique des requêtes.
Choisissez la requête qui a créé la table temporaire.
Dans la ligne Table de destination, cliquez sur Table temporaire.
Qualifier les tables temporaires avec _SESSION
Lorsque des tables temporaires sont utilisées avec un ensemble de données par défaut, les noms de table non qualifiés font référence à une table temporaire s'il en existe une, ou à une table de l'ensemble de données par défaut. L'exception concerne les instructions CREATE TABLE
, où la table cible est considérée comme une table temporaire si et seulement si le mot clé TEMP
ou TEMPORARY
est présent.
Prenons par exemple la requête à plusieurs instructions suivante :
-- Create table t1 in the default dataset CREATE TABLE t1 (x INT64); -- Create temporary table t1. CREATE TEMP TABLE t1 (x INT64); -- This statement selects from the temporary table. SELECT * FROM t1; -- Drop the temporary table DROP TABLE t1; -- Now that the temporary table is dropped, this statement selects from the -- table in the default dataset. SELECT * FROM t1;
Vous pouvez indiquer explicitement que vous faites référence à une table temporaire en qualifiant le nom de la table avec _SESSION
:
-- Create a temp table CREATE TEMP TABLE t1 (x INT64); -- Create a temp table using the `_SESSION` qualifier CREATE TEMP TABLE _SESSION.t2 (x INT64); -- Select from a temporary table using the `_SESSION` qualifier SELECT * FROM _SESSION.t1;
Si vous utilisez le qualificateur _SESSION
pour une requête sur une table temporaire qui n'existe pas, la requête à plusieurs instructions génère une erreur indiquant que la table n'existe pas. Par exemple, s'il n'existe aucune table temporaire appelée t3
, la requête à plusieurs instructions génère une erreur même si une table nommée t3
existe dans l'ensemble de données par défaut.
Vous ne pouvez pas utiliser _SESSION
pour créer une table non-temporaire :
CREATE TABLE _SESSION.t4 (x INT64); -- Fails
Collecter des informations sur une tâche de requête multi-instruction
Une tâche de requête multi-instruction contient des informations sur la requête multi-instruction qui a été exécutée. Certaines opérations courantes que vous pouvez effectuer avec les données de tâches incluent l'affichage de la dernière instruction exécutée dans la requête multi-instruction, ou l'affichage de toutes les instructions exécutées dans la requête multi-instruction.
Afficher la dernière instruction exécutée
La méthode jobs.getQueryResults
affiche les résultats de la dernière instruction exécutée par la requête multi-instructions. Si aucune instruction n'a été exécutée, aucun résultat n'est renvoyé.
Afficher toutes les instructions exécutées
Pour obtenir les résultats de toutes les instructions de la requête multi-instruction, énumérez les tâches enfants et appelez sur chacune d'elles la méthode jobs.getQueryResults
.
Énumérer les tâches enfants
Les requêtes à plusieurs instructions sont exécutées dans BigQuery à l'aide de jobs.insert
, comme n'importe quelle autre requête, en spécifiant les requêtes à plusieurs instructions comme texte de requête. Lorsqu'une requête à plusieurs instructions s'exécute, des tâches supplémentaires, appelées tâches enfants, sont créées pour chaque instruction de la requête à plusieurs instructions. Vous pouvez répertorier les tâches enfants d'une requête à plusieurs instructions en appelant jobs.list
et en transmettant l'ID de tâche de la requête à plusieurs instructions en tant que paramètre parentJobId
.
Déboguer une requête à plusieurs instructions
Voici quelques conseils pour déboguer les requêtes à plusieurs instructions :
Utilisez l'instruction
ASSERT
pour confirmer qu'une condition booléenne est "True".Utilisez
BEGIN...EXCEPTION...END
pour détecter les erreurs et pour afficher le message d'erreur et la trace de la pile.Utilisez
SELECT FORMAT("....")
pour afficher les résultats intermédiaires.Lorsque vous exécutez une requête à plusieurs instructions dans la console Google Cloud, vous pouvez afficher la sortie de chaque instruction dans la requête à plusieurs instructions. La commande "bq query" de l'outil de ligne de commande affiche également les résultats de chaque étape lorsque vous exécutez une requête à plusieurs instructions.
Dans la console Google Cloud, vous pouvez sélectionner une instruction individuelle dans l'éditeur de requête et l'exécuter.
Autorisations
L'autorisation d'accès à une table, un modèle ou une autre ressource est vérifiée au moment de l'exécution. Si une instruction n'est pas exécutée ou qu'une expression n'est pas évaluée, BigQuery ne vérifie pas si l'utilisateur exécutant la requête à plusieurs instructions a accès aux ressources référencées.
Dans une requête à plusieurs instructions, les autorisations de chaque expression ou instruction sont validées séparément. Par exemple :
SELECT * FROM dataset_with_access.table1; SELECT * FROM dataset_without_access.table2;
Si l'utilisateur exécutant le script a accès à table1
, mais pas à table2
, la première requête aboutit et la deuxième échoue. La tâche de requête à plusieurs instructions échoue également.
Contraintes de sécurité
Dans les requêtes à plusieurs instructions, vous pouvez utiliser le SQL dynamique pour créer des instructions SQL au moment de l'exécution. Cela est pratique, mais peut offrir de nouvelles opportunités d'utilisation abusive. Par exemple, l'exécution de la requête suivante représente une menace potentielle pour la sécurité (injection SQL), car le paramètre de table peut être mal filtré, autoriser l'accès à et être exécuté sur des tables non souhaitées.
-- Risky query vulnerable to SQL injection attack.
EXECUTE IMMEDIATE CONCAT('SELECT * FROM SensitiveTable WHERE id = ', @id);
Pour éviter d'exposer ou de divulguer des données sensibles dans une table ou d'exécuter des commandes telles que DROP TABLE
pour supprimer des données dans une table, les instructions procédurales dynamiques de BigQuery acceptent plusieurs mesures de sécurité pour réduire l'exposition aux attaques d'injection SQL, y compris :
- Une instruction
EXECUTE IMMEDIATE
ne permet pas d'intégrer plusieurs instructions SQL à sa requête, développée avec des paramètres et des variables de requête. - Les commandes suivantes ne peuvent pas être exécutées dynamiquement :
BEGIN
/END
,CALL
,CASE
,IF
,LOOP
,WHILE
etEXECUTE IMMEDIATE
.
Limites du champ de configuration
Les champs de requête de configuration de tâche suivant ne peuvent pas être définis pour une requête à plusieurs instructions :
clustering
create_disposition
destination_table
destination_encryption_configuration
range_partitioning
schema_update_options
time_partitioning
user_defined_function_resources
write_disposition
Tarifs
La tarification des requêtes multi-instructions inclut les frais liés aux requêtes (lorsque vous utilisez le modèle de facturation à la demande) et le stockage pour les tables temporaires. Lorsque vous utilisez des réservations, l'utilisation des requêtes est couverte par vos frais de réservation.
Calcul de la taille des requêtes à la demande
Si vous utilisez la facturation à la demande, BigQuery facture les requêtes à plusieurs instructions en fonction du nombre d'octets traités lors de l'exécution des requêtes à plusieurs instructions.
Pour obtenir une estimation du nombre d'octets qu'une requête à plusieurs instructions peut traiter, vous pouvez exécuter une simulation.
La tarification suivante s'applique à ces requêtes à plusieurs instructions :
DECLARE
: nombre total d'octets scannés pour toutes les tables référencées dans l'expressionDEFAULT
. Les instructionsDECLARE
sans références de table n'entraînent aucuns frais.SET
: nombre total d'octets scannés pour toutes les tables référencées dans l'expression. Les instructionsSET
sans références de table n'entraînent aucuns frais.IF
: nombre total d'octets scannés pour toutes les tables référencées dans l'expression de condition. Les expressions de conditionIF
sans références de table n'entraînent aucuns frais. Une instruction non exécutée dans le blocIF
n'entraîne aucuns frais.WHILE
: nombre total d'octets scannés pour toutes les tables référencées dans l'expression de condition. Les instructionsWHILE
sans références de table dans l'expression de condition n'entraînent aucuns frais. Une instruction non exécutée dans le blocWHILE
n'entraîne aucuns frais.CONTINUE
ouITERATE
: aucuns frais associés.BREAK
ouLEAVE
: aucuns frais associés.BEGIN
ouEND
: aucuns frais associés.
Si une requête à plusieurs instructions échoue, le coût des instructions effectuées jusqu'au moment de l'échec vous est facturé. Les instructions qui échouent n'entraînent aucuns frais.
Par exemple, l'exemple de code suivant contient des commentaires précédant chaque instruction expliquant le coût, le cas échéant, facturé par chaque instruction :
-- No cost, since no tables are referenced. DECLARE x DATE DEFAULT CURRENT_DATE(); -- Incurs the cost of scanning string_col from dataset.table. DECLARE y STRING DEFAULT (SELECT MAX(string_col) FROM dataset.table); -- Incurs the cost of copying the data from dataset.big_table. Once the -- table is created, you are not charged for storage while the rest of the -- multi-statement query runs. CREATE TEMP TABLE t AS SELECT * FROM dataset.big_table; -- Incurs the cost of scanning column1 from temporary table t. SELECT column1 FROM t; -- No cost, since y = 'foo' doesn't reference a table. IF y = 'foo' THEN -- Incurs the cost of scanning all columns from dataset.other_table, if -- y was equal to 'foo', or otherwise no cost since it is not executed. SELECT * FROM dataset.other_table; ELSE -- Incurs the cost of scanning all columns from dataset.different_table, if -- y was not equal to 'foo', or otherwise no cost since it is not executed. UPDATE dataset.different_table SET col = 10 WHERE true; END IF; -- Incurs the cost of scanning date_col from dataset.table for each -- iteration of the loop. WHILE x < (SELECT MIN(date_col) FROM dataset.table) DO -- No cost, since the expression does not reference any tables. SET x = DATE_ADD(x, INTERVAL 1 DAY); -- No cost, since the expression does not reference any tables. IF true THEN -- LEAVE has no associated cost. LEAVE; END IF; -- Never executed, since the IF branch is always taken, so does not incur -- a cost. SELECT * FROM dataset.big_table; END WHILE;
Pour en savoir plus, consultez la section Calcul de la taille des requêtes.
Tarifs de stockage
Les tables temporaires créées par des requêtes multi-instructions vous sont facturées. Vous pouvez utiliser les vues TABLE_STORAGE
ou TABLE_STORAGE_USAGE_TIMELINE
pour afficher l'espace de stockage utilisé par ces tables temporaires. Les tables temporaires se trouvent dans des ensembles de données _script%
masqués, portant des noms générés de manière aléatoire.
Quotas
Pour en savoir plus sur les quotas des requêtes à plusieurs instructions, consultez la page Quotas et limites.
Afficher le nombre de requêtes à plusieurs instructions
Vous pouvez afficher le nombre de requêtes à plusieurs instructions actives à l'aide de la vue INFORMATION_SCHEMA.JOBS_BY_PROJECT
.
L'exemple suivant utilise la vue INFORMATION_SCHEMA.JOBS_BY_PROJECT
pour afficher le nombre de requêtes à plusieurs instructions du jour précédent :
SELECT
COUNT(*)
FROM
`region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
WHERE
creation_time BETWEEN TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 DAY) AND CURRENT_TIMESTAMP()
AND job_type = "QUERY"
AND state = 'RUNNING'
AND statement_type = 'SCRIPT'
Pour en savoir plus sur l'interrogation de INFORMATION_SCHEMA.JOBS
pour les requêtes à plusieurs instructions, consultez la page Job de requête à plusieurs instruction.