標準 SQL のスクリプト ステートメント

スクリプトを使用すると、1 回のリクエストで複数のステートメントを BigQuery に送信できます。スクリプトでは、変数だけでなく、IFWHILE などの制御フロー ステートメントも使用できます。たとえば、変数を宣言して値を代入し、第 3 の場所にあるステートメントからその変数を参照できます。

スクリプトの変数と一時テーブルルール、デバッグ、プロシージャの記述の詳細については、スクリプトとストアド プロシージャをご覧ください。

DECLARE

DECLARE variable_name[, ...] [variable_type] [DEFAULT expression];

variable_name は、有効な識別子である必要があります。また、variable_type は BigQuery の任意のタイプです。

説明

指定された型の変数を宣言します。たとえば DEFAULT 句が指定された場合、変数は式の値で初期化されます。DEFAULT 句が指定されない場合、変数は値 NULL で初期化されます。

[variable_type] を省略する場合、DEFAULT 句を指定する必要があります。変数の型は、DEFAULT 句の式の型によって推定されます。

変数の宣言は、スクリプトの先頭、他のステートメントの前、または BEGIN が宣言されたブロックの先頭に置きます。変数名は大文字と小文字を区別しません。

複数の変数名を 1 つの DECLARE ステートメント内に記述できます。ただし、variable_typeexpression は 1 つだけです。

現在のブロックまたは格納中のブロックですでに宣言されている変数と同じ名前の変数を宣言するとエラーになります。

たとえば DEFAULT 句が存在する場合、式の値は指定された型に強制型変換できる必要があります。同じブロックまたは格納中のブロック内ですでに宣言されているその他の変数を参照できます。

変数の最大サイズは 1 MB で、スクリプトで使用されるすべての変数の最大サイズは 10 MB です。

次の例では、変数 x を INT64 として値 NULL で初期化しています。

DECLARE x INT64;

次の例では、変数 d を DATE として現在の日付の値で初期化しています。

DECLARE d DATE DEFAULT CURRENT_DATE();

次の例では、xyzINT64 として値 0 で初期化しています。

DECLARE x, y, z INT64 DEFAULT 0;

次の例では、dataset1.products テーブルの任意の項目に対応する item という名前の変数を宣言しています。item の型はテーブル スキーマから推測されます。

DECLARE item DEFAULT (SELECT item FROM dataset1.products LIMIT 1);

SET

構文

SET name = expression;
SET (variable_name_1, variable_name_2, …, variable_name_n) =
  (expression_1, expression_2, …, expression_n);

説明

変数が指定された式の値を持つように設定するか、または複数の式の結果に基づいて複数の変数を同時に設定します。

SET スクリプト本文内のどこにでも記述できます。

次の例では、変数 x の値を 5 に設定しています。

SET x = 5;

次の例では、a の値を 4、b の値を 'foo'、c の値を false にそれぞれ設定しています。

SET (a, b, c) = (1 + 3, 'foo', false);

次の例では、クエリの結果を複数の変数に代入しています。まず、2 つの変数 target_wordcorpus_count を宣言します。次に、SELECT AS STRUCT クエリの結果を 2 つの変数に割り当てます。クエリの結果は、2 つのフィールドを持つ STRUCT を含む 1 つの行です。最初の要素は最初の変数に割り当てられ、2 番目の要素は 2 番目の変数に割り当てられます。

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;

このステートメント リストは、次の文字列を出力します。

Found 151 occurrences of "methinks" across 38 Shakespeare works

EXECUTE IMMEDIATE

構文

EXECUTE IMMEDIATE sql_expression [ INTO variable[, ...] ] [ USING identifier[, ...] ];

sql_expression:
  { "query_statement" | expression("query_statement") }

identifier:
  { variable | value } [ AS alias ]

説明

動的 SQL ステートメントをすぐに実行します。

  • sql_expression: クエリ ステートメント、クエリ ステートメントで使用できる式、単一の DDL ステートメント、または単一の DML ステートメントを表します。IF のような制御ステートメントは使用できません。
  • expression: 関数条件式式サブクエリのいずれかです。
  • query_statement: 実行する有効なスタンドアロン SQL ステートメントを表します。値を返す場合、INTO 句には同じ型の値を含める必要があります。USING 句にあるシステム変数と値の両方にアクセスできます。他のすべてのローカル変数とクエリ パラメータは、クエリ ステートメントに公開されません。
  • INTO 句: SQL 式の実行後、INTO 句を使用して結果を 1 つ以上の変数に格納できます。
  • USING 句: SQL 式の実行前、USING 句から 1 つ以上の識別子を SQL 式に渡すことができます。これらの識別子はクエリ パラメータと同様に機能し、クエリ ステートメントに値を公開します。識別子は変数または値です。

