SQL Server에서 동일한 예외를 다시 던지는 방법
방금 시행 블록에서 발생한 것과 동일한 예외를 SQL Server에 다시 던지고 싶습니다.나는 같은 메시지를 보낼 수 있지만 같은 오류를 던지고 싶다.
BEGIN TRANSACTION
BEGIN TRY
INSERT INTO Tags.tblDomain (DomainName, SubDomainId, DomainCode, Description)
VALUES(@DomainName, @SubDomainId, @DomainCode, @Description)
COMMIT TRANSACTION
END TRY
BEGIN CATCH
declare @severity int;
declare @state int;
select @severity=error_severity(), @state=error_state();
RAISERROR(@@Error,@ErrorSeverity,@state);
ROLLBACK TRANSACTION
END CATCH
RAISERROR(@@Error, @ErrorSeverity, @state);
이 행에는 에러가 표시되지만, 그런 기능을 원합니다.로 인해 50000이하지만, 에러 번호 50000을 .@@error
,
프런트 엔드에서 이 오류를 캡처하고 싶습니다.
예.
catch (SqlException ex)
{
if ex.number==2627
MessageBox.show("Duplicate value cannot be inserted");
}
이 기능을 원합니다.이 기능을 통해서는 달성할 수 없습니다.raiseerror
백엔드에 커스텀에러 메시지를 표시하지 않습니다.
RAISEERROR
에 ErrorNo를 됩니다.
Msg 2627, Level 14, State 1, Procedure spOTest_DomainInsert,
14행 UNIQE KEY 제약 조건 'UK_DomainCode' 위반.개체 'Tags.tblDomain'에 중복 키를 삽입할 수 없습니다.문이 종료되었습니다.
편집:
stored procedure에 실행이 필요한 쿼리가 여러 개 포함되어 있는데 프런트 엔드에서 예외를 처리하려면 try catch block을 사용하지 않는 단점은 무엇입니까?
SQL 2012에서는 throw 스테이트먼트가 도입되었습니다.
http://msdn.microsoft.com/en-us/library/ee677615.aspx
매개 변수 없이 DLOW 문이 지정된 경우 CATCH 블록 안에 표시되어야 합니다.이것에 의해, 검출된 예외가 발생합니다.
BEGIN TRY
BEGIN TRANSACTION
...
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
THROW
END CATCH
다음으로 에러가 발생하여 오류 메시지가 보고되었을 때 일련의 문을 롤백하기 위한 완전한 기능의 클린 코드샘플을 나타냅니다.
begin try
begin transaction;
...
commit transaction;
end try
begin catch
if @@trancount > 0 rollback transaction;
throw;
end catch
SQL 2012 이전
begin try
begin transaction;
...
commit transaction;
end try
begin catch
declare @ErrorMessage nvarchar(max), @ErrorSeverity int, @ErrorState int;
select @ErrorMessage = ERROR_MESSAGE() + ' Line ' + cast(ERROR_LINE() as nvarchar(5)), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE();
if @@trancount > 0 rollback transaction;
raiserror (@ErrorMessage, @ErrorSeverity, @ErrorState);
end catch
CATCH 블록 내부로 재투입(SQL2012 이전 코드, SQL2012 이상에서는 Drow 문 사용):
DECLARE
@ErrorMessage nvarchar(4000) = ERROR_MESSAGE(),
@ErrorNumber int = ERROR_NUMBER(),
@ErrorSeverity int = ERROR_SEVERITY(),
@ErrorState int = ERROR_STATE(),
@ErrorLine int = ERROR_LINE(),
@ErrorProcedure nvarchar(200) = ISNULL(ERROR_PROCEDURE(), '-');
SELECT @ErrorMessage = N'Error %d, Level %d, State %d, Procedure %s, Line %d, ' + 'Message: ' + @ErrorMessage;
RAISERROR (@ErrorMessage, @ErrorSeverity, 1, @ErrorNumber, @ErrorSeverity, @ErrorState, @ErrorProcedure, @ErrorLine)
선택사항은 다음과 같습니다.
- 오류를 발견하지 않음(거품이 일게 함)
- 커스텀 키우기
SQL은 어떤 시점에서 reraise 명령 또는 특정 오류만 탐지하는 기능을 도입할 수 있습니다.하지만 지금은 회피책을 사용하세요.미안하다.
할 수 없습니다. 엔진만이 5만 미만의 오차를 발생시킬 수 있습니다.네가 할 수 있는 건 그렇게 보이는 예외를 두는 것뿐이야
질문자가 고객 측 거래를 이용해 원하는 일을 한 건 좀 바보같아요
좋아, 이건 회피책이야...:-)
DECLARE @Error_Number INT
BEGIN TRANSACTION
BEGIN TRY
INSERT INTO Test(Id, Name) VALUES (newID(),'Ashish')
/* Column 'Name' has unique constraint on it*/
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER()
--RAISERROR (@ErrorMessage,@Severity,@State)
ROLLBACK TRAN
END CATCH
catch block에 주목하면 에러가 발생하지 않고 실제 에러 번호가 반환됩니다(트랜잭션이 롤백됩니다).이제 에 들어갑니다.예외를 검출하는 대신 ExecuteScalar()를 사용하면 원하는 실제 에러 번호를 취득하고 적절한 번호를 표시합니다.
int errorNumber=(int)command.ExecuteScalar();
if(errorNumber=<SomeNumber>)
{
MessageBox.Show("Some message");
}
이게 도움이 됐으면 좋겠는데
편집 :- 주의사항입니다.해당 레코드의 수를 취득하여 ExecuteNonQuery를 사용하려고 하면 위의 솔루션이 작동하지 않을 수 있습니다.그렇지 않으면, 당신이 필요로 하는 것에 어울릴 것 같아요.알려줘.
오류가 발생한 후 저장 프로시저 실행을 중지하고 호출 프로그램으로 오류를 버블링하려면 다음 코드를 사용하여 오류를 발생시킬 수 있는 각 문을 따릅니다.
If @@ERROR > 0
Return
저장 프로시저에서의 실행이 오류 발생 후에도 계속된다는 것을 알고 놀랐습니다.이것을 깨닫지 못하면 버그를 추적하기 어려워질 수 있습니다.
이런 유형의 오류 처리는 병렬입니다(이전).넷) Visual Basic 6.SQL Server 2012에서 Throw 명령어를 기대하고 있습니다.
아직 2012년으로 이행하지 않았기 때문에 원래 에러 코드의 버블업을 구현하는 방법 중 하나는 캐치 블록에서 (다시) 던지고 있는 예외의 텍스트 메시지 부분을 사용하는 것입니다.발신자 코드의 캐치 블록에 해석하기 위한 XML 텍스트 등, 몇개의 구조를 포함할 수 있습니다.
트랜잭션 내에서 SQL 문을 실행하고 오류를 코드에 입력할 때 이러한 시나리오에 대한 래퍼 저장 프로시저를 생성할 수도 있습니다.
CREATE PROCEDURE usp_Execute_SQL_Within_Transaction
(
@SQL nvarchar(max)
)
AS
SET NOCOUNT ON
BEGIN TRY
BEGIN TRANSACTION
EXEC(@SQL)
COMMIT TRANSACTION
END TRY
BEGIN CATCH
DECLARE @ErrorMessage nvarchar(max), @ErrorSeverity int, @ErrorState int
SELECT @ErrorMessage = N'Error Number: ' + CONVERT(nvarchar(5), ERROR_NUMBER()) + N'. ' + ERROR_MESSAGE() + ' Line ' + CONVERT(nvarchar(5), ERROR_LINE()), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE()
ROLLBACK TRANSACTION
RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState)
END CATCH
GO
-- Test it
EXEC usp_Execute_SQL_Within_Transaction @SQL = 'SELECT 1; SELECT 2'
EXEC usp_Execute_SQL_Within_Transaction @SQL = 'SELECT 1/0; SELECT 2'
EXEC usp_Execute_SQL_Within_Transaction @SQL = 'EXEC usp_Another_SP'
설계상의 관점에서, 원래의 에러 번호와 커스텀 메세지에 예외를 두는 목적은 무엇입니까?어느 정도 애플리케이션과 데이터베이스 간의 인터페이스 계약이 깨집니다.원래 오류를 찾아 더 높은 코드로 처리하려면 데이터베이스에서 처리하지 마십시오.그런 다음 예외를 발견하면 사용자에게 표시되는 메시지를 원하는 메시지로 변경할 수 있습니다.하지만 나는 그것을 하지 않을 것이다. 왜냐하면 그것은 너의 데이터베이스 코드를 흐음 '잘못'하게 만들기 때문이다.다른 사람이 말한 것처럼, 독자적인 에러 코드 세트(50000 이상)를 정의하고, 대신에 에러 코드를 폐기할 필요가 있습니다.그런 다음 무결성 문제('복제된 값은 허용되지 않습니다')를 잠재적인 비즈니스 문제(ZIP 코드가 잘못되었습니다), '기준과 일치하는 행을 찾을 수 없습니다' 등)와 별도로 지정할 수 있습니다.
언급URL : https://stackoverflow.com/questions/2481273/how-to-rethrow-the-same-exception-in-sql-server
'source' 카테고리의 다른 글
선택한 항목을 버튼의 명령 매개 변수로 전달하려면 어떻게 해야 합니까? (0) | 2023.04.24 |
---|---|
Azure DevOps 파이프라인의 여러 단계에서 변수 공유 (0) | 2023.04.24 |
UITextField의 초기 키보드 애니메이션에서 매우 느린 지연/지연 (0) | 2023.04.24 |
iOS 8에서 위치 서비스가 작동하지 않음 (0) | 2023.04.24 |
시스템 변환그림그리기.아이콘에서 시스템으로Media.ImageSource (0) | 2023.04.24 |