Secuencias de comandos de BigQuery
Las secuencias de comandos de BigQuery te permiten enviar varias declaraciones a BigQuery en una sola solicitud, usar variables y usar declaraciones de flujo de control como IF
y WHILE
. Por ejemplo, puedes declarar una variable, asignarle un valor y, luego, hacer referencia a ella en una tercera declaración.
En BigQuery, una secuencia de comandos es una lista de instrucciones de SQL que se ejecuta en secuencia. Una lista de instrucciones de SQL es una lista de todas las instrucciones válidas de BigQuery que están separadas por punto y coma.
Por ejemplo:
-- Declare a variable to hold names as an array. DECLARE top_names ARRAY<STRING>; -- Build an array of the top 100 names from the year 2017. SET top_names = ( SELECT ARRAY_AGG(name ORDER BY number DESC LIMIT 100) FROM `bigquery-public-data`.usa_names.usa_1910_current WHERE year = 2017 ); -- Which names appear as words in Shakespeare's plays? SELECT name AS shakespeare_name FROM UNNEST(top_names) AS name WHERE name IN ( SELECT word FROM `bigquery-public-data`.samples.shakespeare );
Las secuencias de comandos se ejecutan en BigQuery mediante jobs.insert
, de modo similar a cualquier otra búsqueda, con la secuencia de comandos de varias declaraciones especificada como el texto de la búsqueda. Cuando se ejecuta una secuencia de comandos, se crean trabajos adicionales, conocidos como trabajos secundarios, para cada declaración de la secuencia de comandos. Para enumerar los trabajos secundarios de una secuencia de comandos, llama a jobs.list
y pasa el ID de tarea de la secuencia de comandos como el parámetro parentJobId
.
Cuando se invoca a jobs.getQueryResults
en una secuencia de comandos, mostrará los resultados de consulta de la última declaración DDL, DML o SELECT para ejecutarla en la secuencia de comandos; si no se ejecutó ninguna de las declaraciones anteriores, no habrá resultados de consulta. Para obtener los resultados de todas las declaraciones en la secuencia de comandos, enumera los trabajos secundarios y llama a jobs.getQueryResults
en cada uno de ellos.
BigQuery interpreta cualquier solicitud con varias declaraciones como una secuencia de comandos, a menos que las declaraciones consistan en declaraciones CREATE TEMP FUNCTION
, con una única declaración de consulta final. Por ejemplo, lo siguiente no se consideraría una secuencia de comandos:
CREATE TEMP FUNCTION Add(x INT64, y INT64) AS (x + y); SELECT Add(3, 4);
DECLARE
DECLARE variable_name[, ...] [variable_type] [DEFAULT expression];
variable_name
debe ser un identificador válido, y variable_type
es cualquier tipo de BigQuery.
Descripción
Declara una variable del tipo especificado. Si se especifica la cláusula DEFAULT
, la variable se inicializa con el valor de la expresión; si no hay una cláusula DEFAULT
, la variable se inicializa con el valor NULL
.
Si se omite [variable_type]
, se debe especificar una cláusula DEFAULT
. El tipo de la variable se inferirá según el tipo de la expresión en la cláusula DEFAULT
.
Las declaraciones de variables deben aparecer al comienzo de una secuencia de comandos, antes de cualquier otra declaración, o al comienzo de un bloque declarado con BEGIN
. Los nombres de las variables no distinguen entre mayúsculas y minúsculas.
Pueden aparecer varios nombres de variables en una sola declaración DECLARE
, pero solo una variable_type
y expression
.
Es un error declarar una variable con el mismo nombre que una variable declarada anteriormente en el bloque actual o en un bloque contenedor.
Si la cláusula DEFAULT
está presente, el valor de la expresión debe ser coercible para el tipo especificado. La expresión puede hacer referencia a otras variables declaradas previamente dentro del mismo bloque o un bloque contenedor.
El tamaño máximo de una variable es de 1 MB, y el tamaño máximo de todas las variables utilizadas en una secuencia de comandos es de 10 MB.
Ejemplos
En el siguiente ejemplo, se inicializa la variable x
como un INT64 con el valor NULL
.
DECLARE x INT64;
En el siguiente ejemplo, se inicializa la variable d
como DATE con el valor de la fecha actual.
DECLARE d DATE DEFAULT CURRENT_DATE();
En el siguiente ejemplo, se inicializan las variables x
, y
y z
como INT64
con el valor 0.
DECLARE x, y, z INT64 DEFAULT 0;
En el siguiente ejemplo, se declara una variable llamada item
que corresponde a un elemento arbitrario en la tabla dataset1.products
. Se infiere el tipo de item
del esquema de la tabla.
DECLARE item DEFAULT (SELECT item FROM dataset1.products LIMIT 1);
SET
Sintaxis
SET name = expression;
SET (variable_name_1, variable_name_2, …, variable_name_n) = (expression_1, expression_2, …, expression_n);
Descripción
Establece una variable para tener el valor de la expresión proporcionada, o establece muchas variables al mismo tiempo en función del resultado de varias expresiones.
La declaración SET
puede aparecer en cualquier parte del cuerpo de una secuencia de comandos.
Ejemplos
En el siguiente ejemplo, se establece que la variable x
tenga el valor 5.
SET x = 5;
En el siguiente ejemplo, se establece que la variable a
tenga el valor 4, que la variable b
tenga el valor ‘foo’ y que la variable c
tenga el valor false
.
SET (a, b, c) = (1 + 3, 'foo', false);
En el siguiente ejemplo, se asigna el resultado de una consulta a muchas variables.
Primero, declara dos variables, target_word
y corpus_count
; a continuación, asigna los resultados de una consulta SELECT AS STRUCT
a las dos variables. El resultado de la consulta es una sola fila que contiene un STRUCT
con dos campos; el primer elemento se asigna a la primera variable y el segundo elemento se asigna a la segunda variable.
DECLARE target_word STRING DEFAULT 'methinks'; DECLARE corpus_count, word_count INT64; SET (corpus_count, word_count) = ( SELECT AS STRUCT COUNT(DISTINCT corpus), SUM(word_count) FROM `bigquery-public-data`.samples.shakespeare WHERE LOWER(word) = target_word ); SELECT FORMAT('Found %d occurrences of "%s" across %d Shakespeare works', word_count, target_word, corpus_count) AS result;
Con esta lista de declaraciones se genera la siguiente string:
Found 151 occurrences of "methinks" across 38 Shakespeare works
EXECUTE IMMEDIATE
Sintaxis
EXECUTE IMMEDIATE sql_expression [ INTO variable[, ...] ] [ USING identifier[, ...] ];
sql_expression:
{ "query_statement" | expression("query_statement") }
identifier:
{ variable | value } [ AS alias ]
Descripción
Ejecuta una declaración de SQL dinámica sobre la marcha.
sql_expression
: Representa una declaración de consulta, una expresión que puedes usar en una declaración de consulta, una única declaración DDL o una única declaración DML.expression
: Puede ser una función, una expresión condicional o una subconsulta de expresión.query_statement
: Representa una declaración de SQL independiente válida para ejecutar. Si esto muestra un valor, la cláusulaINTO
debe contener valores del mismo tipo. Puedes acceder a las variables del sistema y los valores presentes en la cláusulaUSING
. Todas las demás variables locales y parámetros de consulta no están expuestos a la declaración de consulta.- Cláusula
INTO
: Después de ejecutar la expresión de SQL, puedes almacenar los resultados en una o más variables mediante la cláusulaINTO
. - Cláusula
USING
: Antes de ejecutar la expresión de SQL, puedes pasar uno o más identificadores de la cláusulaUSING
a la expresión de SQL. Estos identificadores funcionan de manera similar a los parámetros de consulta y exponen valores a la declaración de consulta. Un identificador puede ser una variable o un valor.
Puedes incluir estos marcadores de posición en query_statement
para los identificadores a los que se hace referencia en la cláusula USING
:
?
: El valor de este marcador de posición se vincula por índice a un identificador en la cláusulaUSING
.-- y = 1 * (3 + 2) = 5 EXECUTE IMMEDIATE "SELECT ? * (? + 2)" INTO y USING 1, 3;
@identifier
: El valor de este marcador de posición se vincula por nombre a un identificador en la cláusulaUSING
. Esta sintaxis es idéntica a la del parámetro de consulta.-- y = 1 * (3 + 2) = 5 EXECUTE IMMEDIATE "SELECT @a * (@b + 2)" INTO y USING 1 as a, 3 as b;
Estas son algunas notas adicionales sobre el comportamiento de la declaración EXECUTE IMMEDIATE
:
EXECUTE IMMEDIATE
no puede ejecutarse de forma dinámica como un elemento anidado.- Si una declaración
EXECUTE IMMEDIATE
muestra resultados, esos resultados se convierten en el resultado de toda la declaración y se actualizan las variables de sistema adecuadas. - La misma variable puede aparecer en las cláusulas
INTO
yUSING
. query_statement
puede contener una sola declaración analizada que contenga otras declaraciones (por ejemplo, BEGIN…END).- Si
query_statement
no muestra ninguna fila, incluso las tablas de valores sin filas, todas las variables en la cláusulaINTO
se establecen como NULL. - Si
query_statement
muestra una fila, incluso las tablas de valores sin filas, los valores se asignan por posición, no por nombre de variable. - Si hay una cláusula
INTO
, se genera un error si intentas mostrar más de una fila dequery_statement
.
Ejemplos
En este ejemplo, creamos una tabla de libros y la propagamos con datos. Ten en cuenta las diferentes formas en las que puedes hacer referencia a las variables, guardar valores en variables y usar expresiones.
-- create some variables
DECLARE book_name STRING DEFAULT 'Ulysses';
DECLARE book_year INT64 DEFAULT 1922;
DECLARE first_date INT64;
-- Create a temporary table called Books.
EXECUTE IMMEDIATE
"CREATE TEMP TABLE Books (title STRING, publish_date INT64)";
-- Add a row for Hamlet (less secure)
EXECUTE IMMEDIATE
"INSERT INTO Books (title, publish_date) VALUES('Hamlet', 1599)";
-- add a row for Ulysses, using the variables declared at the top of this
-- script and the ? placeholder
EXECUTE IMMEDIATE
"INSERT INTO Books (title, publish_date) VALUES(?, ?)"
USING book_name, book_year;
-- add a row for Emma, using the identifier placeholder
EXECUTE IMMEDIATE
"INSERT INTO Books (title, publish_date) VALUES(@name, @year)"
USING 1815 as year, "Emma" as name;
-- add a row for Middlemarch, using an expression
EXECUTE IMMEDIATE
CONCAT("INSERT INTO Books (title, publish_date)", "VALUES('Middlemarch', 1871)");
-- save the publish date of the first book, Hamlet, to a variable called first_date
EXECUTE IMMEDIATE "SELECT publish_date FROM Books LIMIT 1" INTO first_date;
+------------------+------------------+
| title | publish_date |
+------------------+------------------+
| Hamlet | 1599 |
| Ulysses | 1922 |
| Emma | 1815 |
| Middlemarch | 1871 |
+------------------+------------------+
BEGIN
Sintaxis
BEGIN sql_statement_list END;
Descripción
BEGIN
inicia un bloque de declaraciones donde las variables declaradas existen solo hasta el END
correspondiente. sql_statement_list
es una lista de cero o más instrucciones de SQL que terminan en punto y coma.
Las declaraciones de variables deben aparecer al comienzo del bloque, antes de otros tipos de declaraciones. Las variables declaradas dentro de un bloque solo pueden referenciarse dentro de ese bloque y en cualquier bloque anidado. Es un error declarar una variable con el mismo nombre que una variable declarada en el mismo bloque o en un bloque externo.
Hay un nivel máximo de anidación de 50 para bloques y declaraciones condicionales como BEGIN
/END
, IF
/ELSE
/END IF
y WHILE
/END WHILE
.
BEGIN
/END
no se puede ejecutar de forma dinámica como un elemento anidado.
Ejemplos
En el siguiente ejemplo, se declara una variable x
con el valor predeterminado 10. Luego, se inicia un bloque, en el que a una variable y
se le asigna el valor de x
, que es 10, y muestra este valor. Luego, la declaración END
finaliza el bloque, y finaliza el alcance de la variable y
. Por último, muestra el valor de x
.
DECLARE x INT64 DEFAULT 10; BEGIN DECLARE y INT64; SET y = x; SELECT y; END; SELECT x;
BEGIN…EXCEPTION
Sintaxis
BEGIN sql_statement_list EXCEPTION WHEN ERROR THEN sql_statement_list END;
Descripción
BEGIN...EXCEPTION
ejecuta un bloque de declaraciones. Si alguna de las declaraciones experimenta un error, la secuencia de comandos omite el resto del bloque y ejecuta las declaraciones en la cláusula EXCEPTION
.
En la cláusula EXCEPTION
, puedes acceder a los detalles del error mediante las siguientes variables de sistema EXCEPTION
:
Nombre | Tipo | Descripción |
---|---|---|
@@error.formatted_stack_trace |
STRING |
El contenido de @@error.stack_trace se expresa como una string legible para el ser humano. Este valor está destinado a fines de visualización y está sujeto a cambios sin previo aviso. En su lugar, el acceso programático al seguimiento de pila de un error debería usar @@error.stack_trace . |
@@error.message |
STRING |
Especifica un mensaje de error legible para el ser humano. |
@@error.stack_trace |
Consulta 1. | Cada elemento del arreglo corresponde a una declaración o llamada a procedimiento que se ejecuta en el momento del error, y el primer marco de pila que está en ejecución aparece primero. El significado de cada campo se define de la siguiente manera:
|
@@error.statement_text |
STRING |
Especifica el texto de la declaración que causó el error. |
1 El tipo para @@error.stack_trace
es ARRAY<STRUCT<line INT64, column INT64, filename STRING, location STRING>>
.
Como BigQuery se reserva el derecho de revisar los mensajes de error en cualquier momento, los consumidores de @@error.message
no deben confiar en que los mensajes de error permanezcan iguales o sigan un patrón en particular. No obtengas información sobre la ubicación del error mediante la extracción de texto del mensaje de error; en su lugar, usa @@error.stack_trace
y @@error.statement_text
.
Para controlar las excepciones que arroja (sin control) un controlador de excepciones, debes unir el bloque a otro externo con un controlador independiente.
A continuación, se muestra cómo usar un bloque externo con un controlador de excepciones independiente:
BEGIN BEGIN ... EXCEPTION WHEN ERROR THEN SELECT 1/0; END; EXCEPTION WHEN ERROR THEN -- The exception thrown from the inner exception handler lands here. END;
Los bloques BEGIN...EXCEPTION
también admiten instrucciones DECLARE
, como cualquier otro bloque BEGIN
. Las variables declaradas en un bloque BEGIN
son válidas solo en la sección BEGIN
y no se pueden usar en el controlador de excepciones del bloque.
Ejemplos
CREATE OR REPLACE PROCEDURE dataset1.proc1() BEGIN SELECT 1/0; END; CREATE OR REPLACE PROCEDURE dataset1.proc2() BEGIN CALL dataset1.proc1(); END; BEGIN CALL dataset1.proc2(); EXCEPTION WHEN ERROR THEN SELECT @@error.message, @@error.stack_trace, @@error.statement_text, @@error.formatted_stack_trace; END;
En este ejemplo, cuando ocurra el error de división por cero, en lugar de finalizar la secuencia de comandos completa, BigQuery finalizará dataset1.proc1()
y dataset1.proc2()
, y ejecutará la declaración SELECT en el controlador de excepciones. Cuando se ejecute el controlador de excepciones, las variables tendrán los siguientes valores:
Variable | Valor |
---|---|
@@error.message |
"Query error: division by zero: 1 / 0 at <project>.dataset1.proc1:2:3]" |
@@error.stack_trace |
[ STRUCT(2 AS line, 3 AS column, NULL AS filename, "<project>.dataset1.proc1:2:3" AS location), STRUCT(2 AS line, 3 AS column, NULL AS filename, "<project>.dataset1.proc2:2:3" AS location), STRUCT(10 AS line, 3 AS column, NULL AS filename, NULL AS location), ] |
@@error.statement_text |
"SELECT 1/0" |
@@error.formatted_stack_trace |
"At <project>.dataset1.proc1[2:3]\nAt <project>.dataset1.proc2[2:3]\nAt [10:3]" |
END
Finaliza un bloqueo que inicia BEGIN
. BEGIN
/END
no se puede ejecutar de forma dinámica como un elemento anidado.
IF
Sintaxis
IF condition THEN [sql_statement_list] [ELSEIF condition THEN sql_statement_list] [ELSEIF condition THEN sql_statement_list]... [ELSE sql_statement_list] END IF;
Descripción
Ejecuta la primera sql_statement_list
en la que la condición es verdadera o la ELSE
sql_statement_list
opcional si las condiciones no coinciden.
Hay un nivel máximo de anidación de 50 para bloques y declaraciones condicionales como BEGIN
/END
, IF
/ELSE
/END IF
y WHILE
/END WHILE
.
IF
no puede ejecutarse de forma dinámica como un elemento anidado.
Ejemplos
En el siguiente ejemplo, se declara una variable INT64 target_product_id
con un valor predeterminado de 103. Luego, se verifica si la tabla dataset.products
contiene una fila con la columna product_id
que coincide con el valor de target_product_id
. Si es así, se da como resultado una string que indica que se ha encontrado el producto, junto con el valor de default_product_id
. En caso contrario, se da como resultado una string que indica que no se ha encontrado el producto, también con el valor de default_product_id
.
DECLARE target_product_id INT64 DEFAULT 103;
IF EXISTS (SELECT 1 FROM dataset.products
WHERE product_id = target_product_id) THEN
SELECT CONCAT('found product ', CAST(target_product_id AS STRING));
ELSEIF EXISTS (SELECT 1 FROM dataset.more_products
WHERE product_id = target_product_id) THEN
SELECT CONCAT('found product from more_products table',
CAST(target_product_id AS STRING));
ELSE
SELECT CONCAT('did not find product ', CAST(target_product_id AS STRING));
END IF;
Bucles
LOOP
Sintaxis
LOOP sql_statement_list END LOOP;
Descripción
Ejecuta sql_statement_list
hasta que una declaración BREAK
o LEAVE
salga del bucle. sql_statement_list
es una lista de cero o más declaraciones de SQL que terminan en punto y coma. LOOP
no puede ejecutarse de forma dinámica como un elemento anidado.
Ejemplos
En el siguiente ejemplo, se declara una variable x
con el valor predeterminado 0. Luego, usa la declaración LOOP
para crear un bucle que se ejecutará hasta que la variable x
sea mayor o igual que 10; después de que se cierra el bucle, el ejemplo genera el valor de x
.
DECLARE x INT64 DEFAULT 0; LOOP SET x = x + 1; IF x >= 10 THEN LEAVE; END IF; END LOOP; SELECT x;
En este ejemplo, se muestra lo siguiente:
+----+
| x |
+----+
| 10 |
+----+
WHILE
Sintaxis
WHILE boolean_expression DO
sql_statement_list
END WHILE;
Hay un nivel máximo de anidación de 50 para bloques y declaraciones condicionales como BEGIN
/END
, IF
/ELSE
/END IF
y WHILE
/END WHILE
.
Descripción
Mientras boolean_expression
sea verdadero, ejecuta sql_statement_list
.
boolean_expression
se evalúa para cada iteración del bucle.
WHILE
no puede ejecutarse de forma dinámica como un elemento anidado.
BREAK
Descripción
Sale del bucle actual.
Usar BREAK
fuera de un bucle es un error.
Ejemplos
En el siguiente ejemplo, se declaran dos variables, heads
y heads_count
. Luego, se inicia un bucle, que asigna un valor booleano aleatorio a heads
. A continuación, verifica si heads
es verdadero; si es así, da como resultado “Heads!” (cara) y heads_count
aumenta; si no, da como resultado “Tails!” (cruz) y sale del bucle. Finalmente, da como resultado una string que indica cuántas veces el “lanzamiento de la moneda” dio como resultado “tails”.
DECLARE heads BOOL; DECLARE heads_count INT64 DEFAULT 0; LOOP SET heads = RAND() < 0.5; IF heads THEN SELECT 'Heads!'; SET heads_count = heads_count + 1; ELSE SELECT 'Tails!'; BREAK; END IF; END LOOP; SELECT CONCAT(CAST(heads_count AS STRING), ' heads in a row');
LEAVE
Sinónimo de BREAK
.
CONTINUE
Descripción
Omite cualquier declaración siguiente en el bucle actual y regresa al inicio del bucle.
Usar CONTINUE
fuera de un bucle es un error.
Ejemplos
En el siguiente ejemplo, se declaran dos variables, heads
y heads_count
. Luego, se inicia un bucle, que asigna un valor booleano aleatorio a heads
y verifica si heads
es verdadero. Si es así, el resultado es “Cara”, heads_count
aumenta y se reinicia el bucle, sin tener en cuenta las declaraciones restantes. En caso contrario, el resultado es “Sello” y sale del bucle. Finalmente, da como resultado una string que indica cuántas veces el “lanzamiento de la moneda” dio como resultado “Cara”.
DECLARE heads BOOL; DECLARE heads_count INT64 DEFAULT 0; LOOP SET heads = RAND() < 0.5; IF heads THEN SELECT 'Heads!'; SET heads_count = heads_count + 1; CONTINUE; END IF; SELECT 'Tails!'; BREAK; END LOOP; SELECT CONCAT(CAST(heads_count AS STRING), ' heads in a row');
ITERATE
Sinónimo de CONTINUE
.
RAISE
Sintaxis
RAISE [USING MESSAGE = message];
Descripción
Genera un error y usa, de manera opcional, el mensaje de error especificado cuando se proporciona USING
MESSAGE = message
.
Cuando no se proporciona USING MESSAGE
Solo se debe usar la declaración RAISE
dentro de una cláusula EXCEPTION
. La declaración RAISE
generará nuevamente la excepción que se capturó y conservará el seguimiento de pila original.
Cuando se proporciona USING MESSAGE
Si la declaración RAISE
se encuentra dentro de la sección BEGIN
de un bloque BEGIN...EXCEPTION
, ocurrirá lo siguiente:
- Se invocará al controlador.
El valor de
@@error.message
coincidirá exactamente con la stringmessage
proporcionada (que puede serNULL
simessage
esNULL
).Se establecerá el seguimiento de pila en la declaración
RAISE
.
Si la declaración RAISE
no se encuentra dentro de la sección BEGIN
de un bloque BEGIN...EXCEPTION
, la declaración RAISE
detendrá la ejecución de la secuencia de comandos con el mensaje de error proporcionado.
RETURN
En una secuencia de comandos de BigQuery, RETURN
detiene la ejecución de la secuencia de comandos actual.
CALL
Sintaxis
CALL procedure_name (procedure_argument[, …])
Descripción
Llama a un procedimiento con una lista de argumentos.
procedure_argument
puede ser una variable o una expresión. Para los argumentos OUT
o INOUT
, una variable pasada como argumento debe tener el tipo de BigQuery adecuado.
Es posible que la misma variable no aparezca varias veces como un argumento OUT
o INOUT
en la lista de argumentos del procedimiento.
La profundidad máxima de las llamadas a procedimiento es de 50 fotogramas.
CALL
no puede ejecutarse de forma dinámica como un elemento anidado.
Ejemplos
En el siguiente ejemplo, se declara una variable retCode
. Luego, llama al procedimiento updateSomeTables
en el conjunto de datos myDataset
, pasando los argumentos 'someAccountId'
y retCode
. Por último, muestra el valor de retCode
.
DECLARE retCode INT64;
-- Procedure signature: (IN account_id STRING, OUT retCode INT64)
CALL myDataset.UpdateSomeTables('someAccountId', retCode);
SELECT retCode;
Variables de sistema
Puedes usar variables de sistema para verificar la información durante la ejecución de una secuencia de comandos.
Nombre | Tipo | Descripción |
---|---|---|
@@current_job_id |
STRING |
ID de tarea del trabajo que se está ejecutando actualmente. En el contexto de una secuencia de comandos, muestra el trabajo responsable de la declaración actual en vez de la secuencia de comandos completa. |
@@last_job_id |
STRING |
ID de tarea del trabajo más reciente que se ejecutará en la secuencia de comandos actual, sin incluir el que se encuentra en la actualidad. Si la secuencia de comandos contiene declaraciones CALL , posiblemente, este trabajo se originó en un procedimiento diferente. |
@@project_id |
STRING |
ID del proyecto que se usó para ejecutar la consulta actual. En el contexto de un procedimiento, @@project_id se refiere al proyecto que ejecuta la secuencia de comandos, no al proyecto que posee el procedimiento. |
@@row_count |
INT64 |
Si se usa en una secuencia de comandos y la declaración de la secuencia de comandos anterior es DML, especificará la cantidad de filas modificadas, insertadas o borradas como resultado de esa declaración DML. Si la declaración anterior es MERGE, @@row_count representa la cantidad total de filas insertadas, quitadas y borradas. Este valor es NULL si no está en una secuencia de comandos. |
@@script.bytes_billed |
INT64 |
Total de bytes facturados hasta el momento en el trabajo de la secuencia de comandos en ejecución actualmente. Este valor es NULL si no está en una secuencia de comandos. |
@@script.bytes_processed |
INT64 |
Total de bytes procesados hasta el momento en el trabajo de la secuencia de comandos en ejecución actualmente. Este valor es NULL si no está en una secuencia de comandos. |
@@script.creation_time |
TIMESTAMP |
Hora de creación del trabajo de la secuencia de comandos en ejecución actualmente. Este valor es NULL si no está en una secuencia de comandos. |
@@script.job_id |
STRING |
ID de tarea del trabajo de la secuencia de comandos en ejecución actualmente. Este valor es NULL si no está en una secuencia de comandos. |
@@script.num_child_jobs |
INT64 |
Cantidad de trabajos secundarios completados en la actualidad. Este valor es NULL si no está en una secuencia de comandos. |
@@script.slot_ms |
INT64 |
Cantidad de milisegundos de ranura que la secuencia de comandos utilizó hasta el momento. Este valor es NULL si no está en una secuencia de comandos. |
@@time_zone |
STRING |
La zona horaria predeterminada que se debe usar en funciones de SQL que dependen de esta cuando no se especifica una zona horaria explícita como argumento. A diferencia de otras variables de sistema, se puede modificar @@time_zone mediante una declaración SET para cualquier nombre de zona horaria válido. Al inicio de cada secuencia de comandos, @@time_zone comienza como “UTC”. |
Además de las variables de sistema que se muestran arriba, puedes usar las variables de sistema EXCEPTION
durante la ejecución de una secuencia de comandos. Si no se usan en un controlador de excepciones, las variables de sistema EXCEPTION
son NULL
. Las siguientes son variables de sistema EXCEPTION
.
@@error.formatted_stack_trace
@@error.message
@@error.stack_trace
@@error.statement_text
Para obtener más información sobre las variables de sistema EXCEPTION
, consulta BEGIN…EXCEPTION.
Permisos
El permiso para acceder a una tabla, modelo o a otro recurso se verifica en el momento de la ejecución. Si no se ejecuta una declaración o no se evalúa una expresión, BigQuery no verifica si el usuario que ejecuta la secuencia de comandos tiene acceso a los recursos a los que hace referencia.
Dentro de una secuencia de comandos, los permisos para cada expresión o declaración se validan por separado. Por ejemplo, observa la siguiente secuencia de comandos:
SELECT * FROM dataset_with_access.table1; SELECT * FROM dataset_without_access.table2;
Si el usuario que ejecuta la secuencia de comandos tiene acceso a table1
, pero no tiene acceso a table2
, la primera consulta tendrá éxito y la segunda fallará. El trabajo de la secuencia de comandos también fallará.
Restricciones de seguridad
El SQL dinámico es conveniente, pero puede ofrecer nuevas oportunidades para el uso inadecuado. Por ejemplo, la ejecución de la siguiente consulta representa una amenaza de seguridad potencial, ya que el parámetro de la tabla podría filtrarse de forma incorrecta, permitir el acceso a tablas no deseadas y ejecutarse en ellas.
EXECUTE IMMEDIATE CONCAT(‘SELECT * FROM ’, @employee_table);
A fin de evitar la exposición o el filtrado datos sensibles en una tabla o la ejecución de comandos como DROP TABLE
para borrar datos en una tabla, la secuencia de comandos de SQL dinámica de BigQuery admite varias medidas de seguridad con el propósito de reducir la exposición a los ataques de inyección de SQL, incluidos los siguientes:
- No puedes ejecutar varias declaraciones de SQL incorporadas en los parámetros que se pasaron a SQL dinámico.
- Los siguientes comandos no pueden ejecutarse de forma dinámica:
BEGIN
/END
,CALL
,IF
,LOOP
,WHILE
yEXECUTE IMMEDIATE
.
Limitaciones del campo de configuración
Los siguientes campos de configuración de consulta no se pueden configurar para la secuencia de comandos:
clustering
create_disposition
destination_table
destination_encryption_configuration
range_partitioning
schema_update_options
time_partitioning
user_defined_function_resources
write_disposition