バインド変数

アプリケーションはユーザーからデータを受け取り、SQL ステートメントでそのデータを使用できます。たとえば、アプリケーションがユーザーに住所や電話番号などの連絡先情報の入力を求める場合があります。

このユーザー入力を SQL ステートメントで指定するには、ユーザー入力をステートメントの他の部分と連結して SQL ステートメントの文字列をプログラムで作成します。あるいは、 バインド変数 を使うこともできます。変数をバインドするには、 SQL ステートメントのテキストに1つ以上のプレースホルダーを配置し、各プレースホルダーに変数(使用する値)を指定します。

バインド変数の概要

バインド変数を使うと、SQL ステートメントのリテラルをプレースホルダーに置き換えることができます。たとえば、次の SQL ステートメントでは、挿入値にリテラルを使用しています。

INSERT INTO t (c1, c2) VALUES (1, 'Test string');
Copy

次の SQL ステートメントでは、挿入値にプレースホルダーを使用しています。

INSERT INTO t (c1, c2) VALUES (?, ?);
Copy

アプリケーションコードは、SQL ステートメント内の各プレースホルダーとデータをバインドします。プレースホルダーでデータをバインドする手法は、プログラミング言語によって異なります。プレースホルダーの構文もプログラミング言語によって異なります。 ?:varname、または %varname のどちらかになります。

Javascriptストアドプロシージャでのバインド変数の使用

Javascript を使用して、 SQL を実行するストアドプロシージャを作成できます。

Javascriptコードでバインド変数を指定するには、 ? プレースホルダーを使用します。たとえば、次の INSERT ステートメントは、テーブル行に挿入される値のバインド変数を指定します。

INSERT INTO t (col1, col2) VALUES (?, ?)
Copy

Javascriptコードでは、大半の SQL ステートメントの値にバインド変数を使うことができます。制限に関する情報については、 バインド変数の制限事項 をご参照ください。

Javascriptでのバインド変数の使用に関する詳細情報については、 変数のバインド をご参照ください。

Snowflakeスクリプトでのバインド変数の使用

Snowflake Scripting を使用して、コードブロックやストアドプロシージャなどの SQL を実行する手続き型コードを作成できます。Snowflake Scriptingコードでバインド変数を指定するには、変数名のプレフィックスにコロンを付けます。たとえば、次の INSERT ステートメントは variable1 という名前のバインド変数を指定します。

INSERT INTO t (c1) VALUES (:variable1)
Copy

Snowflake Scriptingコードでは、大半の SQL ステートメントの値にバインド変数を使用できます。制限に関する情報については、 バインド変数の制限事項 をご参照ください。

Snowflake Scriptingでのバインド変数の使用に関する詳細については、 SQL ステートメントでの変数の使用(バインド) および SQL ステートメントでの引数の使用(バインド) をご参照ください。

SQLAPI でのバインド変数の使用

Snowflake SQL API を使用して、Snowflakeデータベースのデータにアクセスして更新することができます。SQLAPI を使用するアプリケーションを作成して、 SQL ステートメントを送信し、展開を管理することができます。

SQL ステートメントを実行するリクエストを送信する場合、ステートメント内の値にバインド変数を使用できます。詳細については、 ステートメントでのバインド変数の使用 をご参照ください。

ドライバーでのバインド変数の使用

Snowflake ドライバー を使用すると、Snowflake上で操作を実行するアプリケーションを記述できます。ドライバーはGo、Java、Pythonなどのプログラミング言語をサポートしています。特定のドライバーのアプリケーションでバインド変数を使用する方法については、そのドライバーのリンクからご覧ください。

注釈

PHP ドライバーはバインド変数をサポートしていません。

バインド変数と値の配列の使用

SQL ステートメントでは、値の配列を変数にバインドできます。この手法を使用すると、1つのバッチで複数行を挿入することで、ネットワークのラウンドトリップやコンパイルを回避し、パフォーマンスを向上させることができます。配列バインドの使用は、「バルクインサート」または「バッチインサート」とも呼ばれます。

注釈

Snowflakeは、配列バインドの使用の代わりに推奨される他のデータロード方法をサポートしています。詳細については、 Snowflakeにデータをロード および データのロードおよびアンロードコマンド をご参照ください。

以下は、Pythonコードでの配列バインドの例です。

conn = snowflake.connector.connect( ... )
rows_to_insert = [('milk', 2), ('apple', 3), ('egg', 2)]
conn.cursor().executemany(
            "insert into grocery (item, quantity) values (?, ?)",
            rows_to_insert)
Copy

この例では、次のバインドリストを指定します: [('milk', 2), ('apple', 3), ('egg', 2)]。アプリケーションがバインドリストを指定する方法は、プログラミング言語によって異なります。

このコードは、テーブルに3行を挿入します。

+-------+----+
| C1    | C2 |
|-------+----|
| milk  |  2 |
| apple |  3 |
| egg   |  2 |
+-------+----+

