IBQueryとIBTransaction

—————————
デバッガ例外通知
—————————
プロジェクト Project2.exe は例外クラス EIBClientError (メッセージ ‘Transaction not assigned’)を送出しました。
—————————
ブレーク(B) 継続(C) ヘルプ
—————————

InterBaseのコンポーネントをテストで使っているのだけれど、トランザクションのコンポーネントをIBQueryにセットしないことにはSQLを実行することはできないみたい。たぶん。InterBaseコンポーネントではSQLを実行するにはトランザクションでコミット・ロールバックしなければならない、という仕様なら従うけれどもー。デバッグしていて思ったんだけれど、コミットもロールバックもしないでアプリケーションが強制終了するという事態に陥ったら、コミットできないままの処理はどうなってしまうんだろう。さっきのテストのようにDBが開かなくなるんじゃないかとビビってるんだけれど大丈夫だろうか。IBQueryのプロパティでauto commitとか無いのだろうか。

firebirdのテーブルがDROPできない

categoryという名前のテーブルを作成して、それを削除しようとしたら、

SQL> drop table category;
Statement failed, SQLSTATE = 42000
unsuccessful metadata update
-object CATEGORY is in use

というエラーが発生してテーブルが削除することができなかった。原因は、トランザクションでコミットしていない処理が残っていたから。
SQL> commit;
と入力してやってからdropを実行すると上手く行った。

と、思ったら、commitしてもテーブルを削除できない現象を確認した。CATEGORYオブジェクトは使用中である・・・ふむ。
firebirdのisqlを一旦quitコマンドで終了させて、再度起動してデータベースに接続してみたら、今度はdropコマンドが通った。う~ん、なんだこりゃ。

あ、わかった。isqlで繋げたまま、delphiのIDEでも繋げていたからおかしな現象が発生していた模様。めんどくさいけどisqlはその都度接続するようにしないといかんな。

Delphi : DBGridのデータが(WIDEMEMO)と表示される場合の対処法

組み込みデータベースのsqliteをADOで接続してselectしたテーブルをDBGridにバインドしてみたら、sqliteのTextフィールドの値が表示されないのでかなりハマった。WIDEMEMOって何?とか思っていろいろググってみたが解決方法はわからず。さんざん調べてみて解決方法はどうも2つあるらしい。

  • OnGetTextイベントでテキストの値を変換する
  • OnDrawColumnCellイベントで値を変換する

OnGetTextイベントでやるのが一般的なようだけれど、いや、そのイベントどこのコンポーネントにあるのかわからないんだけど。しょうがないのOnDrawColumnCellイベントの方でやることにする(このイベントはDBGridのイベントでに存在する)。で、コードは適当に外国のサイトにあるのを参考にしてみた。

procedure TmainForm.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
if Column.Field.FieldName = ‘comment’ then begin
DBGrid1.Canvas.FillRect(Rect);
DBGrid1.Canvas.TextRect(Rect, Rect.Left, Rect.Top, Column.Field.Value);
end;
end;

コードの内容は、想像に任せる。sqliteのText型がダメなのか?それじゃあfirebirdで試してみたら上手く表示されるのかも・・・とか考えていたら別のDBでも同じようにWIDEMEMOで表示されませんとかそういうネタがあったのでsqlite固有の問題ではないのかもしれない。

delphiを使う限りにおいては、組み込みデータベースはsqliteよりfirebirdの方が相性はいいという情報がちらほらあるが、どうなんだろうか。firebirdはinterbaseが元になっていて、そのinterbaseはBorlandが開発していて、そのBorlandはdelphiを開発していた、だからdelphiとfirebirdは相性がいい、とか。速度の面ではsqliteの方が速いらしい。

念のためfirebirdも試してみる

