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 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 を呼び出すと一部の列情報が利用可能になりますが、情報が完全に正確ではない可能性があり、その後 SQLExecute または SQLExecDirect を呼び出すとより正確な情報が得られる可能性があります。

制限事項

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へのデータのロード をご参照ください。