2012-04-27 20 views
1

削除されたレコードが削除される前にログに記録するDataSnapメソッドがあります。削除に失敗した場合は、トランザクションをロールバックして、ログレコードも保持しないようにします。古典的な理由は、削除されているレコードが別のテーブルで使用されていることです。Reraise SQLエラー - SQLエラーが発生する

私のSQLは次のようになります。

begin transaction 
begin try 
    insert into audit ([fields]) values ([the vlaues]) 
    delete [sometable] where [id] = [someid] 
    commit transaction 
end 
begin catch 
    rollback transaction 
end catch 

これだけで正常に動作します。ただし、エラーメッセージは表示されないため、DataSnapサーバーでは表示されません。 SQL構文エラーは常にエラーメッセージを表示し、他の挿入/更新一意キーと外部キー違反は常にエラーを返します。なぜこのコードがエラーを抑制するのか分かりません。 DataSnapコードはシンプルです:

procedure TMyClass.DeleteRecord([params]); 
var 
    qry: TSQLQuery; 
begin 
    qry := TSQLQuery.Create; 
    ... 
    qry.CommandText := [sql from above]; 
    qry.ParamByName('[params]').Value := [Values]; 
    qry.ExecSQL; // <- No error is raised here 
end; 

構文エラーやパラメータのバインドに問題がないように、クエリはうまく実行されます。私は外来キーの違反のエラーを見たことはありません。そう、

try catch 
    rollback transaction 
    raiserror(N'Test Error Message', 16, 1) 
end catch 

が、私はまだのDataSnapサーバーをデバッグするときにエラーが発生表示されていない:私は、SQL Management StudioでSQLを実行すると、私は常にエラーを参照してください...だから私は、次のようにcatchブロックを変更してみましたもちろん、クライアントアプリケーションはエラーの何も知らない。 DataSnapサーバーで 'raiserror'と外部キー違反のエラーが発生しない理由は何ですか?

FYI - 私はすべてDelphi XE2 EnterpriseとSQL Server 2008 R2をWindows Server 2008 R2上で実行しています。

答えて

0

解決策は非常に簡単になりました。 SQLステートメントの先頭にset nocount on;を追加すると、DataSnapからエラーを隠した問題が修正されました。私はこれまでにこれを見てきましたが、主にデータが返されたときです。これはqry.ExecSQL();を使用しているので、ここでもnocountが必要でした。必要に応じて

set nocount on; 
begin transaction 
begin try 
    insert into audit ([fields]) values ([the vlaues]) 
    delete [sometable] where [id] = [someid] 
    commit transaction 
end 
begin catch 
    declare @eMsg nvarchar(2048), @eSv int, @eSt int 
    select @eMsg = error_message(), @eSv = error_severity(), @eSt = error_state() 
    rollback transaction 
    raiserror(@eMsg, @eSv, @eSt) 
end catch 

今すぐクライアントアプリケーションでリレイズエラーが表示されます。ここでは

は、私は、トランザクションをロールバックした後、SQLエラーをリレイズするために使用するコードです。

関連する問題