SQL Server2008 Merge应用实例(Merge执行统计库存,复制表,输出$action列 ,output...INTO..)

--SQL Server2008 Merge应用实例 
       
/********************************************************************************        
 *主题:SQL Server2008 Merge应用实例 
 *说明:本文是个人学习的一些笔记和个人愚见        
 *      有很多地方你可能觉得有异议,欢迎一起讨论        
        
 *作者:Stephenzhou(阿蒙)        
 *日期: 2012.12.5
    
 *Mail:[email protected]        
 *另外:转载请著名出处。        
**********************************************************************************/    


先不解释 看实例吧

有两个表如下

 

 

if OBJECT_ID('Stock') is not null
drop table Stock 
go
create table Stock (Symbol varchar(10) primary key,Qty int check(Qty>0))
if OBJECT_ID('Trade') is not null
drop table Trade 
go
create table Trade (Symbol varchar(10) primary key,Delta int check(Delta<>0))

--两个表,第一个表Stock为库存表  ,Trade为交易记录表

--库存表的记录为:

insert into Stock values('ADVW',10)
insert into Stock values('BYA',5)



--增加三条交易记录,

insert into Trade values('ADVW',5)
insert into Trade values('BYA',-5)
insert into Trade values('NWT',3)


查询两表的内容


select * from Stock
select * from Trade

Symbol     Qty
---------- -----------
ADVW       10
BYA        5

(2 行受影响)

Symbol     Delta
---------- -----------
ADVW       5
BYA        -5
NWT        3

(3 行受影响)

 

在交易的时候就应该会影响到库存,这时候就用了merge 。等下我们还要用传统方法来处理然后对比下

 


 

merge Stock 
using Trade
on Stock.Symbol=Trade.Symbol
when matched and (Stock.Qty+Trade.Delta=0) then --就是如果交易和库存一样的话就删除这条记录
DELETE
when matched then 
UPDATE SET Stock.Qty+=Trade.Delta  --有交易也在库存里有 就减去交易
when not matched then 
insert values(Trade.Symbol,Trade.Delta);  --有交易没有库存的就加到库存里

select * from Stock
select * from Trade

Symbol     Qty
---------- -----------
ADVW       15
NWT        3

(2 行受影响)

Symbol     Delta
---------- -----------
ADVW       5
BYA        -5
NWT        3

(3 行受影响)


 

使用Merge进行表复制

  生成两个表,在存储过程执行一次复制一次

 

create table Original(PK int primary key ,Fname varchar(10),Number int)
create table Replica(PK int primary key ,Fname varchar(10),Number int)


  
  create procedure uspSyncReplica
  as
  Merge Replica r using Original o on o.PK=r.PK
  WHEN MATCHED AND (o.Fname!=r.Fname or o.Number!=r.Number) then 
  update set r.Fname=o.Fname , r.Number=o.Number
  when  not matched then 
  insert values(o.PK,o.Fname,o.Number)
  when not matched by source then
  delete;
  
     INSERT INTO Original VALUES(1,'Stephen',10)
   INSERT INTO Original VALUES(2,'Jack',20)
   INSERT INTO Original VALUES(3,'BEILL',30)
   select *from Original
   select *from Replica
   /*
   PK          Fname      Number
----------- ---------- -----------
1           Stephen    10
2           Jack       20
3           BEILL      30

(3 行受影响)

PK          Fname      Number
----------- ---------- -----------

(0 行受影响)
   */
EXECUTE uspSyncReplica 
   /*
   (3 行受影响)
   */

  select *from Original
   select *from Replica
   /*
   PK          Fname      Number
----------- ---------- -----------
1           Stephen    10
2           Jack       20
3           BEILL      30

(3 行受影响)

PK          Fname      Number
----------- ---------- -----------
1           Stephen    10
2           Jack       20
3           BEILL      30

(3 行受影响)
   */


 

在上面的存储过程执行一次复制一次    使用$action虚拟列查询MERGE输出如下

  
  alter procedure uspSyncReplica
  as
  Merge Replica r using Original o on o.PK=r.PK
  WHEN MATCHED AND (o.Fname!=r.Fname or o.Number!=r.Number) then 
  update set r.Fname=o.Fname , r.Number=o.Number
  when  not matched then 
  insert values(o.PK,o.Fname,o.Number)
  when not matched by source then
  delete 
  output $action ,inserted.*,deleted.*;
  
     INSERT INTO Original VALUES(1,'Stephen',10)
   INSERT INTO Original VALUES(2,'Jack',20)
   INSERT INTO Original VALUES(3,'BEILL',30)
   select *from Original
   select *from Replica


 

EXECUTE uspSyncReplica 

$action    PK          Fname      Number      PK          Fname      Number ---------- ----------- ---------- ----------- ----------- ---------- ----------- INSERT     1           Stephen    10          NULL        NULL       NULL INSERT     2           Jack       20          NULL        NULL       NULL INSERT     3           BEILL      30          NULL        NULL       NULL

(3 行受影响)


 

查询复制后的表

PK          Fname      Number
----------- ---------- -----------
1           Stephen    10
2           Jack       20
3           BEILL      30

