【发布时间】:2015-08-04 23:15:40
【问题描述】:
我在许多存储过程中都有这种模式
-- Table1
[id] [int] IDENTITY(1,1) NOT NULL
[data] [varchar](512) NULL
[count] INT NULL
-- 'data' is unique, with a unique index on 'data' in 'Table1'
BEGIN TRY
INSERT INTO Table1 (data, count) SELECT @data,1;
END TRY
BEGIN CATCH
UPDATE Table1 SET count = count + 1 WHERE data = @data;
END CATCH
before 因使用这种模式而受到抨击
在您的正常逻辑流程中,您永远不应该“捕获”异常。 (因此为什么它被称为“异常”..它应该是异常的(罕见的)。在您的 INSERT 周围放置一个存在检查。“如果不存在(从 Data where data = @data 中选择 null)开始 /* 在此处插入 */结束
但是,在这种情况下,我看不到解决方法。考虑以下替代方法。
INSERT INTO Table1 (data,count)
SELECT @data,1 WHERE NOT EXISTS
(SELECT 1 FROM Table1 WHERE data = @data)
如果我这样做,则意味着每个插入都是唯一的,但我无法“捕获”更新条件。
DECLARE @id INT;
SET @id = (SELECT id FROM Table1 WHERE data = @data)
IF(@id IS NULL)
INSERT INTO Table1 (data, count) SELECT @data,1;
ELSE
UPDATE Table1 SET count = count + 1 WHERE data = @data;
如果我这样做,我会在检查和插入之间出现竞争条件,所以我可以插入重复项。
BEGIN TRANSACTION
DECLARE @id INT;
SET @id = (SELECT id FROM Table1 WHERE data = @data)
IF(@id IS NULL)
INSERT INTO Table1 (data, count) SELECT @data,1;
ELSE
UPDATE Table1 SET count = count + 1 WHERE data = @data;
END TRANSACTION
如果我将其包装在 TRANSACTION 中,则会增加更多开销。我知道TRY/CATCH 也会带来开销,但我认为 TRANSACTION 增加了更多 - 有人知道吗?
人们一直告诉我在正常的应用逻辑中使用TRY/CATCH 是不好,但不会告诉我为什么
注意:我至少在一个机器上运行 SQL Server 2005,所以我不能使用MERGE
【问题讨论】:
-
你刚刚杀死了我想到的第一个答案,即合并。 :)
标签: sql-server exception try-catch upsert