USING 句で参照される識別子の query_statement には、次のプレースホルダを含めることができます。

  • ?: このプレースホルダの値は、インデックスで USING 句の識別子にバインドされます。

    -- y = 1 * (3 + 2) = 5
    EXECUTE IMMEDIATE "SELECT ? * (? + 2)" INTO y USING 1, 3;
    
  • @identifier: このプレースホルダの値は、名前で USING 句の識別子にバインドされます。この構文はクエリ パラメータの構文と同じです。

    -- y = 1 * (3 + 2) = 5
    EXECUTE IMMEDIATE "SELECT @a * (@b + 2)" INTO y USING 1 as a, 3 as b;
    

EXECUTE IMMEDIATE ステートメントの動作に関するその他の注意事項は次のとおりです。

  • EXECUTE IMMEDIATE は、ネストされた要素として動的に実行されません。つまり、別の EXECUTE IMMEDIATE ステートメントに EXECUTE IMMEDIATE をネストすることはできません。
  • EXECUTE IMMEDIATE ステートメントが結果を返す場合、それらの結果はステートメント全体の結果になり、適切なシステム変数が更新されます。
  • 同じ変数を INTO 句と USING 句の両方に使用できます。
  • query_statement には、他のステートメント(BEGIN...END など)を含む単一の解析済みステートメントを含めることができます。
  • ゼロ行の値テーブルからも含めて、query_statement からゼロ行が返される場合、INTO 句のすべての変数は NULL に設定されます。
  • ゼロ行の値のテーブルからも含めて、1 つの行が query_statement から返される場合、値は変数名ではなく位置で割り当てられます。
  • INTO 句が存在する場合、query_statement から複数の行を返そうとするとエラーがスローされます。

この例では、書籍の表を作成してその表にデータを入力します。変数の参照、変数への値の保存、式の使用にはさまざまな方法があります。

-- 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...END

構文

BEGIN
  sql_statement_list
END;

説明

BEGIN は、宣言された変数が対応する END まで存在するステートメントのブロックを開始します。sql_statement_list は、それぞれがセミコロンで終わるゼロ個以上の SQL ステートメントのリストです。

変数宣言は、ブロックの先頭で、その他のタイプのステートメントよりも前に配置する必要があります。ブロック内で宣言された変数は、そのブロック内とネストされたブロック内でのみ参照できます。同じブロックまたは外側のブロックで宣言されている変数と同じ名前の変数を宣言するとエラーになります。

ブロックや条件文(BEGIN / ENDIF / ELSE / END IFWHILE / END WHILE など)の最大のネストレベルは 50 です。

BEGIN / END は、ネストされた要素として動的に実行されません。

次の例では、変数 x にデフォルト値 10 を宣言しています。次にブロックを開始し、変数 y に値 x(この場合は 10)が割り当てられ、この値を返します。さらに、END ステートメントはブロックを終了し、変数 y のスコープを終了します。最後に x の値を返します。

DECLARE x INT64 DEFAULT 10;
BEGIN
  DECLARE y INT64;
  SET y = x;
  SELECT y;
END;
SELECT x;

BEGIN...EXCEPTION...END

構文

BEGIN
  sql_statement_list
EXCEPTION WHEN ERROR THEN
  sql_statement_list
END;

説明

BEGIN...EXCEPTION はステートメントのブロックを実行します。ステートメントのいずれかにエラーが発生した場合、スクリプトは残りのブロックをスキップし、EXCEPTION 句のステートメントを実行します。

EXCEPTION 句内では、次の EXCEPTION システム変数を使用することでエラーの詳細にアクセスできます。

