Scripts do BigQuery
Com os scripts do BigQuery, é possível enviar várias instruções ao BigQuery em uma solicitação, além de usar variáveis e usar instruções de fluxo de controle como IF
e WHILE
. Por exemplo, é possível declarar uma variável, atribuir um valor a ela e, em seguida, referenciá-la em uma terceira instrução.
No BigQuery, um script é uma lista de instruções SQL que serão executadas em sequência. Uma lista de instruções SQL é uma lista de todas as instruções válidas do BigQuery separadas por ponto e vírgula.
Exemplo:
-- 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 );
Os scripts são executados no BigQuery usando jobs.insert
, que é semelhante a qualquer outra consulta, com o script de várias instruções especificado como o texto da consulta. Quando um script é executado, são criados nele outros jobs, conhecidos como jobs filhos, para cada instrução. Para enumerar os jobs filhos de um script, chame jobs.list
e transmita o código do job como o parâmetro parentJobId
.
Quando jobs.getQueryResults
for invocado em um script, ele retornará os resultados de consulta da última instrução SELECT, DML ou DDL a ser executada no script. Se nenhuma delas for executada, não haverá resultados de consulta. Para receber os resultados de todas as instruções no script, enumere os jobs filhos e chame jobs.getQueryResults
em cada um deles.
O BigQuery interpreta qualquer solicitação com várias instruções como um script, a menos que elas sejam instruções CREATE TEMP FUNCTION
com uma única instrução de consulta final. Por exemplo, o caso a seguir não seria considerado um script:
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
precisa ser um identificador válido e variable_type
é qualquer tipo do BigQuery.
Descrição
Declara uma variável do tipo especificado. Se a cláusula DEFAULT
for especificada, a variável será inicializada com o valor da expressão. Se nenhuma cláusula DEFAULT
estiver presente, a variável será inicializada com o valor NULL
.
Se o [variable_type]
for omitido, será preciso especificar uma cláusula DEFAULT
. O tipo da variável será inferido pelo tipo da expressão na cláusula DEFAULT
.
As declarações de variável precisam aparecer no início de um script, antes de qualquer outra instrução ou no início de um bloco declarado com BEGIN
. Não há diferenciação entre maiúsculas e minúsculas nos nomes de variáveis.
Vários nomes de variáveis podem aparecer em uma única instrução DECLARE
, mas apenas uma variable_type
e expression
.
É um erro declarar uma variável com o mesmo nome de uma variável declarada anteriormente no bloco atual ou em um bloco que a contém.
Se a cláusula DEFAULT
estiver presente, o valor da expressão precisará ser coercível para o tipo especificado. A expressão pode referenciar outras variáveis declaradas anteriormente dentro do mesmo bloco ou em um bloco que a contém.
O tamanho máximo de uma variável é 1 MB, e o tamanho máximo de todas as variáveis usadas em um script é de 10 MB.
Exemplos
O exemplo a seguir inicializa a variável x
como um INT64 com o valor NULL
.
DECLARE x INT64;
O exemplo a seguir inicializa a variável d
como uma DATE com o valor da data atual.
DECLARE d DATE DEFAULT CURRENT_DATE();
O exemplo a seguir inicializa as variáveis x
, y
e z
como INT64
com o valor 0.
DECLARE x, y, z INT64 DEFAULT 0;
No exemplo a seguir, uma variável denominada item
é declarada, correspondendo a um item arbitrário na tabela dataset1.products
. O tipo de item
é inferido do esquema da tabela.
DECLARE item DEFAULT (SELECT item FROM dataset1.products LIMIT 1);
SET
Sintaxe
SET name = expression;
SET (variable_name_1, variable_name_2, …, variable_name_n) = (expression_1, expression_2, …, expression_n);
Descrição
Define o valor da expressão fornecida para uma variável ou define várias variáveis ao mesmo tempo, com base no resultado de várias expressões.
A instrução SET
pode aparecer em qualquer parte do corpo de um script.
Exemplos
O exemplo a seguir define o valor 5 para a variável x
.
SET x = 5;
O exemplo a seguir define o valor 4 para a variável a
, "foo" para b
e false
para c
.
SET (a, b, c) = (1 + 3, 'foo', false);
O exemplo a seguir atribui o resultado de uma consulta a diversas variáveis.
Primeiro, ele declara duas variáveis, target_word
e corpus_count
; em seguida, atribui os resultados de uma consulta SELECT AS STRUCT
às duas variáveis. O resultado da consulta é uma única linha contendo um STRUCT
com dois campos: o primeiro elemento é atribuído à primeira variável e o segundo elemento é atribuído à segunda variável.
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;
Essa lista de instruções gera a seguinte string:
Found 151 occurrences of "methinks" across 38 Shakespeare works
EXECUTE IMMEDIATE
Sintaxe
EXECUTE IMMEDIATE sql_expression [ INTO variable[, ...] ] [ USING identifier[, ...] ];
sql_expression:
{ "query_statement" | expression("query_statement") }
identifier:
{ variable | value } [ AS alias ]
Descrição
Executa uma instrução SQL dinâmica imediatamente.
sql_expression
: representa uma instrução de consulta, uma expressão que você pode usar em uma instrução de consulta, uma única instrução DDL ou uma única instrução DML.expression
: pode ser uma função, uma expressão condicional ou uma subconsulta de expressão.query_statement
: representa uma instrução SQL independente válida para ser executada. Se isso retornar um valor, a cláusulaINTO
precisará conter valores do mesmo tipo. É possível acessar variáveis e valores do sistema presentes na cláusulaUSING
. Todas as outras variáveis locais e parâmetros de consulta não são expostos à instrução de consulta.- Cláusula
INTO
: depois que a expressão SQL for executada, será possível armazenar os resultados em uma ou mais variáveis, usando a cláusulaINTO
. - Cláusula
USING
: antes de executar a expressão SQL, é possível passar um ou mais identificadores da cláusulaUSING
para a expressão SQL. Esses identificadores funcionam de maneira semelhante aos parâmetros de consulta, expondo valores à instrução de consulta. Um identificador pode ser uma variável ou um valor.
É possível incluir esses marcadores no query_statement
para identificadores referenciados na cláusula USING
:
?
: o valor desse marcador por índice está vinculado a um identificador na cláusulaUSING
.-- y = 1 * (3 + 2) = 5 EXECUTE IMMEDIATE "SELECT ? * (? + 2)" INTO y USING 1, 3;
@identifier
: o valor desse marcador está vinculado por nome a um identificador na cláusulaUSING
. Essa sintaxe é idêntica à sintaxe do parâmetro de consulta.-- y = 1 * (3 + 2) = 5 EXECUTE IMMEDIATE "SELECT @a * (@b + 2)" INTO y USING 1 as a, 3 as b;
Veja algumas observações adicionais sobre o comportamento da instrução EXECUTE IMMEDIATE
:
EXECUTE IMMEDIATE
não pode ser executado dinamicamente como um elemento aninhado.- Se uma instrução
EXECUTE IMMEDIATE
retornar resultados, eles se tornarão o resultado de toda a instrução e todas as variáveis de sistema apropriadas serão atualizadas. - A mesma variável pode aparecer nas cláusulas
INTO
eUSING
. query_statement
pode conter uma única instrução analisada que contém outras instruções (por exemplo, BEGIN...END)- Se nenhuma linha for retornada de
query_statement
, inclusive de tabelas de valores de linha zero, todas as variáveis na cláusulaINTO
serão definidas como NULL. - Se uma linha for retornada de
query_statement
, inclusive de tabelas de valores de linha zero, os valores serão atribuídos por posição, não por nome de variável. - Se uma cláusula
INTO
estiver presente, um erro será gerado se você tentar retornar mais de uma linha dequery_statement
.
Exemplos
Neste exemplo, criamos uma tabela de livros e a preenchemos com dados. Observe as diferentes maneiras de referir-se a variáveis, salvar valores em variáveis e usar expressões.
-- 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
Sintaxe
BEGIN sql_statement_list END;
Descrição
BEGIN
inicia um bloco de declarações onde as variáveis declaradas existem somente até o END
correspondente. sql_statement_list
é uma lista de zero ou mais instruções SQL terminadas em ponto e vírgula.
As declarações de variável precisam aparecer no início do bloco, antes de outros tipos de declarações. As variáveis declaradas dentro de um bloco só podem ser referenciadas dentro desse mesmo bloco e em blocos aninhados. É um erro declarar uma variável com o mesmo nome de uma variável declarada no mesmo bloco ou em um bloco externo.
Há um nível máximo de aninhamento de 50 para blocos e declarações condicionais
como BEGIN
/END
, IF
/ELSE
/END IF
e WHILE
/END WHILE
.
BEGIN
/END
não pode ser executado dinamicamente como um elemento aninhado.
Exemplos
O exemplo a seguir declara uma variável x
com o valor padrão 10. Em seguida,
ele inicia um bloco, em que uma variável y
recebe o valor de x
,
que é 10, e retorna esse valor; próxima à instrução END
encerra o bloco, encerrando o
escopo da variável y
; Por fim, ele retorna o valor de x
.
DECLARE x INT64 DEFAULT 10; BEGIN DECLARE y INT64; SET y = x; SELECT y; END; SELECT x;
BEGIN...EXCEPTION
Sintaxe
BEGIN sql_statement_list EXCEPTION WHEN ERROR THEN sql_statement_list END;
Descrição
BEGIN...EXCEPTION
executa um bloco de instruções. Se alguma das instruções encontra um erro, o script ignora o restante do bloco e executa as instruções na cláusula EXCEPTION
.
Na cláusula EXCEPTION
, é possível acessar os detalhes sobre o erro usando as seguintes variáveis de sistema EXCEPTION
:
Nome | Tipo | Descrição |
---|---|---|
@@error.formatted_stack_trace |
STRING |
O conteúdo de @@error.stack_trace , expresso como uma string legível. Este valor, destinado a fins de exibição, está sujeito a alterações sem aviso. O acesso programático ao rastreamento de pilha de um erro deve usar @@error.stack_trace . |
@@error.message |
STRING |
Especifica uma mensagem de erro legível. |
@@error.stack_trace |
Consulte 1. | Cada elemento da matriz corresponde a uma instrução ou chamada de procedimento em execução no momento do erro, com o frame de pilha em execução sendo exibido primeiro. O significado de cada campo é definido da seguinte maneira:
|
@@error.statement_text |
STRING |
Especifica o texto da instrução que causou o erro. |
1 O tipo de @@error.stack_trace
é ARRAY<STRUCT<line INT64, column INT64, filename STRING, location STRING>>
.
Como o BigQuery reserva-se o direito de revisar mensagens de erro a qualquer momento, os consumidores de @@error.message
não devem pensar que essas mensagens permanecem iguais nem seguir padrões específicos. Não extraia informações do local em que a falha ocorreu do texto da mensagem de erro. Em vez disso, use @@error.stack_trace
e @@error.statement_text
.
Para processar as exceções que foram geradas, mas não processadas, por um gerenciador de exceções, é necessário agrupar o bloco em outro externo usando um gerenciador diferente.
Veja a seguir como utilizar um bloco externo com um gerenciador de exceções separado:
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;
Os blocos BEGIN...EXCEPTION
também são compatíveis com instruções DECLARE
, como qualquer outro bloco BEGIN
. As variáveis declaradas em um bloco BEGIN
são válidas apenas na
seção BEGIN
, não podendo ser usadas no gerenciador de exceções do bloco.
Exemplos
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;
Neste exemplo, quando ocorre o erro de divisão por zero, em vez de
interromper todo o script, o BigQuery interrompe
dataset1.proc1()
e dataset1.proc2()
e executa a instrução SELECT no
gerenciador de exceções. Quando o gerenciador é executado, as variáveis assumem os seguintes valores:
Variável | 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
Termina um bloco iniciado por BEGIN
. BEGIN
/END
não pode ser executado dinamicamente como um elemento aninhado.
IF
Sintaxe
IF condition THEN [sql_statement_list] [ELSEIF condition THEN sql_statement_list] [ELSEIF condition THEN sql_statement_list]... [ELSE sql_statement_list] END IF;
Descrição
Executa o primeiro sql_statement_list
, em que a condição é verdadeira, ou o ELSE
sql_statement_list
opcional, se não há condições correspondentes.
Há um nível máximo de aninhamento de 50 para blocos e declarações condicionais
como BEGIN
/END
, IF
/ELSE
/END IF
e WHILE
/END WHILE
.
IF
não pode ser executado dinamicamente como um elemento aninhado.
Exemplos
O exemplo a seguir declara uma variável INT64 target_product_id
com um valor padrão de 103; depois, ele verifica se a tabela dataset.products
contém uma linha com a coluna product_id
correspondente ao valor de target_product_id
; em caso afirmativo, ele gera uma string informando que o produto foi encontrado, junto do valor de default_product_id
; em caso negativo, ele gera uma string informando que o produto não foi encontrado, bem como o 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;
Loops
LOOP
Sintaxe
LOOP sql_statement_list END LOOP;
Descrição
Executa sql_statement_list
até que uma instrução BREAK
ou LEAVE
saia do loop. sql_statement_list
é uma lista de zero ou mais instruções SQL terminadas em
ponto e vírgula. LOOP
não pode ser executado dinamicamente como um elemento aninhado.
Exemplos
O exemplo a seguir declara uma variável x
com o valor padrão 0,
ele usa a instrução LOOP
para criar um loop que é executado até que a variável
x
seja maior ou igual a 10; após a saída do loop, o exemplo
gera o valor de x
.
DECLARE x INT64 DEFAULT 0; LOOP SET x = x + 1; IF x >= 10 THEN LEAVE; END IF; END LOOP; SELECT x;
Este exemplo retorna o seguinte:
+----+
| x |
+----+
| 10 |
+----+
ENQUANTO
Sintaxe
WHILE boolean_expression DO
sql_statement_list
END WHILE;
Há um nível máximo de aninhamento de 50 para blocos e declarações condicionais como BEGIN
/END
, IF
/ELSE
/END IF
e WHILE
/END WHILE
.
Descrição
Enquanto boolean_expression
for verdadeiro, executa sql_statement_list
.
boolean_expression
é avaliado para cada iteração do loop.
WHILE
não pode ser executado dinamicamente como um elemento aninhado.
BREAK
Descrição
Sai do loop atual.
É um erro usar BREAK
fora de um loop.
Exemplos
No exemplo a seguir, o código declara duas variáveis, heads
e heads_count
.
Depois, ele inicia um loop, que atribui um valor booleano aleatório a heads
e
verifica se heads
é verdadeiro. Se for o caso, o resultado será "Heads!" (cara), e
heads_count
será adicionado. Em caso negativo, o resultado será "Tails!"(coroa), e o loop
será encerrado. Por fim, ele gera uma string que indica quantas vezes o jogo de "cara ou coroa" resultou em "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; ELSE SELECT 'Tails!'; BREAK; END IF; END LOOP; SELECT CONCAT(CAST(heads_count AS STRING), ' heads in a row');
SAIR
Sinônimo de BREAK
.
CONTINUAR
Descrição
Ignora as instruções a seguir no loop atual e retorna ao início do loop.
É um erro usar CONTINUE
fora de um loop.
Exemplos
No exemplo a seguir, o código declara duas variáveis, heads
e heads_count
. Depois, ele inicia um loop, que atribui um valor booleano aleatório a heads
e verifica se heads
é verdadeiro. Se for o caso, o resultado será "Heads!" (cara), heads_count
será adicionado e o loop será reiniciado, ignorando as instruções restantes. Em caso negativo, o resultado será "Tails!" (coroa), e o loop será encerrado. Por fim, ele gera uma string que indica quantas vezes o jogo de "cara ou coroa" resultou em "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');
ITERAR
Sinônimo de CONTINUE
.
RAISE
Sintaxe
RAISE [USING MESSAGE = message];
Descrição
Gera um erro, opcionalmente, usando a mensagem de erro especificada quando USING
MESSAGE = message
é fornecido.
Quando USING MESSAGE
não é fornecido
A instrução RAISE
só precisa ser usada em uma cláusula EXCEPTION
. A instrução RAISE
gerará novamente a exceção que foi capturada, preservando o rastreamento de pilha original.
Quando USING MESSAGE
é fornecido
Veja o que acontecerá se a instrução RAISE
estiver contida na seção BEGIN
de um bloco BEGIN...EXCEPTION
:
- O gerenciador será invocado.
O valor de
@@error.message
corresponderá exatamente à stringmessage
fornecida (que poderá serNULL
semessage
forNULL
).O rastreamento de pilha será definido com a instrução
RAISE
.
Se a instrução RAISE
não estiver contida na seção BEGIN
de um bloco
BEGIN...EXCEPTION
, a instrução RAISE
interromperá a execução do
script com a mensagem de erro fornecida.
RETURN
Em um script do BigQuery, RETURN
interrompe a execução do script
atual.
CALL
Sintaxe
CALL procedure_name (procedure_argument[, …])
Descrição
Chama um procedimento com uma lista de argumentos.
procedure_argument
pode ser uma variável ou uma expressão. Para argumentos OUT
ou INOUT
, uma variável passada como um argumento precisa ter o tipo apropriado do BigQuery.
A mesma variável pode não aparecer diversas vezes como um argumento OUT
ou INOUT
na lista de argumentos do procedimento.
A profundidade máxima das chamadas de procedimento é de 50 frames.
CALL
não pode ser executado dinamicamente como um elemento aninhado.
Exemplos
O exemplo a seguir declara uma variável retCode
. Em seguida, ele chama o procedimento updateSomeTables
no conjunto de dados myDataset
, passando os argumentos 'someAccountId'
e retCode
. Por fim, o valor de retCode
é retornado.
DECLARE retCode INT64;
-- Procedure signature: (IN account_id STRING, OUT retCode INT64)
CALL myDataset.UpdateSomeTables('someAccountId', retCode);
SELECT retCode;
Variáveis de sistema
É possível usar variáveis de sistema para verificar informações durante a execução de um script.
Nome | Tipo | Descrição |
---|---|---|
@@current_job_id |
STRING |
ID do job em execução no momento. No contexto de um script, retorna o job responsável pela instrução atual, não o script inteiro. |
@@last_job_id |
STRING |
ID do job mais recente a ser executado no script atual, sem incluir o atual. Se o script contém instruções CALL , ele pode ser originário de um procedimento diferente. |
@@project_id |
STRING |
ID do projeto usado para executar a consulta atual. No contexto de um procedimento, @@project_id refere-se ao projeto que executa o script, não ao projeto proprietário do procedimento. |
@@row_count |
INT64 |
Se usado em um script e a instrução de script anterior for DML, especifica o número de linhas modificadas, inseridas ou excluídas, em decorrência dessa instrução DML. Se a instrução anterior é MERGE, @@row_count representa o número total combinado de linhas inseridas, removidas e excluídas. Esse valor será NULL se não estiver em um script. |
@@script.bytes_billed |
INT64 |
Total de bytes faturados até o momento no job de script em execução no momento. Esse valor será NULL se não estiver em um script. |
@@script.bytes_processed |
INT64 |
Total de bytes processados até o momento no job de script em execução no momento. Esse valor será NULL se não estiver em um script. |
@@script.creation_time |
TIMESTAMP |
Hora de criação do job de script em execução no momento. Esse valor será NULL se não estiver em um script. |
@@script.job_id |
STRING |
ID do job de script em execução no momento. Esse valor será NULL se não estiver em um script. |
@@script.num_child_jobs |
INT64 |
Número de jobs filhos concluídos no momento. Esse valor será NULL se não estiver em um script. |
@@script.slot_ms |
INT64 |
Número de milissegundos de slot usados até o momento pelo script. Esse valor será NULL se não estiver em um script. |
@@time_zone |
STRING |
O fuso horário padrão a ser usado em funções SQL dependentes de fuso horário, quando um fuso horário explícito não é especificado como um argumento. Ao contrário de outras variáveis de sistema, é possível modificar @@time_zone usando uma instrução SET para qualquer nome de fuso horário válido. No início de cada script, @@time_zone começa como "UTC". |
Além das variáveis de sistema mostradas acima, é possível usar EXCEPTION
durante a execução de um script. As variáveis de sistema EXCEPTION
serão NULL
se não forem usadas em um gerenciador de exceções. Veja a seguir as variáveis de sistema EXCEPTION
.
@@error.formatted_stack_trace
@@error.message
@@error.stack_trace
@@error.statement_text
Para mais informações sobre as variáveis de sistema EXCEPTION
, consulte
BEGIN...EXCEPTION.
Permissões
A permissão para acessar uma tabela, modelo ou outro recurso é verificada no momento da execução. Se uma instrução não for executada ou uma expressão não for avaliada, o BigQuery não verificará se o usuário que está executando o script tem acesso aos recursos referenciados por ele.
Em um script, as permissões para cada expressão ou instrução são validadas separadamente. Por exemplo, considere o script a seguir:
SELECT * FROM dataset_with_access.table1; SELECT * FROM dataset_without_access.table2;
Se o usuário que estiver executando o script tiver acesso a table1
, mas não tiver acesso a table2
, a primeira consulta será bem-sucedida e a segunda falhará. O job de script também falhará.
Restrições de segurança
O SQL dinâmico é conveniente, mas pode oferecer novas oportunidades de uso indevido. Por exemplo, a execução da consulta a seguir representa uma possível ameaça à segurança, já que o parâmetro de tabela pode ser filtrado indevidamente, permitir acesso e ser executado em tabelas não intencionais.
EXECUTE IMMEDIATE CONCAT(‘SELECT * FROM ’, @employee_table);
Para evitar a exposição ou o vazamento de dados confidenciais em uma tabela ou a execução de comandos como DROP TABLE
, que excluir dados em uma tabela, o script SQL dinâmico do BigQuery é compatível com várias medidas de segurança que reduzem a exposição a ataques de injeção de SQL, incluindo:
- Não é possível executar várias instruções SQL incorporadas nos parâmetros transmitidos para o SQL dinâmico.
- Os seguintes comandos estão impedidos de serem executados dinamicamente:
BEGIN
/END
,CALL
,IF
,LOOP
,WHILE
eEXECUTE IMMEDIATE
.
Limitações do campo de configuração
Estes campos de configuração de consulta não podem ser definidos para scripts:
clustering
create_disposition
destination_table
destination_encryption_configuration
range_partitioning
schema_update_options
time_partitioning
user_defined_function_resources
write_disposition