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

来源:互联网 发布:c语言内嵌汇编 64位 编辑:程序博客网 时间:2024/05/29 12:15

DELETE语句

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



OUTPUT子句 

create table t(vid int not null,pic varchar(10) not null)insert into tvalues(1,'abc'),      (2,'def'),      (3,'hjkl')--output必须写在where子句之前update tset pic = 'xyz'       --更新操作由删除+添加组合的output deleted.vid,   --删除的记录       deleted.pic,              inserted.vid,  --添加的记录       inserted.picwhere vid < 100--output写在values之前insert into t(vid,pic)output inserted.*values(5,'mn')declare @temp table(vid int,pic varchar(10))delete from toutput deleted.vid,            --引用所有字段deleted.*       deleted.pic into @tempwhere vid < 100


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

--创建主表create table t1(id int primary key,v varchar(10))--创建附表,级联删除create table t2(idd int,id int foreign key references t1(id) on delete cascade,vv varchar(20))insert into t1select 1,'a' union allselect 2,'b' insert into t2select 1,1,'www' union allselect 1,2,'csdn'--创建存储删除的t1表的字段create table temp_t1_delete(id int,v varchar(10))--创建存储删除的t2表的字段create table temp_t2_delete(id int,vv varchar(20))  go--创建表t2的delete触发器create trigger dbo.trigger_t2_delete on dbo.t2for deleteasbegin   insert into temp_t2_delete(id,vv)   select id,vv   from deletedendgo--删除主表记录,自动把删除的主表记录,保存在temp_t1_deletei表中  delete from t1  output deleted.id,            --引用所有字段deleted.*         deleted.v into temp_t1_deletewhere id = 1 --查询已删除的记录select *from temp_t1_delete t1left join temp_t2_delete t2       on t1.id = t2.id/*idvidvv1a1www*/


MERGE语句

create table t_org(org_id int,                   v1 varchar(20),                   v2 varchar(30));                   insert into t_orgselect 1,'org1',''union allselect 2,'org2','name2'union allselect 3,'org3','name3'union allselect 4,'org4','name4'union allselect 5,'org5','name5'create table t_store(org_id int,                     v1 varchar(20),                     v2 varchar(30));insert into t_storeselect 1,'org1',''union allselect 2,'org2-t','name2-t'union allselect 3,'org3-t','name3-t'union allselect 4,'org4-t','name4-t'union allselect 5,'org5-t','name5-t'union allselect 6,'org6-t','name6-t'union allselect 7,'org7-t','name7-t'--生成临时表select * into #t_org from t_orgselect * into #t_store from t_store--定义表变量declare @delete_insert_t_org table(           change nvarchar(100),               org_id int,v1 varchar(20),v2 varchar(30),        --删除的           org_id_t int,v1_t varchar(20),v2_t varchar(30))  --添加的;with mm   --作为merge语句中using的内部派生表as(     select m.org_id,            m.v1,            m.v2     from #t_store m     where m.org_id >1) --注意:表 with(tablock),另外通过top关键字只是处理3条记录merge top (3) into #t_org with (tablock) as b  using (         select *         from mm with (tablock)  --引用上面CTE公用表表达式产生的内部派生表      ) m    on m.org_id = b.org_id      --为了区分是否需要修改,可以增加一个字段来区分,                               --但是这个字段不应该作为关联条件,                               --因为会导致接下来运行的merge分块语句把刚才目标表中update过的那条记录,                               --重复插入目标表中,而是写在when的条件中                                   when matched and b.v1 <> m.v1 and isnumeric(m.org_id) = 1  --可以在这里写:区分字段过滤条件     then update set v1 = m.v1,v2 = m.v2 when not matched by target  --目标表中没有     then insert (org_id,v1,v2) values(m.org_id,m.v1,m.v2)  --不可通过values关键字一次添加多列          when not matched by source  --源表中没有     then delete output  $action,            --操作:delete、insert、update        inserted.org_id,        inserted.v1,        inserted.v2  ,      --可改为inserted.*                        deleted.org_id,        deleted.v1,        deleted.v2          --可改为deleted.*                                    INTO @delete_insert_t_org   --output的输出放入表变量中--关联提示        option (loop join);    --注意:merge必须以分号结尾       select * from @delete_insert_t_org

 

 

原创粉丝点击