名前 説明
@@error.formatted_stack_trace STRING @@error.stack_trace のコンテンツは人が読める文字列として表現されます。この値は表示を目的に使用され、予告なく変更されることがあります。プログラムによるエラーのスタック トレースへのアクセスには、代わりに @@error.stack_trace を使用してください。
@@error.message STRING 人が読めるエラー メッセージを指定します。
@@error.stack_trace 1 をご覧ください。 配列の各要素は、エラーの時点で実行しているステートメントまたはプロシージャ コールに対応し、現在実行中のスタック フレームが先頭に表示されます。各フィールドの意味の定義は、次のとおりです。
  • 行 / 列: スタック フレームの行番号と列番号を 1 から開始して指定します。フレームがプロシージャの本文内で発生した場合、line 1 column 1 はプロシージャの先頭にある BEGIN キーワードに対応します。
  • ロケーション: フレームがプロシージャ本文内にある場合、[project_name].[dataset_name].[procedure_name] 形式でプロシージャのフルネームを指定します。フレームがトップレベル スクリプト内の場所を参照している場合、このフィールドは NULL になります。
  • ファイル名: 将来の使用のために予約されています。常に NULL です。
@@error.statement_text STRING エラーの原因となったステートメントのテキストを指定します。

1: @@error.stack_trace の型は ARRAY<STRUCT<line INT64, column INT64, filename STRING, location STRING>> です。

BigQuery はエラー メッセージをいつでも修正できるため、@@error.message の使用にあたっては、エラー メッセージが常に同じである、または一定のパターンであることを想定しないでください。エラー メッセージからテキストを抽出してエラーの場所情報を取得せず、代わりに @@error.stack_trace@@error.statement_text を使用してください。

例外ハンドラによってスローされる(そして、処理されない)例外を処理するには、個別の例外ハンドラを使用して外側のブロック内にあるブロックをラップする必要があります。

外側のブロックに別の例外ハンドラを使用する方法は次のとおりです。

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;

BEGIN...EXCEPTION ブロックは、他の BEGIN ブロック同様に DECLARE ステートメントもサポートします。BEGIN ブロックで宣言されている変数は、BEGIN セクションでのみ有効で、ブロックの例外ハンドラでは使用できません。

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;

この例では、ゼロ除算のエラーが発生した場合にスクリプト全体が終了するのではなく、BigQuery が dataset1.proc1()dataset1.proc2() を停止し、例外ハンドラで SELECT ステートメントを実行します。例外ハンドラが実行されると、変数の値は次のようになります。

変数
@@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]"

IF

構文

IF condition THEN [sql_statement_list]
  [ELSEIF condition THEN sql_statement_list]
  [...]
  [ELSE sql_statement_list]
END IF;

説明

条件が true の場合は最初の sql_statement_list を、条件が一致しない場合はオプションの ELSE sql_statement_list を実行します。

ブロックや条件文(BEGIN / ENDIF / ELSE / END IFWHILE / END WHILE など)の最大のネストレベルは 50 です。

IF は、ネストされた要素として動的に実行されません。つまり、EXECUTE IMMEDIATE ステートメントに IF をネストすることはできません。

次の例では、INT64 変数 target_product_id のデフォルト値が 103 と宣言されています。この宣言によりテーブル dataset.productsproduct_id 列を持つ行を含み target_product_id の値と一致するかどうかがチェックされます。一致する場合は、プロダクトが見つかったという文字列と default_product_id の値が出力されます。一致しない場合は、プロダクトが見つからなかったという文字列と 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;

ループ

LOOP

構文

LOOP
  sql_statement_list
END LOOP;

説明

BREAK または LEAVE ステートメントでループが終了するまで、sql_statement_list が実行されます。sql_statement_list は、それぞれがセミコロンで終わるゼロ個以上の SQL ステートメントのリストです。

LOOP は、ネストされた要素として動的に実行されません。つまり、EXECUTE IMMEDIATE ステートメントに LOOP をネストすることはできません。

次の例では、変数 x にデフォルト値 0 を宣言しています。次に、LOOP ステートメントを使用して、変数 x が 10 以上になるまで実行されるループを作成します。ループが終了すると、x の値が出力されます。

DECLARE x INT64 DEFAULT 0;
LOOP
  SET x = x + 1;
  IF x >= 10 THEN
    LEAVE;
  END IF;
END LOOP;
SELECT x;

この例では、次を出力します。

+----+
| x  |
+----+
| 10 |
+----+

WHILE

構文

