你的主要问题是你抓到了错误的类型。
你需要抓住
Microsoft.Data.SqlClient.SqlException
而不是
System.Data.SqlClient.SqlException
。
此外,您的过程的错误处理还有很多不足之处:
-
使用
THROW
而不是
RAISERROR
。
-
设置
XACT_ABORT
将来
ON
以便更好地处理错误。错误将强制立即终止批处理或过程。
-
移除
BEGIN CATCH
块它没有做任何有用的事情,只会扰乱异常流,并导致某些类型的错误被错误地吞噬或返回。
-
在整个过程中使用实际事务,以确保一致性。
-
因此,这需要
UPDLOCK
上的锁定提示
SELECT
查询
-
而不是更改为
UPPER
使用
COLLATE someCaseInsensitiveCollationHere
。甚至更好:更改列的实际排序规则。
CREATE PROCEDURE CivilStatusSave
@CivilStatusId CHAR(1),
@CivilStatusName NVARCHAR(15),
@CreateBy NVARCHAR(60),
@CreationDate DATETIME,
@ModifiedBy NVARCHAR(60),
@ModifiedDate DATETIME
AS
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET NOCOUNT, XACT_ABORT ON;
BEGIN TRAN;
IF EXISTS (SELECT 1
FROM CivilStates AS cs WITH (UPDLOCK)
WHERE cs.CivilStatusId = @CivilStatusId)
BEGIN
THROW 50001, 'Ya se encuentra un registro en el sistema, con este codigo', 1;
END;
IF EXISTS (SELECT 1
FROM CivilStates AS cs WITH (UPDLOCK)
WHERE cs.CivilStatusName = @CivilStatusName COLLATE Latin1_General_100_CI_AI
BEGIN
THROW 50002, 'Ya se encuentra un registro en el sistema, con este estado civil', 2;
END;
INSERT INTO CivilStates
(CivilStatusId, CivilStatusName, CreateBy,
CreationDate, ModifiedBy, ModifiedDate)
OUTPUT inserted.CivilStatusId, inserted.CivilStatusName,
inserted.CreateBy, inserted.CreationDate,
inserted.ModifiedBy, inserted.ModifiedDate
VALUES (@CivilStatusId, @CivilStatusName, @CreateBy,
@CreationDate, @ModifiedBy, @ModifiedDate);
COMMIT;
老实说,理论上,您可以仅依靠唯一/主键来强制执行条件,尽管错误消息不太容易理解。