SQL ステートメントの実行リクエストの送信

このトピックでは、 SQL API にリクエストを送信する方法について説明します。

このトピックの内容:

実行のために SQL ステートメントを送信するには、 /api/v2/statements/ リクエストを POST エンドポイントに送信します。詳細については POST /api/v2/statements をご参照ください。

POST /api/v2/statements HTTP/1.1
(request body)
Copy

リクエストの設定

リクエスト URL では、クエリパラメーターを次のように設定できます。

リクエストの本文 には、次のフィールドを設定します。

  • 実行する SQL ステートメントに statement フィールドを設定します。例:

    {
      "statement": "select * from my_table",
      ...
    }
    
    Copy

    単一リクエストで複数のステートメントを送信する場合は、ステートメントの間にセミコロン(;)を使用します。詳細については 単一リクエストによる複数の SQL ステートメントの送信 をご参照ください。

  • ステートメントにバインド変数(? プレースホルダー)を含める場合は、各変数に対応するSnowflakeデータ型と値を指定するオブジェクトに bindings フィールドを設定します。

    詳細については、 ステートメントでのバインド変数の使用 をご参照ください。

  • 使用するウェアハウス、データベース、スキーマ、およびロールを指定するには、 warehousedatabaseschema、および role フィールドを設定します。

    これらのフィールドの値では、大文字と小文字が区別されます。

    これらのフィールドを省略すると、 SQL API はユーザーに対応するプロパティの値(つまり、 DEFAULT_WAREHOUSEDEFAULT_NAMESPACE、および DEFAULT_ROLE ユーザープロパティ)を使用します。

  • ステートメント実行のタイムアウトを設定するには、 timeout フィールドを待機する最大秒数に設定します。 timeout フィールドが設定されていない場合は、 STATEMENT_TIMEOUT_IN_SECONDS パラメーターで指定されたタイムアウトが使用されます。

リクエストの例

たとえば、次の curl コマンドは、実行のために SQL ステートメントを送信します。この例では、ファイル request-body.json を使用してリクエストの本文を指定しています。

curl -i -X POST \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer <jwt>" \
    -H "Accept: application/json" \
    -H "User-Agent: myApplicationName/1.0" \
    -H "X-Snowflake-Authorization-Token-Type: KEYPAIR_JWT" \
    -d "@request-body.json" \
    "https://<account_identifier>.snowflakecomputing.com/api/v2/statements"
Copy

条件:

この例では、 request-body.jsonリクエストの本文 が含まれています。

{
  "statement": "select * from T where c1=?",
  "timeout": 60,
  "database": "TESTDB",
  "schema": "TESTSCHEMA",
  "warehouse": "TESTWH",
  "role": "TESTROLE",
  "bindings": {
    "1": {
      "type": "FIXED",
      "value": "123"
    }
  }
}
Copy

上記の例にあるリクエストの本文で、

  • statement フィールドは、実行する SQL ステートメントを指定します。

    このステートメントには、 バインド変数"cl=?" の疑問符)が含まれています。これは、 bindings フィールドで指定された最初のバインド("1")に評価されます。

  • timeout フィールドは、サーバーがステートメントの実行に60秒許可することを指定します。

  • databaseschemawarehouse、および role フィールドは、ステートメントの実行時に TESTDB データベース、 TESTSCHEMA スキーマ、 TESTWH ウェアハウス、および TESTROLE ロールを使用することを指定します。

ステートメントでのバインド変数の使用

ステートメントでバインド変数(? プレースホルダー)を使用する場合は、 bindings フィールドを使用して、挿入する値を指定します。

このフィールドは、各バインド変数の Snowflakeデータ型 と値を指定する JSON オブジェクトに設定します。

...
"statement": "select * from T where c1=?",
...
"bindings": {
  "1": {
    "type": "FIXED",
    "value": "123"
  }
},
...
Copy

バインドする値の型に対応するバインド型を選択します。たとえば、値が日付(例: 2021-04-15)を表す 文字列 であり、その値を DATE 列に挿入する場合は、 TEXT バインド型を使用します。

次の表は、このプレビューリリースのさまざまな Snowflakeデータ型 にバインドするために使用できる type フィールドの値を示しています。

  • 左の最初の列は、使用できるバインド型を示しています。

  • 残りの列は、データを挿入する予定の列のSnowflakeデータ型を指定します。

  • 各セルは、特定のSnowflakeデータ型の列にデータを挿入する際にバインド型で使用できる値の型を指定します。

    バインド型とSnowflakeデータ型のセルが空の場合は、指定されたバインド型を使用して、そのSnowflakeデータ型の列にデータを挿入することはできません。

さまざまなSnowflakeデータ型でサポートされているバインド型

Snowflakeデータ型

INT / NUMBER

FLOAT

VARCHAR

BINARY

BOOLEAN

DATE

TIME

TIMESTAMP_TZ

