Sql server 2012 为什么使用Throw的自定义异常不执行next语句,而表约束异常执行它
我有一个带有Id smallint和Code varchar5字段的表,代码上有一个唯一的键约束。 表中的代码字段中已经有一行带有“ABC” 我编写了以下存储过程来向其中插入值Sql server 2012 为什么使用Throw的自定义异常不执行next语句,而表约束异常执行它,sql-server-2012,Sql Server 2012,我有一个带有Id smallint和Code varchar5字段的表,代码上有一个唯一的键约束。 表中的代码字段中已经有一行带有“ABC” 我编写了以下存储过程来向其中插入值 ALTER Procedure [dbo].[Insert] @Id smallint output, @Code varchar(5) AS SET NOCOUNT OFF;
ALTER Procedure [dbo].[Insert]
@Id smallint output,
@Code varchar(5)
AS
SET NOCOUNT OFF;
IF not EXISTS (select Code from SomeTable where Code like '%'+@Code and Code <> @Code)
BEGIN
Insert into dbo.SomeTable (Code) values (@Code)
END
ELSE
BEGIN
Throw 50000,'Violation of UNIQUE KEY constraint. Cannot insert Code which is already a suffix of existing Code in table ''dbo.SomeTable''.',1
END
Select Id,Code from dbo.SomeTable where SomeTableCode = 'ABC'
我得到以下例外情况:
Msg 2627, Level 14, State 1, Procedure Insert, Line 19
Violation of UNIQUE KEY constraint 'IX_SomeTable_1'. Cannot insert duplicate key in object 'dbo.SomeTable'. The duplicate key value is (ABC).
The statement has been terminated.
(1 row(s) affected)
我可以看到结果选项卡select语句中执行的行
但当我尝试使用以下语句将代码作为后缀插入表中的其他代码时:
DECLARE @return_value int,
@Id smallint
EXEC @return_value = [dbo].[Insert]
@Id = @Id OUTPUT,
@Code = N'BC'
我收到以下错误,但Select语句未执行,并且在“结果”选项卡中看不到行,为什么
Msg 50000, Level 16, State 1, Procedure Insert, Line 24
Violation of UNIQUE KEY constraint. Cannot insert Code which is already a suffix of existing Code in table 'dbo.SomeTable'.
依照
如果TRY…CATCH构造不可用,则会话将结束
您没有使用TRY/CATCH,因此抛出将停止存储过程的执行
一般来说,这个Paytern是不可靠的
两个并发会话都可以发现不存在,但只有一个插入可以成功。使用合并
抛出显示已经存在或作为后缀存在,实际上不是违反
不要尝试/抓住
编辑,使用类似
BEGIN TRY
MERGE into dbo.SomeTable
etc
END TRY
BEGIN CATCH
DECLARE @errmsg nvarchar(2000);
IF ERROR_NUMBER() = 2627
SET @errmsg = 'Already exists etc'
ELSE
SET @errmsg = ERROR_MESSAGE();
THROW 50000, @errmsg, 1;
END CATCH
SELECT Id,Code from dbo.SomeTable where SomeTableCode = 'ABC';
完整阅读我可以对抛出异常和执行下一条语句进行哪些更改?
BEGIN TRY
MERGE into dbo.SomeTable
etc
END TRY
BEGIN CATCH
DECLARE @errmsg nvarchar(2000);
IF ERROR_NUMBER() = 2627
SET @errmsg = 'Already exists etc'
ELSE
SET @errmsg = ERROR_MESSAGE();
THROW 50000, @errmsg, 1;
END CATCH
SELECT Id,Code from dbo.SomeTable where SomeTableCode = 'ABC';