WHILE boolean_expression DO
  sql_statement_list
END WHILE;

ブロックや条件文(BEGIN / ENDIF / ELSE / END IFWHILE / END WHILE など)の最大のネストレベルは 50 です。

説明

boolean_expression が true の場合は、sql_statement_list が実行されます。boolean_expression は、ループの反復処理ごとに評価されます。

WHILE は、ネストされた要素として動的に実行されません。つまり、EXECUTE IMMEDIATE ステートメントに WHILE をネストすることはできません。

BREAK

構文

BREAK;

説明

現在のループを終了します。

BREAK をループの外側で使用するとエラーが発生します。

次の例では、変数 headsheads_count が宣言されています。次に、ループを開始します。ループ内では、ランダムなブール値が heads に割り当てられています。次に、heads が true の場合に「Heads!」(コインの表)と出力され、heads_count が増分されます。true でない場合は「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

BREAK と同義。

CONTINUE

構文

CONTINUE;

説明

現在のループ内の次のステートメントをスキップし、ループの先頭に戻ります。

CONTINUE をループの外側で使用するとエラーが発生します。

このステートメントではラベルを使用できます。詳細については、ラベルをご覧ください。

次の例では、変数 headsheads_count が宣言されています。次に、ループを開始します。ループ内では、ランダムなブール値が heads に割り当てられています。次に、heads が true の場合に「Heads!」(コインの表)と出力され、heads_count が増分され、ループの最初に戻ります(その他のステートメントは飛ばされる)。true でない場合は「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;
    CONTINUE;
  END IF;
  SELECT 'Tails!';
  BREAK;
END LOOP;
SELECT CONCAT(CAST(heads_count AS STRING), ' heads in a row');

ITERATE

CONTINUE と同義。

トランザクション

BEGIN TRANSACTION

構文

BEGIN [TRANSACTION];

説明

トランザクションを開始します。

COMMIT TRANSACTION または ROLLBACK TRANSACTION ステートメントに達すると、トランザクションが終了します。これらのステートメントのいずれかに到達する前にスクリプトが終了すると、自動ロールバックが発生します。

BigQuery のトランザクションの詳細については、マルチステートメント トランザクションをご覧ください。

次の例では、既存のテーブルから一時テーブルに行を選択し、これらの行を元のテーブルから削除して一時テーブルを別のテーブルに統合するトランザクションを実行します。

BEGIN TRANSACTION;

-- Create a temporary table of new arrivals from warehouse #1
CREATE TEMP TABLE tmp AS
SELECT * FROM mydataset.NewArrivals WHERE warehouse = 'warehouse #1';

-- Delete the matching records from the original table.
DELETE mydataset.NewArrivals WHERE warehouse = 'warehouse #1';

-- Merge the matching records into the Inventory table.
MERGE mydataset.Inventory AS I
USING tmp AS T
ON I.product = T.product
WHEN NOT MATCHED THEN
 INSERT(product, quantity, supply_constrained)
 VALUES(product, quantity, false)
WHEN MATCHED THEN
 UPDATE SET quantity = I.quantity + T.quantity;

DROP TABLE tmp;

COMMIT TRANSACTION;

COMMIT TRANSACTION

構文

COMMIT [TRANSACTION];

説明

オープン トランザクションを commit します。進行中のトランザクションがない場合、ステートメントは失敗します。

BigQuery のトランザクションの詳細については、マルチステートメント トランザクションをご覧ください。

BEGIN TRANSACTION;

-- SQL statements for the transaction go here.

COMMIT TRANSACTION;

ROLLBACK TRANSACTION

構文

ROLLBACK [TRANSACTION];

説明

オープン トランザクションをロールバックします。進行中のトランザクションがない場合、ステートメントは失敗します。

BigQuery のトランザクションの詳細については、マルチステートメント トランザクションをご覧ください。

次の例では、トランザクションでエラーが発生した場合にトランザクションをロールバックします。ロジックを説明するために、テーブルに行を挿入した後にゼロ除算エラーをトリガーします。これらのステートメントが実行されても、テーブルは影響を受けません。

BEGIN

  BEGIN TRANSACTION;
  INSERT INTO mydataset.NewArrivals
    VALUES ('top load washer', 100, 'warehouse #1');
  -- Trigger an error.
  SELECT 1/0;
  COMMIT TRANSACTION;

