merge

merge,从t1表更新数据到t2表,如果t2的name字段的纪录在t1中存在,就将money的值累加,如果不存在,就把t1的值插入到t2中。
如果不用merge的话,那么这个至少是需要一个update和一个insert的。现在,嘿嘿。。。
1,创建测试表及数据
建表的窗口丢了,自己写个脚本查出建表语句如下:
SQL> @getddl
Please enter the object_type.Leave blank for TABLE.
Enter value for object_type: table
Please enter the object_name
here you can not leave blank.
Enter value for name: t1
Please enter the object_name.level blank for current schema
here you can leave blank.
Enter value for schema: 
=================================================================
======================Create statement as follows================
  CREATE TABLE "TEST"."T1"
   (    "NAME" VARCHAR2(32),
        "MONEY" NUMBER
   ) 
在执行一次获取表t2建表语句
CREATE TABLE "TEST"."T1"
   (    "NAME" VARCHAR2(32),
        "MONEY" NUMBER
   ) 
SQL> insert into t1 values('A',10);
1 row created.
SQL> INSERT INTO T1 VALUES('B',20);
1 row created.
SQL> INSERT INTO T2 VALUES('A',30);
1 row created.
SQL> INSERT INTO T2 VALUES('C',20);
1 row created.
2,merge语句如下:
merge into t2
using t1
on (t1.name=t2.name)
when matched then update
set t2.money=t1.money+t2.money
when not matched then
insert values(t1.name,t1.money);

执行之后查询t2,数据如下:
SQL> select * from t2;
A                                                  50
C                                                  20
B                                                  40

完成需求。

merge在oracle10g以后获得了很大的完善,
1,可以选择只更新目标表
2,可以选择只插入
3,可以对merge加条件
4,merge语句中可以用delete(delete子句必须在最后)


merge误区
重新生成测试数据
SQL> truncate table t1;
SQL> truncate table t2;
SQL>  INSERT INTO T1 VALUES('A',30);
SQL>  insert into t1 values('A',10);
SQL> INSERT INTO T1 VALUES('B',20);
SQL>  INSERT INTO T2 VALUES('A',30);
SQL> INSERT INTO T2 VALUES('C',20);
重新执行刚才的merge

SQL> @merge
using t1
      *
ERROR at line 2:
ORA-30926: unable to get a stable set of rows in the source tables
报错原因是有一条t2中的数据对应不止一条t1中的数据。
这样不管咋写都会报错吧,呵呵。
这是本身的数据问题,不多说。

关于delete,删除的是目标表的数据,不管delete的where条件如何写,删除的都是目标表的数据,不会删除源表数据。~~!


更新本身这张表的数据,需要担心using后面的空值
SQL> select * from t2;
NAME                                            MONEY
-------------------------------- --------------------
A                                                  30
C                                                  20
对t2进行自我更新,如果在t2表中发现name=‘d’的纪录,就将money该为100,如果不存在,就增加该纪录。
根据需求,merge语句如下:
SQL> merge into t2
  2  using (select * from t2 where name='D')t
  3  on (t.name=t2.name)
  4  when matched then update
  5  set t2.money=100
  6  when not matched then
  7  insert values('D',200);
SQL> select * from t2;
NAME                                            MONEY
-------------------------------- --------------------
A                                                  30
C                                                  20
可以发现,表中的数据并没有被更新,原因:using后面必须包含要更新或者插入的行,
进行改造:


SQL> merge into t2
  2  using (select count(*) c from t2 where name='D')t
  3  on (t.c!=0)
  4  when matched then update
  5  set t2.money=100
  6  when not matched then
  7  insert values('D',200);
SQL> select * from t2;
NAME                                            MONEY
-------------------------------- --------------------
A                                                  30
C                                                  20
D                                                 200
成功。










来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30123160/viewspace-2052010/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/30123160/viewspace-2052010/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值