ODBC ドライバーの使用

このトピックでは、 ODBC ドライバーの使用方法に関する情報を提供します。

このトピックの内容:

コードのコンパイル

Linux

  • Snowflake ODBC ドライバーライブラリを使用してC/C++アプリケーションを構築し、pthread非互換ライブラリをロードすると、共有メモリへの安全でない同時アクセスが原因でアプリケーションがクラッシュする可能性があります。これを防ぐには、pthread互換ライブラリのみがアプリケーションとともにロードされるようにするオプションを使用して、アプリケーションをコンパイルします。

    gcc/g++の場合、オプションは「-pthread」です。

macOS

  • Snowflake ODBC ドライバーライブラリを使用してC/C++アプリケーションを構築し、pthread非互換ライブラリをロードすると、共有メモリへの安全でない同時アクセスが原因でアプリケーションがクラッシュする可能性があります。これを防ぐには、pthread互換ライブラリのみがアプリケーションとともにロードされるようにするオプションを使用して、アプリケーションをコンパイルします。

    clang/clang++の場合、オプションは「-pthread」です。

SQL ステートメントのバッチの実行(複数ステートメントのサポート)

ODBC では、 SQL ステートメントのバッチ(セミコロンによる区切り) を送信できます。例:

// Sending a batch of SQL statements to be executed
rc = SQLExecDirect(hstmt,
     (SQLCHAR *) "select c1 from t1; select c2 from t2; select c3 from t3",
     SQL_NTS);

Snowflake ODBC ドライバーでステートメントのバッチを送信するには、バッチ内のステートメントの数を指定する必要があります。Snowflakeデータベースでは、 SQLインジェクション 攻撃を防ぐために、正確な数のステートメントが必要です。

次のセクションでは、バッチ内のステートメントの数を指定する方法について説明します。

バッチ内のステートメント数の指定

デフォルトでは、Snowflakeデータベースは、ドライバーが実行のために単一のステートメントを準備して送信することを期待しています。

これを上書きするには、特定のリクエストに対してバッチ内のステートメント数を指定するか、現在のセッションまたはアカウントに対して複数のステートメントを有効にします。

  • 特定のリクエストの数を指定するには、 SqlSetStmtAttr を呼び出して、 SQL_SF_STMT_ATTR_MULTI_STATEMENT_COUNT 属性をバッチ内のステートメントの数に設定します。

    // Specify that you want to execute a batch of 3 SQL statements
    rc = SQLSetStmtAttr(hstmt, SQL_SF_STMT_ATTR_MULTI_STATEMENT_COUNT, (SQLPOINTER)3, 0);
    

    リクエストの数を指定するのではなく、現在のセッションまたはアカウントの設定を使用する場合は、 SQL_SF_STMT_ATTR_MULTI_STATEMENT_COUNT-1 に設定します。

  • 現在のセッションまたはアカウントで複数のステートメントを有効にするには、セッションまたはアカウントを変更し、Snowflake MULTI_STATEMENT_COUNT パラメーターを 0 に設定します。

    -- Specify that you want to execute batches of multiple SQL statements
    -- for the current session.
    alter session set MULTI_STATEMENT_COUNT = 0;
    
     -- Specify that you want to execute batches of multiple SQL statements
     -- for the current account.
    alter account <account> set MULTI_STATEMENT_COUNT = 0;
    

    デフォルトでは、 MULTI_STATEMENT_COUNT1 に設定されています。これは、実行できる SQL ステートメントが1つだけであることを示しています。

    ノート:アカウントレベルで MULTI_STATEMENT_COUNT パラメーターを設定すると、そのアカウントを使用する他のSnowflakeコネクタとドライバーにも影響します(例: Snowflake JDBC ドライバー)。

SQL ステートメントのバッチの準備

ODBC ドライバーは、 SQL ステートメントのバッチを準備する機能をサポートします(例: SQLPrepare 関数を呼び出すことにより)。次の点に注意してください。

  • ステートメントに パラメーター がある場合は、 SQLNumParams 関数を呼び出すと、バッチ内のすべてのステートメントのパラメーター総数が返されます。

  • 結果セットに関する列情報(例: SQLNumResultCols、 SQLDescribeCol、 SQLColAttribute、 SQLColAttributes によって返されるデータ)は、 SQLExecute または SQLExecDirect を呼び出すまで利用できません。( SQLPrepare を呼び出すだけでは、この情報は利用できません。)

制限事項

GET および PUT コマンドは、 SQL ステートメントのバッチではサポートされていません。実行する GET および PUT コメントを含む SQL ステートメントのバッチを送信すると、 GET および PUT コマンドは無視され、エラーは報告されません。

バッチ挿入に対する配列変数へのパラメーターのバインド

アプリケーションコードでは、 INSERT ステートメントのパラメーターを配列変数にバインドすることにより、1つのバッチに複数の行を挿入できます。

例として、次のコードは、 INTEGER 列と VARCHAR 列を含むテーブルに行を挿入します。この例では、配列を INSERT ステートメントのパラメーターにバインドします。

SQLCHAR * Statement = "INSERT INTO t (c1, c2) VALUES (?, ?)";

SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, 0);
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMSET_SIZE, ARRAY_SIZE, 0);
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_STATUS_PTR, ParamStatusArray, 0);
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &ParamsProcessed, 0);
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0,
                 IntValuesArray, 0, IntValuesIndArray);
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, STR_VALUE_LEN - 1, 0,
                 StringValuesArray, STR_VALUE_LEN, StringValuesLenOrIndArray);
...
SQLExecDirect(hstmt, Statement, SQL_NTS);

この手法を使用して多数の値を挿入する場合は、インジェストのためにデータを(ローカルマシン上でファイルを作成することなく)仮ステージにストリーミングすると、ドライバーのパフォーマンスを向上させることができます。値の数がしきい値を超えると、ドライバーはこれを自動的に実行します。

ドライバーによりデータを仮ステージに送信するには、ユーザーはスキーマに対して以下の権限を持っている必要があります。

  • CREATE STAGE

ユーザーにこの権限がない場合、ドライバーはフォールバックして、クエリを含むデータをSnowflakeデータベースに送信します。

さらに、セッションの現在のデータベースとスキーマを設定する必要があります。これらが設定されていない場合、ドライバーによって実行される CREATE TEMPORARY STAGE コマンドは、次のエラーにより失敗する可能性があります。

CREATE TEMPORARY STAGE SYSTEM$BIND file_format=(type=csv field_optionally_enclosed_by='"')
Cannot perform CREATE STAGE. This session does not have a current schema. Call 'USE SCHEMA', or use a qualified name.

注釈

データをSnowflakeデータベースにロードする別の方法( COPY コマンドを使用した一括ロードを含む)については、 Snowflakeへのデータのロード をご参照ください。