depressionist

[prev|next|index]2002:43

[prev|next]20021021Mo

ODBC API を C++ から直接コールして使うプログラムがやっとまともに動くようになった。 そこでリファクタリングしたりして、 共通処理をまとめようとクラス化していくうちに、 MFC に CODBC クラスというのがあったと思い出した。 車輪の再発明をするのは本意ではない。 しかし MFC を使うのも癪だ。 ODBC 用のクラスなんて MFC に統合しないで単独で提供しろよな、とか思った。

それ以前に ODBC API の使い方は、 リファレンスマニュアルを読むのをサボって、 サンプルプログラムや何やから適当に切り張りして作っている。 あまりいいことではない。 そこで最新のマニュアルを読もうと Microsoft の Developer's サイトをあさってみた。 しかしどうしたことか ODBC API のマニュアルが見つからない。 データベース関連は ADO のマニュアルしかない。 もしかして、 ODBC ってそのうちサポートされなくなるのか?

[prev|next]20021022Tu

いろいろ検索してみると、 ODBC API マニュアルは MDAC SDK に含まれている様子。 そこで MDAC SDK をダウンロードする。 中を確認すると確かに ODBC API のマニュアルがあった。

早速、 作成したプログラムで使用した API をマニュアルで確認してみると、 いきなり deprecated になっている。 月初めに書いたプログラムは次のように書くのが新しい。

#include <sql.h>
#include <sqlext.h>
  ...
  // SQLHANDLE 変数を用意して初期化する
  SQLHANDLE henv;
  SQLHANDLE hdbc;
  SQLHANDLE hstmt;
  SQLAllocHandle (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
  SQLSetEnvAttr (henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
  SQLAllocHandle (SQL_HANDLE_DBC, henv, &hdbc);
  SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &hstmt);
  // データベースに接続
  RETCODE rc;
  rc = SQLConnect (hdbc, "DS", SQL_NTS, "USER", SQL_NTS, "PASS", SQL_NTS);
  // プリペアステートメント
  rc = QSLPrepare (hstmt, "insert into table values (?, ?)", SQL_NTS);
  long id;
  const int LEN = 32;
  char name[LEN+1];
  // 変数をバインドする
  SQLBindParameter (hstmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &id, 0, NULL);
  SQLBindParameter (hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, LEN, 0, name, 0, NULL);
  for (int i = 100; i < 200; i ++)
    {
      id = i;
      sprintf (name, "user%d", i);
      // SQL を実行する
      rc = SQLExecute (hstmt);
    }
  // 接続を切断し、ハンドルを開放する
  SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
  SQLDisconnect (hdbc);
  SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
  SQLFreeHandle (SQL_HANDLE_ENV, henv);

[prev|next]20021023We

月曜日にも書いたように、 ODBC API をラップする C++ クラスを作るのは車輪の再発明になって躊躇される。 加えてせっかくダウンロードした MDAC SDK には ADO の SDK もはいっているので、 どうせクラスを作るなら ADO コンポーネントを C++ から利用してやろうと思った。 それも g++ で。

そこで Windows の COM を C++ から利用する方法、 つまり COM クライアントを作成する方法を検索してみた。 すると VC++ には #import という、 タイプライブラリを読み込んで C++ のクラス定義や外部変数宣言へ変換する拡張機能があるようだ。 だから #import <msado15.dll> とすると、 ADO の C++ ヘッダをインクルードしたようになり、 ADO クラスを使えるようになるわけだ。 まったく Microsoft って、 ライブラリのバージョン管理をしたくないのではないか。 昔から共有ライブラリのバージョン違いには悩まされてきたけれど、 何も言語仕様まで拡張することはないだろうに。

[prev|next]20021024Th

MDAC SDK をあさっていたら、 ADO の C++ ヘッダが含まれていた。 これがあれば #import を使わなくても ADO を利用できる。 しかしヘッダがたくさんありすぎてどれをインクルードすればいいのかよくわからん。

とりあえずめぼしいヘッダをインクルードしてみると山のようにエラーが起こる。 ヘッダの中をのぞいてみると、 条件コンパイル文が幾重にも折り重なっている。 少しやる気をなくす。

気をとりなおして、 プリプロセッサに通したりしながら追跡していくと、 ADOConnection; というクラス名だけ単独に記述されている行を発見。 ほかにもクラスの数だけぽんと記述されている。 この文はいったい何がしたいのか。 C++ 的には意味のない文のはずなのでコメントアウトする。 不可解なり。

何とかコネクションを張るところまでは動くようになった。

[prev|next]20021025Fr

昨日の続き。

張ったコネクションを使って SQL を実行させようとしたところ、 実行時エラーになってしまう。 ヘッダを grep してエラーコードを検索してみると、 OLE_E_NOTRUNNING というマクロが定義されている様子。 ということは OLE の初期化に失敗しているということか。 しかし、データベースへの接続はうまく行っているように見える。 というか正常終了している。

ふとしたことでちょと切れる。 メールで友人に愚痴をこぼす。

[prev|next]20021026Sa

いやなことのあった次の日は一日中寝ているに限る。

[prev|next]20021027Su

昨日と同じ。寝て暮し。