特定のドライバーのアプリケーションで配列バインドを使用する方法については、そのドライバーのリンクからご覧ください。

注釈

PHP ドライバーは配列バインドをサポートしていません。

配列バインドの使用の制限事項

配列バインドには、次の制限が適用されます。

  • 配列バインド変数を含むことができるのは INSERT INTO... VALUES ステートメントだけです。

  • VALUES 句は、バインド変数の単一行リストでなければなりません。たとえば、次の VALUES 句は許可されていません。

    VALUES (?,?), (?,?)
    
    Copy

配列バインドを使用しない複数行の挿入

INSERT ステートメントでは、バインド変数を使用して、配列バインドを使用せずに複数行を挿入することができます。次の例では、2つの行に値を挿入していますが、配列バインドは使用していません。

INSERT INTO t VALUES (?,?), (?,?);
Copy

たとえば、アプリケーションは、プレースホルダーに値 [1,'String1',2,'String2'] を順番に並べたものと等しいバインドリストを指定することができます。VALUES 句は複数行を指定するので、ステートメントは動的な行数ではなく、正確な値の数(例では4つ)のみを挿入します。

半構造化データでのバインド変数の使用

半構造化データを変数にバインドするには、変数を文字列型としてバインドし、 PARSE_JSONARRAY_CONSTRUCT のような関数を使用します。

次の例では、 VARIANT 列を1つ持つテーブルを作成し、 PARSE_JSON 関数を呼び出してバインド変数で半構造化データをテーブルに挿入します。

CREATE TABLE t (a VARIANT);
-- Code that supplies a bind value for ? of '{'a': 'abc', 'x': 'xyz'}'
INSERT INTO t SELECT PARSE_JSON(a) FROM VALUES (?);
Copy

次の例では、テーブルにクエリを行います。

SELECT * FROM t;
Copy

クエリは次の出力を返します。

+---------------+
| A             |
|---------------|
| {             |
|   "a": "abc", |
|   "x": "xyz"  |
| }             |
+---------------+

次のステートメントは、 ARRAY_CONSTRUCT 関数を呼び出して、バインド変数を持つ VARIANT 列に半構造化データの配列を挿入します。

INSERT INTO t SELECT ARRAY_CONSTRUCT(column1) FROM VALUES (?);
Copy

これらの例はどちらも単一行を挿入することができますが、配列バインドを使用して複数行を1つのバッチで挿入することもできます。この手法を使って、 VARIANT 列に有効な任意のタイプの半構造化データを挿入することができます。

バインド変数の制限事項

バインド変数には以下の制限があります。

  • SELECT ステートメントの制限。

    • バインド変数により、データ型定義(例: NUMBER(?))や 照合順序指定 (例: COLLATE ?)の一部である数値を置き換えることはできません。

    • バインド変数は、ステージ上のファイルをクエリする SELECT ステートメントのソースには使用できません。

  • DDL コマンドの制限事項。

    • バインド変数は、以下の DDL コマンドでは使用できません。

      • CREATE/ALTER INTEGRATION

      • CREATE/ALTER REPLICATION GROUP

      • CREATE/ALTER PIPE

      • CREATE TABLE ... USING TEMPLATE

    • バインド変数は、以下の句では使用できません。

      • ALTER COLUMN

      • COMMENT ON CONSTRAINT

    • CREATE/ALTER コマンドでは、以下のパラメーターの値にバインド変数を使用することはできません。

      • CREDENTIALS

      • DIRECTORY

      • ENCRYPTION

      • IMPORTS

      • PACKAGES

      • REFRESH

      • TAG

      • 外部テーブル固有のパラメーター

    • バインド変数は、 FILE FORMAT 値の一部であるプロパティには使用できません。

  • COPY INTO コマンドでは、バインド変数は以下のパラメーターの値には使用できません。

    • CREDENTIALS

    • ENCRYPTION

    • FILE_FORMAT

  • SHOW コマンドでは、バインド変数は以下のパラメーターでは使用できません。

    • LIKE

    • LIMIT

    • STARTS WITH

  • バインド変数は、 EXECUTE IMMEDIATE FROM コマンドでは使用できません。

  • 以下でバインド変数を使用する場合、バインド変数の値はあるデータ型から別のデータ型に自動では変換されません。

    • データ型を明示的に指定するSnowflake Scriptingコード

    • DDL ステートメント

    • ステージ名

バインド変数のセキュリティに関する考慮事項

バインド変数は、すべてのケースで機密データをマスキングするわけではありません。たとえば、バインド変数の値はエラーメッセージやその他のアーティファクトに表示される可能性があります。

バインド変数は、 SQL ステートメントをユーザー入力で作成する際に、 SQL インジェクション攻撃を防ぐのに役立ちます。しかし、バインド変数には潜在的なセキュリティリスクがあります。SQL ステートメントへのインプットが外部ソースからのものである場合、それらが検証済みであることを確認します。詳細については、 SQL インジェクション をご参照ください。