単一リクエストによる複数の SQL ステートメントの送信

このトピックでは、複数のステートメントを含むリクエストをSnowflake SQL API に送信する方法について説明します。

このトピックの内容:

紹介

場合によっては、リクエストで複数の SQL ステートメントを指定する必要があります。たとえば、次が必要になる場合があります。

  • 明示的なトランザクションを定義する

  • リクエストのステートメントでセッション変数を設定して使用する

  • リクエストのステートメントで仮テーブルを作成して使用する

  • リクエスト内のステートメントのデータベース、スキーマ、ウェアハウス、またはロールを変更する

次のセクションでは、複数の SQL ステートメントを含むリクエストを送信する方法について説明します。

リクエストでの複数の SQL ステートメントの指定

単一リクエストで複数の SQL ステートメントを送信するには、

  • statement フィールドで、各ステートメントの間にセミコロン(;)を使用します。

  • parameters フィールドで、 MULTI_STATEMENT_COUNT フィールドをリクエスト内の SQL ステートメントの数に設定します。

例:

POST /api/v2/statements HTTP/1.1
Authorization: Bearer <jwt>
Content-Type: application/json
Accept: application/json
User-Agent: myApplication/1.0
X-Snowflake-Authorization-Token-Type: KEYPAIR_JWT

{
  "statement": "alter session set QUERY_TAG='mytesttag'; select count(*) from mytable",
  ...
  "parameters": {
      "MULTI_STATEMENT_COUNT": "2"
  }
}
Copy

この例では、 MULTI_STATEMENT_COUNT2 に設定されています。これは、送信される SQL ステートメントの数に対応します。

statement フィールドに可変数の SQL ステートメントを送信するには、 MULTI_STATEMENT_COUNT0 に設定します。これは、送信された SQL ステートメントの数が実行時にわからないアプリケーションで役立ちます。

MULTI_STATEMENT_COUNT の値が statement フィールドで指定された SQL ステートメントの数と一致しない場合、 SQL API は次のエラーを返します。

Actual statement count <actual_count> did not match the desired statement count <desired_count>.
Copy

条件

  • actual_count は、 statement フィールドで指定されたステートメントの数です。

  • desired_countMULTI_STATEMENT_COUNT の値です。

statement フィールドに複数の SQL ステートメントを指定したが、 MULTI_STATEMENT_COUNT フィールドを指定しなかった場合、 SQL API は次のエラーを返します。

Actual statement count 3 did not match the desired statement count 1.
Copy

注釈

Snowflakeは現在、マルチステートメント SQL リクエストでの変数バインドをサポートしていません。

リクエストでの各 SQL ステートメントの結果の取得

複数の SQL ステートメントを含むリクエストが正常に処理された場合、応答には個々のステートメントの実行から返されたデータは含まれません。代わりに、応答には、個別ステートメントのハンドルの配列を含む statementHandles フィールドが含まれています。

注釈

statementHandles フィールドは statementHandle フィールドとは異なります。

  • statementHandle フィールドは、リクエストにある SQL のセットに対するステートメントのハンドルを指定します。

  • statementHandles フィールドは、リクエストにある個別 SQL ステートメントのハンドルの配列です。

たとえば、実行のために2つの SQL ステートメントを指定するリクエストを送信するとします。

POST /api/v2/statements HTTP/1.1
Authorization: Bearer <jwt>
Content-Type: application/json
Accept: application/json
User-Agent: myApplication/1.0
X-Snowflake-Authorization-Token-Type: KEYPAIR_JWT

{
  "statement": "select * from A; select * from B",
  ...
}
Copy

応答には、個別ステートメントのハンドルの配列を含む statementHandles フィールドが含まれています。

HTTP/1.1 200 OK
...
{
  ...
  "statementHandles" : [ "019c9fce-0502-f1fc-0000-438300e02412", "019c9fce-0502-f1fc-0000-438300e02416" ],
  ...
}
Copy

ステータスを確認して個々のステートメントのデータを取得するには、 GET リクエストを /api/v2/statements/ エンドポイントに送信し、各ステートメントのハンドルを URL パスに追加します。詳細については ステートメントの実行ステータスの確認およびデータの取得 をご参照ください。

GET /api/v2/statements/019c9fce-0502-f1fc-0000-438300e02412
...
Copy
GET /api/v2/statements/019c9fce-0502-f1fc-0000-438300e02416
...
Copy

リクエストで複数のステートメントを指定する際のエラーの処理

リクエストで複数の SQL ステートメントを指定し、いずれかのステートメントの実行中にエラーが発生した場合、Snowflakeは QueryFailureStatus オブジェクトを含む HTTP 応答コード422を返します。

このオブジェクトから、 エラーに関する詳細 を取得できます。

たとえば、リクエストで次のステートメントが指定されていて、2番目の INSERT ステートメントにエラーが含まれているとします。

{
  "statement": "create or replace table table1 (i int); insert into table1 (i) values (1); insert into table1 (i) values ('This is not a valid integer.'); insert into table1 (i) values (2); select i from table1 order by i",
  ...
}
Copy

Snowflakeは、 HTTP 応答コード422と、エラーに関する詳細を含む QueryFailureStatus オブジェクトのある応答を返します。

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
...
{
  "code" : "100132",
  "message" : "JavaScript execution error: Uncaught Execution of multiple statements failed on statement \"insert into table1 (i) values ...\" (at line 1, position 75).\nNumeric value 'This is not a valid integer.' is not recognized in SYSTEM$MULTISTMT at '    throw `Execution of multiple statements failed on statement {0} (at line {1}, position {2}).`.replace('{1}', LINES[i])' position 4\nstackstrace: \nSYSTEM$MULTISTMT line: 10",
  "sqlState" : "P0000",
  "statementHandle" : "019d6e97-0502-317e-0000-096d0041f036"
}
Copy

上記の例では、エラーのある INSERT ステートメントは、 statement フィールドの の文字位置75から始まります。

エラーのあるステートメントの前のステートメントは正常に実行されます(この例では CREATE TABLE および最初の INSERT ステートメント)。エラーのあるステートメントの後のステートメントは実行されません。