コンテンツにスキップ

11.4 Machbase SQLCLIとODBC

Machbase SQLCLIはC/C++アプリケーションで使用する呼び出しレベルインターフェース(Call-Level Interface)です。ODBCドライバーは標準ODBCアプリケーションで使用します。両者は環境・接続・文の ハンドルを使用する実行フローを共有し、SQLCLIには高速Append用の拡張関数が追加されています。

選択基準

要件インターフェース
MachbaseインストールパッケージとともにC/C++アプリケーションを開発SQLCLI
汎用ODBCツールまたはドライバーマネージャーを使用ODBC
Append拡張APIによる大量入力SQLCLI
標準SQLの実行と結果の取得SQLCLIまたはODBC

ヘッダーとライブラリ

インストールディレクトリで次のファイルを確認します。

test -f "$MACHBASE_HOME/include/machbase_sqlcli.h"
test -f "$MACHBASE_HOME/lib/libmachbasecli_dll.so"

Linuxでの動的リンクの例です。

gcc cli_quickstart.c   -I"$MACHBASE_HOME/include"   -L"$MACHBASE_HOME/lib"   -lmachbasecli_dll   -o cli_quickstart

LD_LIBRARY_PATH="$MACHBASE_HOME/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"   MACHBASE_PASSWORD='your-password' ./cli_quickstart

本番ビルドは、インストールパッケージのinstall/machbase_env.mkとプラットフォーム別の リンカー設定に基づいて構成します。

接続文字列

SQLCLIの基本的な接続文字列は次のキーを使用します。

SERVER=127.0.0.1;PORT_NO=5656;UID=APP_USER;PWD=secret;CONNTYPE=1

ODBCデータソースを使用する場合はDSN、アカウント、パスワードを指定します。

DSN=MACHBASE;UID=APP_USER;PWD=secret

マルチデータベースの初期値をサポートするドライバーではDATABASEまたはDBNAMEを使用できます。 実際に配布されたドライバーのサポート状況を確認し、接続後にSELECT CURRENT_DATABASE()で 選択結果を検証します。

クイックスタート

次のプログラムは5656ポートに接続してシステムテーブルのクエリを実行し、全ハンドルを解放します。 パスワードは環境変数で渡します。

#include <stdio.h>
#include <stdlib.h>
#include <machbase_sqlcli.h>

int main(void)
{
    SQLHENV env = SQL_NULL_HENV;
    SQLHDBC dbc = SQL_NULL_HDBC;
    SQLHSTMT stmt = SQL_NULL_HSTMT;
    char conn[512];
    const char *password = getenv("MACHBASE_PASSWORD");

    if (password == NULL) {
        fputs("MACHBASE_PASSWORD is required\n", stderr);
        return 2;
    }

    snprintf(conn, sizeof(conn),
        "SERVER=127.0.0.1;PORT_NO=5656;"
        "UID=SYS;PWD=%s;CONNTYPE=1", password);

    if (SQLAllocEnv(&env) != SQL_SUCCESS) {
        return 3;
    }
    if (SQLAllocConnect(env, &dbc) != SQL_SUCCESS) {
        SQLFreeEnv(env);
        return 4;
    }
    if (SQLDriverConnect(
            dbc, NULL, (SQLCHAR *)conn, SQL_NTS,
            NULL, 0, NULL, SQL_DRIVER_NOPROMPT) != SQL_SUCCESS) {
        SQLFreeConnect(dbc);
        SQLFreeEnv(env);
        return 5;
    }
    if (SQLAllocStmt(dbc, &stmt) != SQL_SUCCESS) {
        SQLDisconnect(dbc);
        SQLFreeConnect(dbc);
        SQLFreeEnv(env);
        return 6;
    }
    if (SQLExecDirect(
            stmt, (SQLCHAR *)"SELECT COUNT(*) FROM V$TABLES",
            SQL_NTS) != SQL_SUCCESS) {
        SQLFreeStmt(stmt, SQL_DROP);
        SQLDisconnect(dbc);
        SQLFreeConnect(dbc);
        SQLFreeEnv(env);
        return 7;
    }

    puts("query succeeded");
    SQLFreeStmt(stmt, SQL_DROP);
    SQLDisconnect(dbc);
    SQLFreeConnect(dbc);
    SQLFreeEnv(env);
    return 0;
}

失敗原因を出力する必要があるアプリケーションは、SQLGetDiagRec()または既存コードの SQLError()でSQLSTATE、ネイティブエラーコード、メッセージを読み取ります。

標準的な実行フロー

  1. 環境ハンドルと接続ハンドルを割り当てます。
  2. SQLDriverConnect()またはSQLConnect()で接続します。
  3. 文ハンドルを割り当てます。
  4. SQLPrepare()SQLExecute()、またはSQLExecDirect()でSQLを実行します。
  5. SELECT結果はSQLBindCol()SQLFetch()で読み取ります。
  6. 文、接続、環境の順にリソースを解放します。

入力値は文字列として連結せず、SQLBindParameter()でバインドします。NULL許容性は SQLDescribeCol()の最後の引数、またはSQLColAttribute(..., SQL_DESC_NULLABLE, ...)で確認します。

Named Bind Parameter