EXCEPTION WHEN ERROR THEN
  -- Roll back the transaction inside the exception handler.
  SELECT @@error.message;
  ROLLBACK TRANSACTION;
END;

RAISE

構文

RAISE [USING MESSAGE = message];

説明

USING MESSAGE = message が指定されると、必要に応じて特定のエラー メッセージを使用して、エラーを発生させます。

USING MESSAGE が指定されていない場合

RAISE ステートメントは EXCEPTION 句内でのみ使用する必要があります。RAISE ステートメントは検出された例外を再生成し、元のスタック トレースを保持します。

USING MESSAGE が指定されている場合

RAISE ステートメントが BEGIN...EXCEPTION ブロックの BEGIN セクションに含まれている場合、次のようになります。

  • ハンドラが呼び出されます。
  • @@error.message の値は、指定された message 文字列(messageNULL の場合は NULL になる可能性があります)と完全に一致します。

  • スタック トレースは、RAISE ステートメントに設定されます。

RAISE ステートメントが BEGIN...EXCEPTION ブロックの BEGIN セクションに含まれていない場合、RAISE ステートメントは指定したエラー メッセージを表示し、スクリプトの実行を停止します。

RETURN

BigQuery スクリプトでは、RETURN は現在のスクリプトの実行を停止します。

CALL

構文

CALL procedure_name (procedure_argument[, …])

説明

引数リストとともにプロシージャを呼び出します。procedure_argument は、変数または式とすることが可能です。OUT 引数または INOUT 引数は、引数として渡される変数ごとに適切な BigQuery のタイプが指定される必要があります。

同じ変数を、プロシージャの引数リストに OUT 引数または INOUT 引数として複数回指定することはできません。

プロシージャ呼び出しの最大深度は 50 フレームです。

CALL は、ネストされた要素として動的に実行されません。つまり、EXECUTE IMMEDIATE ステートメントに CALL をネストすることはできません。

次の例では、変数 retCode を宣言しています。次に、引数 'someAccountId'retCode を渡し、データセット myDataset 内でプロシージャ updateSomeTables を呼び出します。最後に、retCode の値を返します。

DECLARE retCode INT64;
-- Procedure signature: (IN account_id STRING, OUT retCode INT64)
CALL myDataset.UpdateSomeTables('someAccountId', retCode);
SELECT retCode;

システム変数

システム変数を使用して、スクリプトの実行中に情報を確認できます。

名前 説明
@@current_job_id STRING (読み取り専用)現在実行中のジョブのジョブ ID。スクリプトのコンテキストでは、スクリプト全体ではなく、現在のステートメントを処理するジョブが返されます。
@@dataset_id STRING 現在のプロジェクト内にあるデフォルト データセットの ID。クエリでプロジェクトにデータセットが指定されていない場合に使用されます。SET ステートメントを使用して、現在のプロジェクト内の別のデータセット ID に @@dataset_id を割り当てることができます。
@@last_job_id STRING (読み取り専用)現在のスクリプトで実行された最新のジョブのジョブ ID。現在のジョブは含まれません。スクリプトに CALL ステートメントが含まれている場合、このジョブは別のプロシージャで作成された可能性があります。
@@project_id STRING (読み取り専用)現在のクエリを実行するために使用されるプロジェクトの ID。プロシージャのコンテキストでは、@@project_id はプロシージャを所有するプロジェクトではなく、スクリプトを実行しているプロジェクトを指します。
@@row_count INT64 (読み取り専用)スクリプトで使用され、前のスクリプト文が DML の場合、その DML ステートメントの結果として変更、挿入、または削除された行数を指定します。前のステートメントが MERGE ステートメントの場合、@@row_count は挿入、削除された合計行数を表します。スクリプト内にない場合、この値は NULL になります。
@@script.bytes_billed INT64 (読み取り専用)現在実行中のスクリプト ジョブでこれまでに請求された合計バイト数。スクリプト内にない場合、この値は NULL になります。
@@script.bytes_processed INT64 (読み取り専用)現在実行中のスクリプト ジョブでこれまでに処理された合計バイト数。スクリプト内にない場合、この値は NULL になります。
@@script.creation_time TIMESTAMP (読み取り専用)現在実行中のスクリプト ジョブの作成時刻。スクリプト内にない場合、この値は NULL になります。
@@script.job_id STRING (読み取り専用)現在実行中のスクリプト ジョブのジョブ ID。スクリプト内にない場合、この値は NULL になります。
@@script.num_child_jobs INT64 (読み取り専用)現在完了している子ジョブの数。スクリプト内にない場合、この値は NULL になります。
@@script.slot_ms INT64 (読み取り専用)スクリプトがそれまでに使用したスロットのミリ秒数。スクリプト内にない場合、この値は NULL になります。
@@time_zone STRING タイムゾーンが引数として指定されていない場合に、タイムゾーンに依存する SQL 関数で使用するデフォルトのタイムゾーン。@@time_zone は、SET ステートメントを使用して任意の有効なタイムゾーン名に変更できます。各スクリプトの先頭で、@@time_zone は「UTC」で始まります。