調べてみると、DBGridに表示させるフィールドの型はvarchar型か、varhcarより大きな場合はmemo型として表示させることになる模様。long varchar型(text)だからこの表示の問題は発生しているので、text型しか扱えないsqliteは扱いにくい。試しにfirebirdでも同様にやってみることにする。

firebirdのインストール

Firebird日本ユーザー会
のダウンロードよりfirebirdのインストールタイプをダウンロード・実行する。バージョンは2.5を選択してみた。
64-bit Classic, Superclassic & Superserver
Firebird-2.5.1.26351_1_x64.exe

firebirdのユーザ作成

  1. firebirdをインストールしたらコマンドプロンプトを起動する。起動したらfirebirdのインストールディレクトリにcdコマンドで移動する
    C:Usersnakahira>cd "C:Program FilesFirebirdFirebird_2_5bin"

  2. binフォルダにあるgsec.exeを使用してfirebirdを利用するアカウントを作成する。
    C:Program FilesFirebirdFirebird_2_5bin>gsec -user sysdba -pass masterkey -add nakahira -pw test
    sysdbaはfirebirdで初期設定されている管理者アカウントで、masterkeyはそのパスワード。そして新しくnakahiraという名前のアカウントとそのアカウントパスワードをtestとして追加する、という意味。
  3. firebirdのデータベースファイルを作成する。スタートメニューのプログラムプログラムから先程インストールしたFirebird ISQL Toolを実行する。するとコマンドプロンプトみたいな画面が表示されるのでデータベースを作成するコマンドを入力する。
    SQL> create database 'C:test.fdb' page_size 8192 user 'nakahira' password 'test';
    これで、Cドライブ直下にtest.fdbというfirebirdのデータベースファイルが作成される。

firebirdにauto incrementが無い件

ここまでやってみて、今更ながらfirebirdにはフィールドにauto increment機能が無いことに気づいた。どうやって主キーとして設定したidの値をカウントアップするのか、と調べてみたらtriggerを設定してみんなやっているらしい。
How to create an autoincrement column?
テーブルが1つや2つならそれでいいかもしれないが、5つや6つやそれ以上の場合もtriggerを設定していかないといけないのだろうか。まいったな。

firebirdならvarchar型があるのでDBGridに問題無く表示させることができる

テストしてみたら問題無かった。ただ、firebirdっていろいろと面倒だ・・・。組み込みのデータベースならMicrosoftのAccessのmdbファイルを使った方が楽な気がしてきた。

Delphi デバッグで実行してもウインドウが表示されない場合の対処法

デバッグで実行してみても、起動せずにウインドウが表示されない場合の対処法。

  • 直接デバッグフォルダのexeファイルを実行してみる

dllやコンポーネントを追加とか削除したりした場合に、デバッグを実行!とやってみてもうんともすんとも言わない時がある。構文チェックしてみてもエラーはないみたいだが、なぜか起動することができない。そういう時はデバッグフォルダにあるexeファイルを直接ダブルクリックで実行してみることで、何が問題なのかわかる時がある。たいていの場合はdllが見つかりませんというのが表示される。

Microsoft データ リンク エラー

ACCESSのMDBファイルにADO接続設定しようとしたらエラーが出た。ずっと前にも出たことがあったような気がするが完全に記憶から抜け落ちていた。ウィザードにある「接続チェック」ではどうもうまくいかない模様。接続情報を詳細に入力さえしておけばうまく繋がる。ユーザー名、パスワードを接続タブにある入力欄に正しく埋めたとしても、何が問題なのか不明だが下記エラーが出る。このタブの情報は空欄のままでいい。すべてのタブのパスワード設定箇所にMDBに設定しておいたパスワードを入力すれば繋がるようになる。

—————————
Microsoft データ リンク エラー
—————————
プロバイダーの初期化中にエラーが発生したため、接続のテストに失敗しました。アプリケーションを起動できません。システム データベースが存在しないか、またはほかのユーザーが排他的にシステム データベースを開いています。
—————————
OK
—————————