サーバーとドライバーが名前付きパラメーターをサポートする場合、:nameプレースホルダーを使用し、 SQLBindParameterByName()でバインドできます。同じ名前が複数回現れると1つの値が全位置に適用されます。 共通の制約と例は Named Bind Parameterを参照してください。

サポートを確認できない環境では、標準の?プレースホルダーとSQLBindParameter()を使用します。

INSERT結果のROWID

Standard Editionで単一のINSERT ... VALUESが成功した後、生成されたROWIDが必要な場合は 次の方法を使用します。

  • SQLCLI拡張: SQLGetGeneratedRowID()
  • 標準ODBC: 生成ROWID専用の標準APIなし

バッチ、Append、INSERT ... SELECT、UPSERTで同じ戻り値を想定しないでください。詳細な範囲は ROWIDとINSERT結果IDを参照してください。

Append拡張API

高速入力は通常の文と分けたAppendフローを使用します。

段階主な関数
オープンSQLAppendOpen()、選択列はSQLAppendOpenColumns()/W()
1行の入力SQLAppendDataV2()または対応バージョンのAppend関数
バッチ入力SQLAppendBatch()
サーバーへの反映SQLAppendFlush()
エラーコールバックSQLAppendSetErrorCallback()
クローズSQLAppendClose()

Append行の列順序と型は、対象テーブルのスキーマと完全に一致する必要があります。文字列、バイナリ、 IP、DATETIME、NULLの表現は、インストール済みmachbase_sqlcli.hSQL_APPEND_PARAM定義に 基づいて記述します。エラーコールバックでは失敗行とサーバーエラーを記録しますが、パスワードや機密の 生データはログに残しません。

有効なAppendハンドルがある接続は通常のクエリと共有せず、close結果の成功・失敗件数を確認します。

マルチスレッドとリソース管理

  • スレッドごとに接続と文を分けます。
  • 1つの文またはAppendハンドルを複数スレッドで同時に使用しません。
  • すべてのエラー経路でもハンドルを逆順に解放するよう、後処理関数を用意します。
  • 再試行前に、前の接続とAppendの状態が完全に閉じているか確認します。
  • 大量入力では成功件数と失敗件数の両方を記録します。

API詳細の確認

関数プロトタイプ、定数、構造体は、インストール済みの $MACHBASE_HOME/include/machbase_sqlcli.hが該当ライブラリと一致する基準です。 サンプルを別バージョンのヘッダーと混用せず、コンパイル・リンク・5656接続のテストを デプロイパイプラインに含めます。

DECIMAL Append

SQLAppendDataV2()SQLAppendBatch()DECIMALまたはNUMERIC値を入力する際は、 32バイトの不透明型SQL_APPEND_NUMERICと公開生成関数を使用します。 アプリケーションで内部バイトを直接作成・変更しません。

入力関数
UTF-8の数値文字列SQLAppendNumericFromString()
符号付き・符号なし整数SQLAppendNumericFromInt64()SQLAppendNumericFromUInt64()
SQL_NUMERIC_STRUCTSQLAppendNumericFromSQLNumeric()
NULLSQLAppendNumericSetNull()

正確な値を保持するには、文字列またはSQL_NUMERIC_STRUCTを優先します。型配列には SQL_APPEND_TYPE_NUMERICまたはSQL_APPEND_TYPE_DECIMALを指定し、対象列の精度とスケールに 基づいてオーバーフローと丸めを確認してください。

ARRAYと選択列Append

Machbase DBMS 8.7.0は、SQL_MACHBASE_ARRAY_DESCによる型付きARRAYの検索・バインドと、 SQL_MACHBASE_SPARSE_ARRAY_DESCによるスパース入力をサポートします。通常のOpenでもARRAY列に スパースディスクリプターを渡せます。

SQLAppendOpen(statement, (SQLCHAR *)"ARRAY_APPEND_FULL_EXAMPLE", 0);
row[0].mLong = 1;
row[1].mVar.mData = &sparse;
row[1].mVar.mLength = SQL_APPEND_SPARSE_ARRAY_DESC_LENGTH;
SQLAppendDataV3(statement, row, 2);
SQLAppendClose(statement, &success, &failure);

上記コードはID LONG, A INT32[4]テーブルの入力順序に従います。接続・ディスクリプター・バッファの 準備とエラー処理を含む通常Openの全体例を 先に確認してください。旧式のSQLAppendData(void *[])にディスクリプターを渡す方式とは異なります。

一部の列または固定ARRAY要素だけを選択する場合は、SQLAppendOpenColumns()または SQLAppendOpenColumnsW()を使用します。

SQLCHAR *targets[] = {
    (SQLCHAR *)"ID",
    (SQLCHAR *)"CHANNELS[0]",
    (SQLCHAR *)"CHANNELS[3]",
    NULL
};

SQLAppendOpenColumns(statement, (SQLCHAR *)"SENSOR_ARRAY", targets, 0);

ARRAY要素の対象とスパースディスクリプターの位置は0始まりのインデックスです。列名リストの最後の要素は NULLである必要があります。SQLAppendBatch()はARRAYをサポートしません。 ディスクリプター定義、配列全体のNULLと要素NULLの処理、直接ODBCハンドルの制約は Sparse ARRAYと選択列Append APIを参照してください。

最終更新日