2012-04-27 3 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 

내가 여전히 데이터 스냅 서버를 디버깅 할 때 오류가 발생 보이지 않는 : 나는 SQL Management Studio에서 SQL을 실행하면, 난 항상 오류가 ... 그래서 나는 다음과 같이 catch 블록을 변경 시도 물론 클라이언트 응용 프로그램은 오류를 전혀 알지 못합니다. 누구나 'raiserror'와 외래 키 위반 오류가 DataSnap 서버에 나타나지 않는 이유는 무엇입니까?

FYI - 저는 모두 Windows Server 2008 R2에서 실행되는 Delphi XE2 Enterprise 및 SQL 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 오류를 리 레이즈하는 데 사용하는 코드입니다.