原文:【SQL Server学习笔记】Delete 语句、Output 子句、Merge语句


DELETE语句


  1. --建表
  2. select * into distribution
  3. from sys.objects
  4. --1.当delete语句要关联其他表时与update语句类似,可参考上面update语句的写法
  5. --2.truncate table语句删除行比delete快很多,不过必须一次删除所有的行(没有where子句)
  6. --之所以快是因为记录的日志很少,采用表级别锁。
  7. --如果表中有IDENTITY列,会被重置为列定义的种子值4、TOP--1.在一个事务中删除所有记录,此表的记录有1000w条
  8. delete from distribution
  9. --2.通过top每次只删除1000条记录
  10. while (select COUNT(*) from distribution) > 0
  11. begin
  12. delete top (1000)
  13. from distribution
  14. end
  15. /*===============================================================
  16. 比较1和2(不只限于delete,还包括update、insert),2有以下优点:
  17. 1.每次操作1000条,就提交一次,那么产生少量的日志,使日志空间更容易被重用;
  18. 如果一次删除大量记录,而产生的大量日志可能比整个日志文件还大,
  19. 那么会引起日志文件的自动增长,会影响性能
  20. 2.分块操作记录,一次锁住更少的记录,占用更少的锁资源,
  21. 锁定时间更短,操作完成后这些记录可被其他进程访问,并发性更好
  22. =================================================================*/

OUTPUT子句


  1. create table t(vid int not null,pic varchar(10) not null)
  2. insert into t
  3. values(1,'abc'),
  4. (2,'def'),
  5. (3,'hjkl')
  6. --output必须写在where子句之前
  7. update t
  8. set pic = 'xyz' --更新操作由删除+添加组合的
  9. output deleted.vid, --删除的记录
  10. deleted.pic,
  11. inserted.vid, --添加的记录
  12. inserted.pic
  13. where vid < 100
  14. --output写在values之前
  15. insert into t(vid,pic)
  16. output inserted.*
  17. values(5,'mn')
  18. declare @temp table(vid int,pic varchar(10))
  19. delete from t
  20. output deleted.vid, --引用所有字段deleted.*
  21. deleted.pic into @temp
  22. where vid < 100

output子句的一个应用,由于主表和附表是级联删除的,需要实现删除主表记录时,自动保存主表和附表中相关重要字段的值:


  1. --创建主表
  2. create table t1(id int primary key,v varchar(10))
  3. --创建附表,级联删除
  4. create table t2
  5. (
  6. idd int,
  7. id int foreign key references t1(id) on delete cascade,
  8. vv varchar(20)
  9. )
  10. insert into t1
  11. select 1,'a' union all
  12. select 2,'b'
  13. insert into t2
  14. select 1,1,'www' union all
  15. select 1,2,'csdn'
  16. --创建存储删除的t1表的字段
  17. create table temp_t1_delete(id int,v varchar(10))
  18. --创建存储删除的t2表的字段
  19. create table temp_t2_delete(id int,vv varchar(20))
  20. go
  21. --创建表t2的delete触发器
  22. create trigger dbo.trigger_t2_delete
  23. on dbo.t2
  24. for delete
  25. as
  26. begin
  27. insert into temp_t2_delete(id,vv)
  28. select id,vv
  29. from deleted
  30. end
  31. go
  32. --删除主表记录,自动把删除的主表记录,保存在temp_t1_deletei表中
  33. delete from t1
  34. output deleted.id, --引用所有字段deleted.*
  35. deleted.v into temp_t1_delete
  36. where id = 1
  37. --查询已删除的记录
  38. select *
  39. from temp_t1_delete t1
  40. left join temp_t2_delete t2
  41. on t1.id = t2.id
  42. /*
  43. id v id vv
  44. 1 a 1 www
  45. */

