最近发布的脚本,有那种防止重复插入数据(包括存在时更新,不存在是插入的处理,判断的方向可能与下面的示例相反)

使用类似下面的 SQL

declare @id int, @value int

if not exists( select * from tb where id = @id )

insert tb values( @id, @value );

--else

--  update tb set value = @value where id = @id;

或者是使用这种单句的

declare @id int, @value int

insert tb select @id, @value

where not exists( select * from tb where id = @id )

--if @@rowcount = 0

--  update tb set value = @value where id = @id;

或者是用 MERGE 的

declare @id int, @value int

merge tb

using( values(@id, @value) ) data( id, value)

on data.id = tb.id

when not matched by target then insert values( id, value )

--when matched then update set value = data.value

;

这几种方法均已说明是无法防止插入重复数据的,只是发生的概率高低有一定的区别而已

针对这种处理需求,我专门做了一些测试,有效的处理方法如下,大家在处理这类问题时,请参考此方法进行:

declare @id int, @value int

begin tran  -- 使查询的更新锁保留到事务结束

if not exists( select * from tb with(holdlock, updlock) where id = @id )

insert tb values( @id, @value );

--else

--  update tb set value = @value where id = @id;

commit tran

推荐使用这种单句的处理方式,不用显式的事务控制,避免考虑与其他会显式使用事务的地方的交互性

declare @id int, @value int

insert tb select @id, @value

where not exists( select * from tb with(holdlock, updlock) where id = @id )

--if @@rowcount = 0

--  update tb set value = @value where id = @id;

不推荐这种方式,容易出来死锁

declare @id int, @value int

merge tb with(holdlock, updlock)

using( values(@id, @value) ) data( id, value)

on data.id = tb.id

when not matched by target then insert values( id, value )

--when matched then update set value = data.value

另外,where 这个判断是否重复的条件列,需要创建索引,否则因为锁的关系,数据处理的效率会极低

如果表中本来就没有重复数据,应该直接建立唯一索引(UNIQUE INDEX),这个对于查询优化有很大的帮助

SQl server 关于重复插入数据的测试的更多相关文章

  1. 删除sql server中重复的数据

    原文:删除sql server中重复的数据 with list_numbers as( select Name, AuthorOrTime, Url, Price, EstimatePrice, Si ...

  2. SQL Server 2008 批量插入数据时报错

    前几天在SQL Server 2008同步产品数据时,总是提示二进制文本被截断的错误,但是经过检查发现数据都符合格式要求. 百思不得其解,单独插入一条条数据则可以插入,但是批量导入则报错. 批量导入代 ...

  3. 使用变量向SQL Server 2008中插入数据

    QT通过ODBC连接数据库SQL Server 2008,进行数据插入时遇到的问题: 先把数据存入变量中,如何使用变量进行插入?插入语句该怎么写? QSqlQuery query(db); query ...

  4. SQL Server TVPs 批量插入数据

    在SQL Server 中插入一条数据使用Insert语句,但是如果想要批量插入一堆数据的话,循环使用Insert不仅效率低,而且会导致SQL一系统性能问题.下面介绍SQL Server支持的两种批量 ...

  5. sql server 小技巧(2) 删除sql server中重复的数据

    with list_numbers as ( select Name, AuthorOrTime, Url, Price, EstimatePrice, Size, Category, ROW_NUM ...

  6. SQL server 跨库插入数据

    1.INSERT INTO SELECT语句 语句形式为: Insert into Table2(field1,field2,...) select value1,value2,... from Ta ...

  7. sql server 跨数据库插入数据

    创建服务器的连接,创建好后可以存在服务器上,可以在不同位置重复使用,和系统函数类似 exec sp_addlinkedserver 'RemoteServer', '', 'SQLOLEDB ', ' ...

  8. SQL Server 向临时表插入数据

    INSERT INTO #DirtyOldWIPBOM SELECT TOP (100) PERCENT dbo.WIP_BOM.Model, dbo.WIP_BOM.PartNumber,WIP_B ...

  9. SQL SERVER 2008 R2 插入数据非常慢

    表是5字段int类型,第一个字段是主健,自增字段 表结构: id int  Uncheckedbillno bigint  Uncheckedopid int  Checkedbillopid int ...

随机推荐

  1. linux小程序--cmatrix

    wget http://www.asty.org/cmatrix/dist/cmatrix-1.2a.tar.gz .2a.tar.gz cd cmatrix-.2a yum install ncur ...

  2. zTree开发下拉树

    最近,因为工作需要一个树形下拉框的组件,经过查资料一般有两种的实现方法.其一,就是使用zTree实现:其二,就是使用easyUI实现.因为公司的前端不是使用easyUI设计的,故这里我选择了zTree ...

  3. 删除ubuntu后无法进入windows

    一天,脑袋一热想装个ubuntu学习学习,结果装的ubuntu版本比较老,没有集成我笔记本的网卡驱动,在ubuntu下上不了网,心想上不了网学习起来不是很不方便,于是就直接在win7下将ubuntu的 ...

  4. sharepoint webpart

    SharePoint开发中,不仅仅是WebPart,我们都经常会使用的几个关键位置,如下: GAC: C:\Windows\assembly,也就是部署的位置: ISAPI位置,SharePoint ...

  5. session和cookie工作原理说明

    session 第一次请求: session_start 1.第一次发送http请求,由于第一次未携带session_id ,首先自动生成一个session_id,初始化$_SESSION[]; 2. ...

  6. c/c++创建动态链接库

    extern "C" C++保留了一部分过程式语言的特点,因而它可以定义不属于任何类的全局变量和函数.但是,C++毕竟是一种面向对象的程序设计语言,为了支持函数的重载,C++对全局 ...

  7. c++继承概念

    蠢了3年了,在找工作的今天明白了何为继承……呵呵呵…… 3种继承方式:public.protected.private. 注意几点: 1.继承只能继承基类的public和protected成员 2.3 ...

  8. centos7安装数据库

    centos7的yum源中貌似没有正常安装MySQL时的mysql-server. 那么就需要从官网下载了. 下面是安装mysql的命令: # wget http://dev.mysql.com/ge ...

  9. lua 代码风格

    参考  http://www.kancloud.cn/kancloud/lua_style_guide/66327 1.命名 1.命名法:小驼峰命名法,大驼峰命名法(Pascal命名法),小下划线命名 ...

  10. Spring bean 实现初始化、销毁方法的方式及顺序

    Spring 允许 Bean 在初始化完成后以及销毁前执行特定的操作,常用方法有三种: 使用注解,在指定方法上加上@PostConstruct或@PreDestroy注解来制定该方法是在初始化之后还是 ...