原文:【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. Mac 中使用phpstorm 修改文件提示"only read",只读权限

    在终端中执行命令: 给max系统用户liutao赋予整个项目文件权限,即可成功 sudo chown -R liutao /Users/liutao/Desktop/vagrant/newprojec ...

  2. ISO/IEC 9899:2011 条款6.4.2——标识符

    6.4.2 标识符 6.4.2.1 通用 语法 1.identifier: identifier-nodigit identifier    identifier-nondigit identifie ...

  3. React Native 中的 Flex Box 的用法(水平布局、垂直布局、水平居中、垂直居中、居中布局)

     版权声明:本文仅供个人学习. CSS 中 Flex-Box 语法链接 http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html Flex 是 ...

  4. IE和火狐的css兼容性问题

     CSS对浏览器器的兼容性具有很高的价值,通常情况下IE和Firefox存在很大的解析差异,这里介绍一下兼容要点. 1.DOCTYPE 影响 CSS 处理 2.FF: div 设置 margin-le ...

  5. iOS-UIView的layoutSubviews和drawRect方法何时调用(转)

    转自:http://jianyu996.blog.163.com/blog/static/112114555201305113018814/ 首先两个方法都是异步执行.layoutSubviews方便 ...

  6. TCP通信的文件上传案例

  7. stub_status监控Nginx使用情况!

    stub_status监控Nginx使用情况! 查看nginx安装的模块! # /usr/local/nginx/sbin/nginx -V nginx version: nginx/1.8.1 bu ...

  8. vue element-ui typescript tree报错 === Property 'getCheckedNodes' does not exist on type 'Element | Element[] | Vue | Vue[]'.

    import { Tree } from 'element-ui' const ref = <Tree>this.$refs.tree ref.getCheckedNodes()

  9. ASP.NET请求过程-Handler

    什么事Handler asp.net程序所有的请求都是handler处理的.以前的webform我们访问的地址是xxxxx.aspx地址,其实他也会到一个handler(我们写的业务代码都在handl ...

  10. C++ 日志库 boost::log 以及 glog 的对比

    日志能方便地诊断程序原因.统计程序运行数据,是大型软件系统必不可少的组件之一.本文将从设计上和功能上对比 C++ 语言常见的两款日志库: boost::log 和 google-glog . 设计 b ...