MERGE语句


  1. create table t_org(org_id int,
  2. v1 varchar(20),
  3. v2 varchar(30));
  4. insert into t_org
  5. select 1,'org1',''
  6. union all
  7. select 2,'org2','name2'
  8. union all
  9. select 3,'org3','name3'
  10. union all
  11. select 4,'org4','name4'
  12. union all
  13. select 5,'org5','name5'
  14. create table t_store(org_id int,
  15. v1 varchar(20),
  16. v2 varchar(30));
  17. insert into t_store
  18. select 1,'org1',''
  19. union all
  20. select 2,'org2-t','name2-t'
  21. union all
  22. select 3,'org3-t','name3-t'
  23. union all
  24. select 4,'org4-t','name4-t'
  25. union all
  26. select 5,'org5-t','name5-t'
  27. union all
  28. select 6,'org6-t','name6-t'
  29. union all
  30. select 7,'org7-t','name7-t'
  31. --生成临时表
  32. select * into #t_org from t_org
  33. select * into #t_store from t_store
  34. --定义表变量
  35. declare @delete_insert_t_org table(
  36. change nvarchar(100),
  37. org_id int,v1 varchar(20),v2 varchar(30), --删除的
  38. org_id_t int,v1_t varchar(20),v2_t varchar(30)) --添加的
  39. ;with mm --作为merge语句中using的内部派生表
  40. as
  41. (
  42. select m.org_id,
  43. m.v1,
  44. m.v2
  45. from #t_store m
  46. where m.org_id >1
  47. )
  48. --注意:表 with(tablock),另外通过top关键字只是处理3条记录
  49. merge top (3) into #t_org with (tablock) as b
  50. using (
  51. select *
  52. from mm with (tablock) --引用上面CTE公用表表达式产生的内部派生表
  53. ) m
  54. on m.org_id = b.org_id --为了区分是否需要修改,可以增加一个字段来区分,
  55. --但是这个字段不应该作为关联条件,
  56. --因为会导致接下来运行的merge分块语句把刚才目标表中update过的那条记录,
  57. --重复插入目标表中,而是写在when的条件中
  58. when matched and b.v1 <> m.v1 and isnumeric(m.org_id) = 1 --可以在这里写:区分字段过滤条件
  59. then update set v1 = m.v1,v2 = m.v2
  60. when not matched by target --目标表中没有
  61. then insert (org_id,v1,v2) values(m.org_id,m.v1,m.v2) --不可通过values关键字一次添加多列
  62. when not matched by source --源表中没有
  63. then delete
  64. output $action, --操作:delete、insert、update
  65. inserted.org_id,
  66. inserted.v1,
  67. inserted.v2 , --可改为inserted.*
  68. deleted.org_id,
  69. deleted.v1,
  70. deleted.v2 --可改为deleted.*
  71. INTO @delete_insert_t_org --output的输出放入表变量中
  72. --关联提示
  73. option (loop join); --注意:merge必须以分号结尾
  74. select * from @delete_insert_t_org
发布了416 篇原创文章 · 获赞 135 · 访问量 94万+