(3 行受影响)

PK          Fname      Number
----------- ---------- -----------
1           Stephen    10
2           Jack       20
3           BEILL      30

(3 行受影响)


 

如:有一个表 customer, 现在要用一个procedure过程,插入数据,如果表customer中有条数据就更新,没有就新增。

 

if OBJECT_ID('customer')is not null
drop table customer
go
create table customer(
Customerid int primary key,
Firstname varchar(30),
Lastname varchar(30),
Balance decimal
)

create procedure usUpsertCustomer 
(
@Customerid int  ,
@Firstname varchar(30),
@Lastname varchar(30),
@Balance decimal
)as
merge customer c 
using 
(select @Customerid  as Customerid ,@Firstname as  Firstname  ,@Lastname  as  Lastname ,@Balance as  Balance)p 
on  c.Customerid=p.Customerid
when not matched then 
insert values(p.Customerid,p.Firstname,p.Lastname,p.Balance)
when matched  then 
update set c.Customerid=p.Customerid,c.Firstname=p.Firstname,c.Balance=p.Balance
output $action,deleted.*,inserted.*;


execute usUpsertCustomer 1,'Stephen','Zhou',10
/*
$action    Customerid  Firstname                      Lastname                       Balance                                 Customerid  Firstname                      Lastname                       Balance
---------- ----------- ------------------------------ ------------------------------ --------------------------------------- ----------- ------------------------------ ------------------------------ ---------------------------------------
UPDATE     1           Stephen                        Zhou                           10                                      1           Stephen                        Zhou                           10

(1 行受影响)
*/
select * from customer
/*
Customerid  Firstname                      Lastname                       Balance
----------- ------------------------------ ------------------------------ ---------------------------------------
1           Stephen                        Zhou                           10

(1 行受影响)

*/
execute usUpsertCustomer 1,'Stephen','Jack',20
/*
$action    Customerid  Firstname                      Lastname                       Balance                                 Customerid  Firstname                      Lastname                       Balance
---------- ----------- ------------------------------ ------------------------------ --------------------------------------- ----------- ------------------------------ ------------------------------ ---------------------------------------
UPDATE     1           Stephen                        Zhou                           10                                      1           Stephen                        Zhou                           20

(1 行受影响)
*/

select * from customer
/*
Customerid  Firstname                      Lastname                       Balance
----------- ------------------------------ ------------------------------ ---------------------------------------
1           Stephen                        Zhou                           20

(1 行受影响)
*/


 

 

以上基本上介绍了下merge的使用 现在把这个联合 output...into...

 

 

create table book (
isbn varchar(20) primary key ,
price decimal,
shelf int
)
create table weeklychange(
isbn varchar(20) primary key,
price decimal,
shelf int
)
create table bookhistory(
[Action] nvarchar(10),
newISBN varchar(20),
newprice decimal,
newshelf int,
oldisbn varchar(20),
oldprice decimal,
oldshelf int,
archivedat datetime2
)
create procedure uspupdatebooks as 
begin
merge book b using weeklychange w on b.isbn=w.isbn 
when not matched then 
insert values (w.isbn,w.price,w.shelf)
when matched and (w.isbn!=b.isbn or w.price!=b.price or w.shelf!=b.shelf) then 
update set b.isbn=w.isbn , b.price=w.price,b.shelf=w.shelf
output $action,inserted.*,deleted.*,sysdatetime() into bookhistory;
end


insert into weeklychange values('SQL程序设计',89,1)

select * from book
select * from weeklychange
select * from bookhistory
/*
isbn                 price                                   shelf
-------------------- --------------------------------------- -----------

(0 行受影响)

isbn                 price                                   shelf
-------------------- --------------------------------------- -----------
SQL程序设计              89                                      1

(1 行受影响)

Action     newISBN              newprice                                newshelf    oldisbn              oldprice                                oldshelf    archivedat
---------- -------------------- --------------------------------------- ----------- -------------------- --------------------------------------- ----------- ----------------------

(0 行受影响)
*/

execute uspupdatebooks
select * from book
select * from weeklychange
select * from bookhistory

/*
isbn                 price                                   shelf
-------------------- --------------------------------------- -----------
SQL程序设计              89                                      1

(1 行受影响)

isbn                 price                                   shelf
-------------------- --------------------------------------- -----------
SQL程序设计              89                                      1

(1 行受影响)

Action     newISBN              newprice                                newshelf    oldisbn              oldprice                                oldshelf    archivedat
---------- -------------------- --------------------------------------- ----------- -------------------- --------------------------------------- ----------- ----------------------
INSERT     SQL程序设计              89                                      1           NULL                 NULL                                    NULL        2012-12-05 14:19:12.29

(1 行受影响)

*/


 

 

 

 

 

 

 

 *作者:Stephenzhou(阿蒙)     
 *日期: 2012.12.5
 *Mail:[email protected]     
 *另外:转载请著名出处。
 *博客地址:http://blog.csdn.net/szstephenzhou

 

 

你可能感兴趣的:(SQL Server2008 Merge应用实例(Merge执行统计库存,复制表,输出$action列 ,output...INTO..))