热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

避免插入SQLSERVER上的唯一冲突-AvoiduniqueconflictsoninsertSQLSERVER

Imtryingtoinsertintoatablethathasuniqueconstrainton(ProductType,ProductOwnerid)inaw

I'm trying to insert into a table that has unique constraint on (ProductType, ProductOwnerid) in a way that when that key already exists that the contraint violation would not be triggered. So I have this SQL that works as intended:

我正在尝试插入一个对(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)

Is this decent SQL or how could I improve this? I'm not a big fan of the TOP 1, how can I make this more readable/better performing?

这是不错的SQL还是我怎么能改进这个?我不是TOP 1的忠实粉丝,我怎样才能让它更具可读性/表现更好?

2 个解决方案

#1


1  

The MERGE statement is the SQL standard way to handle such cases.

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

A relational database management system uses SQL MERGE (also called upsert) statements to INSERT new records or UPDATE existing records depending on whether or not a condition matches. It was officially introduced in the SQL:2003 standard, and expanded in the SQL:2008 standard.

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

It is a little bit more verbose than your solution but I find it more readable. Also, the intention of the code is very clear since the MERGE statement is specialized in dealing with this exact scenario.

它比你的解决方案更冗长,但我觉得它更具可读性。此外,代码的意图非常明确,因为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


0  

In this query, distinct will also work in place of top 1

在此查询中,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)

推荐阅读
  • Windows7 64位系统安装PLSQL Developer的步骤和注意事项
    本文介绍了在Windows7 64位系统上安装PLSQL Developer的步骤和注意事项。首先下载并安装PLSQL Developer,注意不要安装在默认目录下。然后下载Windows 32位的oracle instant client,并解压到指定路径。最后,按照自己的喜好对解压后的文件进行命名和压缩。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文讨论了在使用sp_msforeachdb执行动态SQL命令时,当发生错误时如何捕获数据库名称。提供了两种解决方案,并介绍了如何正确使用'?'来显示数据库名称。 ... [详细]
  • PDO MySQL
    PDOMySQL如果文章有成千上万篇,该怎样保存?数据保存有多种方式,比如单机文件、单机数据库(SQLite)、网络数据库(MySQL、MariaDB)等等。根据项目来选择,做We ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • 本文介绍了Oracle存储过程的基本语法和写法示例,同时还介绍了已命名的系统异常的产生原因。 ... [详细]
  • 解决.net项目中未注册“microsoft.ACE.oledb.12.0”提供程序的方法
    在开发.net项目中,通过microsoft.ACE.oledb读取excel文件信息时,报错“未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序”。本文提供了解决这个问题的方法,包括错误描述和代码示例。通过注册提供程序和修改连接字符串,可以成功读取excel文件信息。 ... [详细]
  • Postgresql备份和恢复的方法及命令行操作步骤
    本文介绍了使用Postgresql进行备份和恢复的方法及命令行操作步骤。通过使用pg_dump命令进行备份,pg_restore命令进行恢复,并设置-h localhost选项,可以完成数据的备份和恢复操作。此外,本文还提供了参考链接以获取更多详细信息。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • IOS开发之短信发送与拨打电话的方法详解
    本文详细介绍了在IOS开发中实现短信发送和拨打电话的两种方式,一种是使用系统底层发送,虽然无法自定义短信内容和返回原应用,但是简单方便;另一种是使用第三方框架发送,需要导入MessageUI头文件,并遵守MFMessageComposeViewControllerDelegate协议,可以实现自定义短信内容和返回原应用的功能。 ... [详细]
author-avatar
百变精灵2596
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有