TIMESTAMP_LTZ

TIMESTAMP_NTZ

. 型のバインド

FIXED

整数

整数

整数

0(false)/0以外(true)

REAL

整数

整数または浮動小数点数

整数または浮動小数点数

0/0以外

TEXT

整数

整数または浮動小数点数

任意のテキスト

16進数

"true" / "false"

以下のメモを参照

以下のメモを参照

以下のメモを参照

以下のメモを参照

以下のメモを参照

BINARY

16進数

BOOLEAN

true/false、0/1

true/false

DATE

エポック(ミリ秒)

エポック(ミリ秒)

エポック(ミリ秒)

エポック(ミリ秒)

エポック(ミリ秒)

TIME

エポック(ナノ)

エポック(ナノ)

TIMESTAMP_TZ

エポック(ナノ)

エポック(ナノ)

エポック(ナノ)

エポック(ナノ)

TIMESTAMP_LTZ

エポック(ナノ)

エポック(ナノ)

エポック(ナノ)

エポック(ナノ)

エポック(ナノ)

エポック(ナノ)

TIMESTAMP_NTZ

エポック(ナノ)

エポック(ナノ)

エポック(ナノ)

エポック(ナノ)

エポック(ナノ)

エポック(ナノ)

次の点に注意してください。

  • バインド変数の値は文字列である必要があります(たとえば、値 1.0 の場合は "1.0")。

  • DATE バインド型を使用する場合は、エポック以降の ミリ秒 の数を指定します。

  • TIME または TIMESTAMP* バインド型を使用する場合は、エポック以降の ナノ秒 の数を指定します。

  • TIMESTAMP_TZ バインド型を使用する場合は、エポック以降の ナノ秒 の数を指定し、その後にスペースと分単位のタイムゾーンオフセットを指定します(例: 1616173619000000000 960)。

  • TEXT バインド型を使用する場合は、

    • DATE 列にデータを挿入するには、 AUTO 検出でサポートされている任意の 日付形式 を使用できます。

    • TIME 列にデータを挿入するには、 AUTO 検出でサポートされている任意の 時間形式 を使用できます。

    • TIMEZONE* 列にデータを挿入するには、 AUTO 検出でサポートされている任意の 日時形式 を使用できます。

値がSnowflakeでサポートされていない形式の場合、 API はエラーを返します。

{
  code: "100037",
  message: "<bind type> value '<value>' is not recognized",
  sqlState: "22018",
  statementHandle: "<ID>"
}
Copy

注釈

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

同時リクエストの送信

Snowflake SQL API は、サーバーへの同時リクエストの送信をサポートしています。API の同時実行制限は、Snowflakeによって適用される同時実行制限によって決定されます。

現在のサーバーの負荷によっては、サーバーが現在受信しているリクエストが多すぎることを示す HTTP 429エラーが表示される場合があります。

アプリケーションが429エラーを正しく処理するようにするには、同時リクエストを再試行ロジック内でラップします。

SQL ステートメントの実行リクエストの再送信

場合によっては、Snowflakeが API リクエストで SQL ステートメントを実行したかどうかが明確ではない場合があります(例: ネットワークエラーまたはタイムアウトのため)。Snowflakeがステートメントを実行しなかった場合に備えて、Snowflakeに対して同じリクエストを再送信するように選択できます。

しかし、Snowflakeが最初のリクエストでステートメントをすでに実行している場合にリクエストを再送信すると、ステートメントが2回実行されます。一部のタイプのリクエストでは、同じステートメントを繰り返し実行すると、意図しない結果が生じる可能性があります(例: 重複データをテーブルに挿入)。

リクエストを再送信するときにSnowflakeが同じステートメントを2回実行しないようにするには、リクエスト ID を使用してリクエストを他のリクエストと区別します。再送信されたリクエストで、最初のリクエストと同じリクエスト ID と retry=true パラメーターを合わせて指定すると、ステートメントがすでに正常に実行されている場合、Snowflakeはステートメントを再度実行しません。

リクエスト ID を指定するには、 ユニバーサル一意識別子(UUID) を生成します。次に、この識別子を requestId クエリパラメーターに含めます。次の例に示すように、リクエストの一部として retry=true パラメーターも指定する必要があります。

POST /api/v2/statements?requestId=ea7b46ed-bdc1-8c32-d593-764fcad64e83&retry=true HTTP/1.1
Copy

Snowflakeがリクエストの処理に失敗した場合は、同じリクエスト ID で同じリクエストを再送信できます。同じリクエスト ID を使用することにより、同じリクエストを再送信することをサーバーに示します。

注釈

Snowflakeはステートメント履歴内のステートメントをスキャンして照合する必要があるため、 retry=true パラメーターは SQL ステートメントの処理にオーバーヘッドを追加します。このパラメーターは、ステートメントの再試行が必要な場合にのみ使用します。