2011-11-14 10 views
2

Firebird Embeddedを実行しているFirebirdデータベースに接続されたDBExpress接続があります。これまでのところすべてうまく動作しますが、非常に奇妙なことが起こっています。なぜCREATE TABLEは成功すると思われますが、DBXでは失敗しますか?

私は、接続を含むデータモジュールといくつかの異なる表を表すTSimpleDatasetオブジェクトを持っています。私は新しいテーブルを追加しようとする。しかし、動作しているように見えますが、その後失敗:私は、テーブルを作成しようとすると

procedure Update(module: TdmDatabase); 
const 
    SQL = 'CREATE TABLE NEW_TABLE (blah blah blah)'; 
    SQL2 = 'ALTER TABLE NEW_TABLE ADD CONSTRAINT PK_NEW_TABLE PRIMARY KEY (blah)'; 
    SQL3 = 'DROP TABLE NEW_TABLE'; 
begin 
    module.connection.ExecuteDirect(SQL);  //succeeds 
    module.connection.ExecuteDirect(SQL2);  //succeeds 
    try 
    module.New_TableDataset.Active := true; //fails 
    except 
    module.connection.ExecuteDirect(SQL3); //succeeds 
    raise; 
    end; 
end; 

は、動作するように見える、と私はできALTERDROPそれだけで罰金、しかしときSELECTを実行しているデータセットを開こうとすると、「無効なテーブル名」というエラーが表示されます。 CREATE TABLEステートメントが実行された直後にデバッガでプログラムを実行してプログラムを終了させた場合、データベースを調べると新しいテーブルは存在しません。

誰でも何が起こる可能性がありますか、どのように修正できますか? SQLSQL2SQL3が1つ(または多くで)トランザクションで実行されている純粋なトランザクションの問題、のように見える

+0

作成したテーブルの上にSELECTクエリを作成します(+ COMMIT)、私はFirebirdのためIBXを使用するので、これはコメントです。確認してくださいテーブルの作成に使用したトランザクションをコミットします。 "New_TableDataset"が新しいトランザクションを使用してアクティブ化されていることを確認します。システムテーブルのビューが異なる長期実行トランザクションを使用してアクティブ化されません。 –

+0

その他のヒント:ほとんどのDDL操作を自分のトランザクションに実行し、すべてのトランザクションをコミットします。いくつかのツールでは、「DDL操作を自動コミットする」というオプションがあります。また、DDLと通常の操作を混在させることは絶対にありません。 –

+0

非推奨のTSimpleDatasetの代わりにTSqlQueryコンポーネントを使用することがあります。 –

答えて

4
  1. 。そして、トランザクションは少なくともSQLの後にも有効です。 は異なるトランザクションで動作していますが、最初のトランザクションのコミットされていない変更は当然ありません。
  2. この問題は、DataSnap/dbExpress固有の問題ではなく、ドライバの実装固有の問題です。だから、ドライバーが何であるかを知ることは良いことです。オプションでドライバベンダーテクニカルサポートに連絡することもできます。
  3. 対処方法(純粋な投機):
    • 明示的なトランザクション制御にコマンドの実行を囲むようにしてください。それは、トランザクションが必要なステップの後に終了することを(場合によって)保証します。
    • SQLおよび/またはSQL2の後にCOMMITを実行してください。
    • ExecuteDirectの代わりにTSQLQueryを使用してください。うまくいけば、すべてのコマンドが単一のトランザクションで実行されることを望みます。

PS:最後に別のdbExpressドライバ、あるいはデータアクセスライブラリを使用することを検討してください。私は解決策だった、ADOと同様の問題があった

+0

ありがとうございます。 'CREATE TABLE'をそれ自身の明示的なトランザクションに入れました。 –

0

1 /としてまだ言った:すべてのDDL SQLの後にCOMMITを実行します。最初のCREATE OKである場合には

2 /は、私はDBXに慣れていないよ

+1

これはドライバの問題でない限り、アドバイス "2"は役に立ちません。運転手がそれが悪い場合は、交換する必要があります。 "1"については、COMMITがDDL(データ定義言語)文に従うように指定する必要があります。COMMITがすべてのSQL文に従わなければならないように見えますが、それは間違っています。複数の操作がグループとして成功または失敗するようにトランザクションを使用します。 –

+0

@CosminPrund私は2が役に立たないと思っていますが、私の場合は効率的で、時にはドライバーを簡単に置き換えることができない場合もあります。テストするのは簡単です。私はあなたの1 /発言でOKです:私は自分の投稿を編集します。 – philnext

関連する問題