【问题标题】:Avoid unique conflicts on insert SQL SERVER避免插入 SQL SERVER 上的唯一冲突
【发布时间】:2015-05-18 10:05:02
【问题描述】:

我正在尝试插入一个对 (ProductType, ProductOwnerid) 具有唯一约束的表,当该键已经存在时,不会触发约束冲突。所以我有这个按预期工作的 SQL:

INSERT INTO dbo.Products (ProductType, ProductOwnerId)
SELECT TOP 1 22, 44  FROM dbo.products prods
WHERE NOT EXISTS (
    SELECT prods2.ProductType FROM dbo.products prods2 
    WHERE prods2.ProductType = 22 AND prods2.ProductOwnerId = 44)

这是不错的 SQL 还是我该如何改进?我不是 TOP 1 的忠实粉丝,我怎样才能使它更具可读性/性能更好?

【问题讨论】:

  • 22 和 44 是否仅用于演示,或者这两个始终在您的查询中?否则这没有任何意义。
  • 你为什么想要一个永远不会触发的约束。然后删除它。
  • 改用 MERGE。
  • 你也可以选择If select count ... = 0 Then Insert...。这至少会使其更具可读性。
  • 22 和 44 仅用于演示目的,在生产中使用参数化查询/命令

标签: sql sql-server performance database-performance


【解决方案1】:

MERGE 语句是处理此类情况的 SQL 标准方法。

关系数据库管理系统使用 SQL MERGE(也称为 upsert) 语句插入新记录或更新现有记录 取决于条件是否匹配。是正式的 在 SQL:2003 标准中引入,并在 SQL:2008 中扩展 标准。

它比您的解决方案更冗长,但我发现它更具可读性。此外,代码的意图非常明确,因为 MERGE 语句专门处理这种情况。

CREATE TABLE products (
    ProductId INT IDENTITY(1, 1), 
    ProductType int, ProductOwnerId INT, 

    CONSTRAINT [unq_type_owner] UNIQUE (ProductType, ProductOwnerId)
);

MERGE INTO dbo.products p
USING (VALUES (22, 44))  AS source(ProductType, ProductOwnerId)
ON p.ProductType = source.ProductType AND p.ProductOwnerId = source.ProductOwnerId

WHEN NOT MATCHED THEN
    INSERT (ProductType, ProductOwnerId)
    VALUES (source.ProductType, source.ProductOwnerId)

-- OPTIONAL OUTPUT
OUTPUT $action, Inserted.* ;

【讨论】:

    【解决方案2】:

    在这个查询中,distinct 也可以代替 top 1

    INSERT INTO dbo.Products (ProductType, ProductOwnerId)
        SELECT DISTINCT 22, 44  
        FROM dbo.products prods
        WHERE NOT EXISTS (SELECT prods2.ProductType 
                          FROM dbo.products prods2 
                          WHERE prods2.ProductType = 22 AND prods2.ProductOwnerId = 44)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-16
      • 1970-01-01
      • 2019-11-01
      • 2014-10-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多