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

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

このトピックの内容:

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

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

リクエストの設定

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

注釈

コードは、非同期クエリの実行を処理できる必要があります。明示的な:codenowrap:async=true プロパティを指定しない場合、クエリが常に同期的に実行されるという保証はありません。詳細については、応答ワークフロー をご参照ください。

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

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

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

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

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

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

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

    これらのフィールドの値は大文字と小文字が区別され、SQL SHOW コマンドによって返されるフィールドの大文字と小文字に一致する必要があります。たとえば、次の SQL コマンドを使用してデータベースを作成するとします。

    CREATE OR REPLACE DATABASE Xpto; 
    Copy

    この例では、:doc:` オブジェクト識別子が引用符で囲まれていないため、デフォルトで大文字として作成されます </sql-reference/identifiers-syntax>`。

    SHOW DATABASES コマンドがデータベース名として大文字の XPTO を返す場合、フィールド値として大文字の XPTO を指定する必要があります。

    これらのフィールドを省略すると、 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" \  -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 バインド型を使用します。

次の表は、様々な:doc:Snowflakeデータ型 </sql-reference-data-types> にバインドするために使用できる 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 ステートメントの処理にオーバーヘッドを追加します。このパラメーターは、ステートメントの再試行が必要な場合にのみ使用します。