我正在尝试验证我的过程值并抛出自定义异常,因为DAL / CRUD层中需要的数字。这也适用于我的示例。我的问题是我不会再次抛出相同的异常只是因为我有一个外部的try catch用于其他用途,btw捕获不期望的异常。有任何想法吗?内部抛出后我试图使用error_message,因为这是包含substitue参数。但我不能再使用消息 AND 我的具体号码了。例如 50101 。
create procedure dbo.ValidateString (
@Value nvarchar(max) output,
@Column varchar(100)
)
as
begin
set nocount on;
begin try
begin tran;
if @Value is null
begin
raiserror (50201, 11, 0, @Column, @Value);
end
set @Value = ltrim(rtrim(@Value));
if datalength(@Value) = 0
begin
raiserror (50211, 11, 0, @Column, @Value);
end
commit tran;
return 0;
end try
begin catch
if @@trancount > 0
begin
rollback tran;
end
if error_number() = 50201
begin
--argument null
raiserror (50201, 11, 0, @Column, @Value);
return 1;
end
if error_number() = 50211
begin
--argument
raiserror (50211, 11, 0, @Column, @Value);
return 1;
end
declare
@errorMessage nvarchar(max) = error_message(),
@errorSeverity int = error_severity(),
@errorState int = error_state();
raiserror (@errorMessage, @errorSeverity, @errorState);
return 1;
end catch
set nocount off;
end
go
create procedure dbo.InsertData (
@Name varchar(60),
@Active bit = null
)
as
begin
set nocount on;
begin try
begin tran;
exec dbo.ValidateString @Name output, 'Name';
insert into dbo.tblTest (ID, Name, Active)
values (newid(), @Name, isnull(@Active, 'false'));
if @@rowcount = 1
begin
commit tran;
return 0;
end
rollback tran;
return 1;
end try
begin catch
if @@trancount > 0
begin
rollback tran;
end
if error_number() = 50201
begin
--argument null
raiserror (50201, 11, 0, 'Name', @Name);
return 1;
end
if error_number() = 50211
begin
--argument
raiserror (50311, 11, 0, 'Name', @Name);
return 1;
end
declare
@errorMessage nvarchar(max) = error_message(),
@errorSeverity int = error_severity(),
@errorState int = error_state();
raiserror (@errorMessage, @errorSeverity, @errorState);
return 1;
end catch
set nocount off;
end
go
答案 0 :(得分:1)
定义自定义错误时,请设置消息文本以使用参数。这样,每次在嵌套的try-catch场景中重新抛出错误时,都可以传递一个新文本。
sp_addmessage @msgnum = 50005,
@severity = 11,
@msgtext = N'Message given: <<%30.20s>>'
GO
CREATE PROCEDURE dbo.sp_inner_ex AS
BEGIN
DECLARE @error INT = 50005
PRINT 'Raising inner'
RAISERROR (@error, -- Message id.
11, -- Severity,
1, -- State,
N'Inner error message');
END
GO
CREATE PROCEDURE dbo.sp_outer_ex AS
BEGIN
BEGIN TRY
EXEC dbo.sp_inner_ex
END TRY
BEGIN CATCH
DECLARE @error INT = ERROR_NUMBER()
PRINT 'Raising outer'
RAISERROR (@error, -- Message id.
11, -- Severity,
1, -- State,
N'Outer error message');
END CATCH
END
GO
EXEC dbo.sp_outer_ex
GO
sp_dropmessage @msgnum = 50005;
DROP PROCEDURE dbo.sp_inner_ex
DROP PROCEDURE dbo.sp_outer_ex
GO
预期产出:
Raising inner
Raising outer
Msg 50005, Level 11, State 1, Procedure sp_outer_ex, Line 42
Message given: << Outer error message>>
请记住以下内容:
sp_addmessage是邮件的ID。 msg_id是int,默认值为NULL。用户定义的错误消息的msg_id可以是50,001和2,147,483,647之间的整数。 msg_id和语言的组合必须是唯一的;如果指定语言的ID已存在,则返回错误。
您只能抛出自定义错误,而不是系统错误。
RAISERROR ...使用sp_addmessage存储在sys.messages目录视图中的用户定义的错误消息编号。用户定义的错误消息的错误号应大于50000.当未指定msg_id时,RAISERROR会引发错误消息,错误号为50000.