firebird 配列フィールドについて


おっさん  2016-08-09 00:42:58  No: 48248

私には乗り越えるのが難しい関所にさしかかってしまいました。
どなたかお分かりの方、ご教授願えませんでしょうか。

RAD STUDIO XE5 エンタープライズを使用しています。
firebird.3.0を利用し、簡単なデータベースアプリケーションを
作っています。スタンドアロンだけではなく、社内で共用できる
ものも作れてとても便利ですね。

ところで今回どうしてもたくさんのフィールドが必要なデータベース
(フィールド数120ほど)を作らなければいけなくなりました。
正直にフィールドを120作ってテストしてみたところ遅いこと遅いこと...
データベースファイルを開くのもままならないので他の策を考えることと
しました。いろいろ調べてみると配列フィールドを定義できるとのことなので
これを試してみようと思いました。ここでつまずいたわけです。テーブルは
このように定義しました。

CREATE TABLE TEST ( TTT VARCHAR(038) [120]);

これで可変長38文字の配列フィールドTTTが要素数120個定義できたと思います。
これをTFDQUERY(TestQueryという名前です)で受けます。フィールドを確認
すると確かにTTTというフィールドがTarrayFieldで作成されていました。
問題はここからで、早速テストデータを入れてみようと思い次のようにしました。

TArrayField(TestQuery.FieldByName(‘TTT’)).FieldValue[0] := ‘test1’;

ボタンクリックイベントにこう書いたのですが、ボタンをクリックすると
「引数が範囲外」とでます。配列の要素数が確保されていないのかと思い
(テーブル定義の時に[120]としたのはなんだったのか?)

Sizeプロパティに要素数を設定し再びやってみても同じエラーです。

これは定義はできているが配列が確保されていないということなのではない
でしょうか。対策はあるでしょうか。


igy  2016-08-09 07:29:26  No: 48249

TArrayField(TestQuery.FieldByName(‘TTT’)).FieldValue[0] := ‘test1’;

TArrayField(TestQuery.FieldByName(‘TTT’)).FieldValues[1] := ‘test1’;
にしたら、どうなりますか?


おっさん  2016-08-09 07:34:50  No: 48250

>TArrayField(TestQuery.FieldByName(‘TTT’)).FieldValues[1] := ‘test1’; 

これやりました。ですが結果は同じでした。


au  2016-08-09 18:06:43  No: 48251

ヘルプによるとフィールド定義をしないで使う場合はTDataSetのObjectViewをTrueに設定と書いてありますけどTrueになってますか?

ttp://docwiki.embarcadero.com/RADStudio/XE5/ja/%E9%85%8D%E5%88%97%E9%A0%85%E7%9B%AE%E3%82%92%E6%93%8D%E4%BD%9C%E3%81%99%E3%82%8B

後、Berlinの新機能のFireDACの所に、Interbase/Firebirdの配列型に対応とあるので、もしかするとXE5のFireDACだと配列型の操作は出来ないのかもしれません。
ttp://docwiki.embarcadero.com/RADStudio/Berlin/ja/%E6%96%B0%E6%A9%9F%E8%83%BD
その場合はIBXだと上手く行くのかもしれません。


おっさん  2016-08-09 21:59:37  No: 48252

icyさん、auさんありがとうございます。

>TDataSetのObjectViewをTrueに設定と書いてありますけどTrueになってますか? 

このヘルプは見ました。で、オブジェクトインスペクタで確認してみましたところ
もともとtrueになっていました。念のためにコードでも明示的に指定もしました。

>もしかするとXE5のFireDACだと配列型の操作は出来ないのかもしれません。
ヘルプは見たのですが、このことまではノーチェックでした...ありゃぁ
まいったな。

他に多すぎるフィールドを持つ(というか少なくして)このようなデータベースを
ハンドリングするアイデアをお持ちではないですか。私は120の配列フィールドTTT
を1つのBlobフィールドにしてCSV形式で入れてやろうかと考えたのですが、任意の
要素を取り出したり更新したりするのが面倒そうで、1歩間違うとえらいことになるし
...困りましたわ


おっさん  2016-08-09 22:13:27  No: 48253

先ほどauさんの発言にあるリンクに行ってみたのですが、確かに見覚えのあるページで
タイトルが「配列項目を操作する」とあります。おっしゃってた通り

「Firebird 配列データ型のサポート。」とありますね...ってことは
MySQLやSQLiteもしくはPosgretSQLなら使えるんでしょうか?1つの解決策ですよね

でも...たくさんのフィールドを配列フィールドにしたからってパフォーマンスの向上
が望めるかどうかわかりませんよね...向上しますでしょうか?


おっさん  2016-08-09 22:17:34  No: 48254

訂正
「Firebird 配列データ型のサポート。」とあるのは最初のリンクではなく
2つ目の「新機能-RAD  studio」のページですね


通りすがり  2016-08-09 22:33:21  No: 48255

FieldByNameは毎回行うのではなく、1カラムにつき1回呼び出したらTFieldに保持しておくといいのでは?
というより(プロファイラなど)何らかの方法で、『どの処理が』『どのような理由で』遅いのかをまず確認するべきですよね。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加