안녕하세요? [쓸만한게없네] 윤선식입니다.
간만에 글을 올리네요.
RAISERROR 관련된 글은 여기저기 있지만 심플하게 되어 있는 샘플이 없는 것 같아서 하나 올립니다.
예제는 A값과 B값을 입력받아서 A / B를 한 결과를 돌려주는 것입니다.
Procedure는 다음과 같이 구성합니다.
CREATE PROC [dbo].UP_RaiseTest
@VAL1 INT,
@VAL2 INT,
@VAL3 INT OUTPUT
AS
BEGIN
DECLARE @ErrorNumber INT;
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;
DECLARE @ErrorProcedure NVARCHAR(126);
DECLARE @ErrorLine INT;
DECLARE @ErrorMessage NVARCHAR(2048);
SET @ErrorNumber = 0;
BEGIN TRY
SET @VAL3 = @VAL1 / @VAL2;
END TRY
BEGIN CATCH
SELECT
@ErrorNumber = ERROR_NUMBER()
-- CATCH 블록을 실행시킨 오류의 오류번호를 반환합니다.
,@ErrorSeverity = ERROR_SEVERITY()
-- CATCH 블록이 실행되도록 한 오류의 심각도를 반환합니다.
,@ErrorState = ERROR_STATE()
-- CATCH 블록을 실행시킨 오류의 상태번호를 반환합니다.
,@ErrorProcedure = ERROR_PROCEDURE()
-- CATCH 블록이 실행되는 오류가 발생한 저장프로시저나 트리거의 이름을 반환합니다.
,@ErrorLine = ERROR_LINE()
-- CATCH 블록실행을 유발한 오류가 발생한 줄번호를 반환합니다.
,@ErrorMessage = ERROR_MESSAGE()
-- CATCH 블록을 실행시키는 오류의 메시지텍스트를 반환합니다.
END CATCH;
IF @ErrorNumber <> 0
BEGIN
SELECT
@ErrorNumber AS ErrorNumber
,@ErrorSeverity AS ErrorSeverity
,@ErrorState AS ErrorState
,@ErrorProcedure AS ErrorProcedure
,@ErrorLine AS ErrorLine
,@ErrorMessage AS ErrorMessage
;
RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);
END
END
프로시져의 직접 실행 사용법은 다음과 같습니다.
DECLARE @RETVALINT
DECLARE @VAL1 INT, @VAL2 INT, @VAL3 INT
SET @VAL1 = 10;
SET @VAL2 = 0;
EXEC @RETVAL = dbo.UP_RaiseTest @VAL1, @VAL2, @VAL3 = @VAL3 OUTPUT;
SELECT @RETVAL, @VAL3;
위 프로시저를 실행한 결과는 다음과 같습니다.
같은Procedure를 .Net Program에서 다음과 같이 사용할 수 있습니다.
private void RaiseErrorTest()
{
string connectionString = "~~~~";
SqlConnection conn = null;
SqlCommand cmd = null;
int cnt = 0;
int intReturnValue = 0;
try
{
conn = new SqlConnection(connectionString);
cmd = new SqlCommand("TestDB.DBO.UP_RaiseTest", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter pVal1 = cmd.Parameters.Add("@VAL1", SqlDbType.Int);
SqlParameter pVal2 = cmd.Parameters.Add("@VAL2", SqlDbType.Int);
SqlParameter pVal3 = cmd.Parameters.Add("@VAL3", SqlDbType.Int);
SqlParameter RetVal = cmd.Parameters.Add("@RetVal", SqlDbType.Int);
pVal3.Direction = ParameterDirection.Output;
RetVal.Direction = ParameterDirection.ReturnValue;
pVal1.Value = int.Parse(txtA.Text); // A 값을 받습니다.
pVal2.Value = int.Parse(txtB.Text); // B 값을 받습니다.
conn.Open();
cnt = cmd.ExecuteNonQuery();
intReturnValue = (int)RetVal.Value;
txtC.Text = pVal3.Value.ToString();
conn.Close();
}
catch (SqlExceptionSqlex)
// 이 부분이 반드시 필요함. 일반 Exception을 받기 전에 SQL Exception 을 먼저 처리하도록 합니다.
{
foreach (SqlErrorerr in Sqlex.Errors)
// SQL Exception를 가져옵니다.
{
txtC.Text = Sqlex.Message;
// C 값을 표시할 자리에 ERROR_MESSAGE() 를 가져오도록 합니다
}
}
catch (Exceptionex)
{
txtC.Text = ex.ToString();
}
finally
{
if (cmd != null)
cmd.Dispose();
}
}
정상적일 경우엔 10 / 5 = 2 의 값을 나타냅니다.
에러일 경우 C 값을 나타내는 자리에 ERROR_MESSAGE() 를 표시합니다.
이상입니다.