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
成功。
如果不用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/