Secuencias de comandos en SQL estándar

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áusula INTO debe contener valores del mismo tipo. Puedes acceder a las variables del sistema y los valores presentes en la cláusula USING. 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áusula INTO.
  • Cláusula USING: Antes de ejecutar la expresión de SQL, puedes pasar uno o más identificadores de la cláusula USING 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áusula USING.

    -- 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áusula USING. 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 y USING.
  • 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áusula INTO 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 de query_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:
  • línea/columna: especifica la línea y el número de columna del marco de pila y comienza por 1. Si el marco se produce dentro del cuerpo de un procedimiento, line 1 column 1 corresponde a la palabra clave BEGIN al comienzo del cuerpo del procedimiento.
  • ubicación: si el marco se produce dentro del cuerpo de un procedimiento, especifica el nombre completo del procedimiento en el formato [project_name].[dataset_name].[procedure_name]. Si el marco hace referencia a una ubicación en una secuencia de comandos de nivel superior, este campo es NULL.
  • nombre de archivo: reservado para uso futuro. Siempre NULL.
@@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 la división por cero error, en lugar de detener la secuencia de comandos completa, BigQuery detendrá 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 string message proporcionada (que puede ser NULL si message es NULL).

  • 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 y EXECUTE 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