相关疑难解决方法(0)

带有输出的 MERGE 是否比条件插入和选择更好的做法?

我们经常会遇到“如果不存在,则插入”的情况。Dan Guzman 的博客对如何使此进程线程安全进行了出色的调查。

我有一个基本表,它只是将字符串从SEQUENCE. 在存储过程中,我需要获取该值的整数键(如果它存在),或者INSERT它然后获取结果值。该dbo.NameLookup.ItemName列有一个唯一性约束,因此数据完整性没有风险,但我不想遇到异常。

这不是一个IDENTITY所以我无法获得,SCOPE_IDENTITY并且NULL在某些情况下价值可能是。

在我的情况下,我只需要处理INSERT桌面上的安全问题,所以我试图决定是否使用MERGE这样的方法更好:

SET NOCOUNT, XACT_ABORT ON;

DECLARE @vValueId INT 
DECLARE @inserted AS TABLE (Id INT NOT NULL)

MERGE 
    dbo.NameLookup WITH (HOLDLOCK) AS f 
USING 
    (SELECT @vName AS val WHERE @vName IS NOT NULL AND LEN(@vName) > 0) AS new_item
        ON f.ItemName= new_item.val
WHEN MATCHED THEN
    UPDATE SET @vValueId = f.Id
WHEN NOT MATCHED BY TARGET THEN
    INSERT …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql merge sql-server-2014

12
推荐指数
2
解决办法
4890
查看次数

SQL Server 2014 并发输入问题

在表中Orders,我存储了我们从所有商店收到的订单。由于一个订单可以有多个行,列中有OrderIDOrderLineID 在那里OrderID可以复制,但OrderLineID必须是一个顺序中是唯一的。

由于订单可以修改,存储过程首先检查收到的订单OrderLineID是否已经存在于表中,然后决定插入还是更新。为此,我们:

  • 从 XML 输入动态构建插入和更新语句
  • 插入客户表
  • 插入到 shippingAddresses 表中

然后是主表:

IF NOT EXISTS (Select 1 from Orders where OrderLineID=@OrderLineID ......)
INSERT INTO Orders () VALUES ()
ELSE UPDATE Orders SET ... WHERE OrderLineID=@OrderLineID
Run Code Online (Sandbox Code Playgroud)

或者该MERGE功能是否提供更好的性能/控制?

但问题如下:

由于线路问题/服务器繁忙等,Order消息(或修改)可能会被多次发送,我们不知道按哪个顺序发送。因此,为了避免Order修改后到达,从而覆盖修改,我们添加了一个时间列:

IF NOT EXISTS (Select 1 from Orders where OrderLineID=@OrderLineID)
INSERT INTO Orders () VALUES ()
ELSE UPDATE Orders SET ... WHERE OrderLineID=@OrderLineID AND LastModified<@CreatedTime
Run Code Online (Sandbox Code Playgroud)

这样,如果后一条消息比前一条消息旧,则对表没有影响。

但是,消息及其修改可能会在很短的时间内发送两次(或更多),以至于后一条消息在保存前一条消息之前到达。因此,对于存储过程的两次执行,它 …

sql-server concurrency unique-constraint

5
推荐指数
1
解决办法
1191
查看次数