我试图插入一个对(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的忠实粉丝,我怎样才能让它更具可读性/更好的表现呢?
答案 0 :(得分:1)
MERGE语句是处理此类情况的SQL标准方法。
关系数据库管理系统使用SQL MERGE(也称为 upsert)语句来INSERT新记录或UPDATE现有记录 取决于条件是否匹配。这是正式的 在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.* ;
答案 1 :(得分:0)
在此查询中,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)