上記のシステム変数に加えて、スクリプト実行中に EXCEPTION システム変数を使用できます。例外ハンドラで使用されない場合、EXCEPTION システム変数は NULL になります。以下は EXCEPTION システム変数です。

  • @@error.formatted_stack_trace
  • @@error.message
  • @@error.stack_trace
  • @@error.statement_text

EXCEPTION システム変数の詳細については、BEGIN...EXCEPTION をご覧ください。

システム プロシージャ

BigQuery は、次のシステム プロシージャをサポートしています。

BQ.JOBS.CANCEL

構文

CALL BQ.JOBS.CANCEL(job);

Description

実行中のジョブをキャンセルします。

ジョブを '[project_id.]job_id' 形式の文字列として指定します。このシステム プロシージャをジョブとは異なるプロジェクトから実行する場合は、プロジェクト ID を含める必要があります。このプロシージャは、ジョブと同じリージョンで実行する必要があります。

詳細については、ジョブをキャンセルするをご覧ください。

BQ.REFRESH_MATERIALIZED_VIEW

構文

CALL BQ.REFRESH_MATERIALIZED_VIEW(view_name);

Description

マテリアライズド ビューを更新します。

マテリアライズド ビューの名前を '[project_id.]dataset.table' 形式の文字列として指定します。マテリアライズド ビューとは異なるプロジェクトからこのシステム プロシージャを実行する場合は、プロジェクト ID を含める必要があります。

詳細については、手動更新をご覧ください。

権限

テーブル、モデル、その他のリソースへのアクセス権は、実行時にチェックされます。ステートメントが実行されない場合、または式が評価されない場合、BigQuery は、スクリプトを実行するユーザーが参照しているリソースにアクセスできるかどうかをチェックしません。

スクリプト内で、各式またはステートメントの権限は別々に検証されます。たとえば、次のスクリプトについて考えてみます。

SELECT * FROM dataset_with_access.table1;
SELECT * FROM dataset_without_access.table2;

スクリプトを実行するユーザーに table1 へのアクセス権があるが、table2 へのアクセス権がない場合、最初のクエリは成功し、2 番目のクエリは失敗します。スクリプト ジョブ自体も失敗します。

セキュリティの制約

動的 SQL は便利ですが、不正使用の可能性が高まります。たとえば、次のクエリを実行すると、テーブル パラメータが不適切にフィルタリングされ、意図しないテーブルにアクセスして実行される可能性があるため、セキュリティ上の脅威となりえます。

EXECUTE IMMEDIATE CONCAT(‘SELECT * FROM ’, @employee_table);

テーブル内の機密データの公開や漏洩しないために、あるいは DROP TABLE などのコマンドを実行してテーブル内のデータを削除しないようにするために、BigQuery の動的 SQL スクリプトは、SQL インジェクション攻撃への露出を減らすための複数のセキュリティ対策をサポートしています。

  • 動的 SQL に渡されたパラメータに埋め込まれた複数の SQL ステートメントを実行することはできません。
  • 次のコマンドは動的に実行されません。BEGIN / ENDCALLIFLOOPWHILEEXECUTE IMMEDIATE

構成フィールドの制限

次のクエリ構成フィールドはスクリプト用に設定できません:

  • clustering
  • create_disposition
  • destination_table
  • destination_encryption_configuration
  • range_partitioning
  • schema_update_options
  • time_partitioning
  • user_defined_function_resources
  • write_disposition