【SQL Server学习笔记】Delete 语句、Output 子句、Merge语句的更多相关文章

  1. SQL server 学习笔记1

    1.查询安装的排序规则选项喝当前的排序规则服务器属性 select * from fn_helpcollations(); 2.查看当前服务器的排序规则 select serverproperty(' ...

  2. sql server 学习笔记 ( backup 备份方案 )

    做个记入就好 USE [master] SELECT bs.database_name AS 'Database Name', bs.backup_start_date AS 'Backup Star ...

  3. 【SQL Server学习笔记】事务、锁定、阻塞、死锁 sys.sysprocesses

    http://blog.csdn.net/sqlserverdiscovery/article/details/7712068 Column name Data type Description   ...

  4. SQL SERVER学习笔记:临时表与表变量

    本文主要摘自徐海蔚的<Microsoft SQL SERVER企业级平台管理实践> 表变量可以作为存储过程的返回参数,而临时表不行.(存疑?表值参数只在SQL SERVER2008才开始支 ...

  5. sql server 学习笔记 (nested transaction 嵌套事务)

    什么时候会用到嵌套事务 ? 为了代码复用,我们会写许多的储蓄过程,而中间如果需要使用到 transaction 难免就会发生嵌套了. sql server 并不直接支持嵌套事务. 但它可以用一些招式来 ...

  6. Sql Server学习笔记

    1.指定路径创建数据库 create database student on--创建库的时候必须写 ( name=student, filename='E:\database\student.mdf' ...

  7. sql server 学习笔记 ( row_number, rank, dense_rank over partition by order by )

    refer : https://blog.csdn.net/winer2008/article/details/4283539 https://www.cnblogs.com/linJie193090 ...

  8. sql server 学习笔记

    1. 修改student表中sdept字段改为varchar类型,长度为30,并且不为空 ) not null 2. 删除student表中的address列 alter table student ...

  9. 【SQL SERVER学习笔记】Sqlserver游标的尝试

    DECLARE @ProName NVARCHAR(50)DECLARE @CityName NVARCHAR(50)DECLARE @ProId INT DECLARE @CityId INT DE ...

随机推荐

  1. 神经网络模型(Backbone)

    自己搭建神经网络时,一般都采用已有的网络模型,在其基础上进行修改.从2012年的AlexNet出现,如今已经出现许多优秀的网络模型,如下图所示. 主要有三个发展方向: Deeper:网络层数更深,代表 ...

  2. Linux shell脚本 (十二)case语句

    case语句 case ... esac 与其他语言中的 switch ... case 语句类似,是一种多分枝选择结构. case 语句匹配一个值或一个模式,如果匹配成功,执行相匹配的命令.case ...

  3. MySQL查询获取行号rownum

    MySQL中可以使用变量产生行号,下面是2个简单例子: 使用工具:MySQL Workbench 说明:表heyf_10中字段,empid(员工工号).deptid(部门编号).salary(薪资): ...

  4. Web安全测试检查点

    Web安全测试检查点 上传功能 1.绕过文件上传检查功能 2.上传文件大小和次数限制 注册功能 1.注册请求是否安全传输 2.注册时密码复杂度是否后台检验 3.激活链接测试 4.重复注册 5.批量注册 ...

  5. 你真的懂wait、notify和notifyAll吗

    生产者消费者模型是我们学习多线程知识的一个经典案例,一个典型的生产者消费者模型如下: public void produce() { synchronized (this) { while (mBuf ...

  6. Linux交换空间(swap space)的那些优缺点

    下面的所有例子都在ubuntu-server-x86_64 16.04下执行通过 什么是swap? swap space是磁盘上的一块区域,可以是一个分区,也可以是一个文件,或者是他们的组合.简单点说 ...

  7. centos6.8下配置vsftp

    几个小时的调试 终于OK了 以下配置就算开了selinux 也照样能正常上传 注意 默认的上传目录 在 /home/用户名目录 如果不能下载文件 设置下文件的权限 一.安装VSFTP # yum -y ...

  8. 【Leetcode_easy】687. Longest Univalue Path

    problem 687. Longest Univalue Path 参考 1. Leetcode_easy_687. Longest Univalue Path; 2. Grandyang; 完

  9. python 全栈开发之旅

    目录 python 基础语法 python 数据类型(未完成) python 内置函数(未完成) python 常用标准库(未完成) python 类(未完成) python 进程.线程.协程(未完成 ...

  10. 第一次打开PyCharm的基本操作(附图)

    第一次打开PyCharm可能需要修改一些个性化和了解一些基本操作,有助于接下来的学习过程.(后续可能会更新) 我的版本是64位的1.3 1.换界面皮肤 默认黑色的,不喜欢黑色皮肤可以换成白色的 Fil ...