MERGE


1Purpose

Use the MERGE statement to select rows from one or more sources for update or insertion into a table or view. You can specify conditions to determine whether to update or insert into the target table or view.This statement is a convenient way to combine multiple operations. It lets you avoid multiple INSERTUPDATE, and DELETE DML statements.MERGE is a deterministic statement. You cannot update the same row of the target table multiple times in the same MERGE statement.

大概就是说,用merge可以选择出一个或多个源码去用来更新或插入到表中或视图中。你可以指定条件来决定是否更新或插入到目标表或视图中。Merge用来进行多项DML组合操作是很方便的。


2
Prerequisites

You must have the INSERT and UPDATE object privileges on the target table and the SELECT object privilege on the source table. To specify the DELETEclause of the merge_update_clause, you must also have the DELETE object privilege on the target table.

前提就是,你必须在目的表上有insert,update,delete的权限,在源表上有select的权限


3
Syntax

MERGE [ hint ]

   INTO [ schema. ] { table | view } [ t_alias ]

   USING { [ schema. ] { table | view }

         | subquery 

         } [ t_alias ]

   ON ( condition )

   [ merge_update_clause ]

   [ merge_insert_clause ]

   [ error_logging_clause ] ;

WHEN MATCHED THEN

UPDATE SET column = { expr | DEFAULT }

           [, column = { expr | DEFAULT } ]...

[ where_clause ]

DELETE where_clause ]

WHEN NOT MATCHED THEN

INSERT [ (column [, column ]...) ]

VALUES ({ expr | DEFAULT }

          [, { expr | DEFAULT } ]...

       )

[ where_clause ]

LOG ERRORS 

  [ INTO [schema.] table ]

  [ (simple_expression) ]

  [ REJECT LIMIT { integer | UNLIMITED } ]


4
Examples

Merging into a Table:

CREATE TABLE bonuses (employee_id NUMBER, salary NUMBER DEFAULT 100);

INSERT INTO bonuses(employee_id)

   (SELECT e.employee_id FROM employees e, orders o

   WHERE e.employee_id = o.sales_rep_id

   GROUP BY e.employee_id); 

创建一个bonuses表默认值为100

SELECT * FROM bonuses ORDER BY employee_id;

EMPLOYEE_ID     salary

----------- ----------

        153        100

        154        100

        155        100

        156        100

        158        100

        159        100

        160        100

        161        100

        163        100

我想做的就是,employees table中部门为80salary>8000的数据删除,<=的则以原来salary0.1插入到bonuses中,同时对bonuses中的salary更新为在原有salary上加上employees中对应salary0.01.

Merge into bonuses d

Using(select employee_id,salary,department_id from employees where department_id=80) s

On(d.employee_id=s.employee_id)

When matched then 
update set d.salary = d.salary + s.salary*0.01

Delete where (s.salary>8000)--from table 都不要......

When not matched then 

Insert(d.employee_id,d.salary)

Values(s.employee_id,s.salary*0.01)

Where(s.salary<=8000);

SELECT * FROM bonuses ORDER BY employee_id;

EMPLOYEE_ID      BONUS

----------- ----------

        153        180

        154        175

        155        170

        159        180

        160        175

        161        170

        164         72

        165         68

        166         64

        167         62

        171         74

        172         73

        173         61

        179         62
以下内容为转载

5、练习

2011-12-24 MERGE语句

作者:Jeff Kemp

难度:中

我创建了两张表并填入一些数据:

CREATE TABLE plch_empdept

( empid NUMBER NOT NULL

, deptid NUMBER NOT NULL

, CONSTRAINT plch_empdept_pk PRIMARY KEY (empid, deptid)

);

CREATE TABLE plch_newrecs 

( empid    NUMBER NOT NULL

, deptid   NUMBER NOT NULL

, deleteme CHAR(1) NOT NULL

, CONSTRAINT plch_newrecs_pk PRIMARY KEY (empid, deptid)

);

INSERT INTO plch_empdept VALUES (10, 100);

INSERT INTO plch_empdept VALUES (10, 200);

INSERT INTO plch_newrecs VALUES (10, 200, 'Y');

INSERT INTO plch_newrecs VALUES (10, 300, 'N');

INSERT INTO plch_newrecs VALUES (10, 400, 'Y');

COMMIT;

然后我执行了一些SQL(即下列的每个答案),目的是向 plch_empdept 表加入数据来源是 plch_newrecs 表中的deleteme等于'N' 的数据(假如数据在plch_empdept中已经存在则不修改), 如果 plch_newrecsdeleteme等于'Y'则从 plch_empdept删去相应数据。对应关系由组合键(empid, deptid)决定。

然后运行如下查询:

SELECT * FROM plch_empdept ORDER BY deptid

哪些选项提供的SQL语句能够 (a)执行不出错,并且(b)上述查询输出下列的结果:

EMPID  DEPTID

-----  ------

   10     100

   10     300

(A)

MERGE INTO plch_empdept

     USING (SELECT * FROM plch_newrecs) src

        ON (    plch_empdept.empid = src.empid

            AND plch_empdept.deptid = src.deptid)

WHEN MATCHED

THEN

   UPDATE SET

      plch_empdept.empid = src.empid

    , plch_empdept.deptid = src.deptid

   DELETE

           WHERE src.deleteme = 'Y'

WHEN NOT MATCHED

THEN

   INSERT     (empid, deptid)

       VALUES (src.empid, src.deptid)

        WHERE src.deleteme = 'N'

/

(B)

DELETE plch_empdept

WHERE (empid, deptid) IN (SELECT empid, deptid

                             FROM plch_newrecs

                            WHERE deleteme = 'Y')

/                            

INSERT INTO plch_empdept (empid, deptid)

   SELECT empid, deptid

     FROM plch_newrecs

    WHERE deleteme = 'N'

   MINUS

   SELECT empid, deptid FROM plch_empdept

/   

   

(C)

DELETE plch_empdept

WHERE (empid, deptid) IN (SELECT empid, deptid

                             FROM plch_newrecs

                            WHERE deleteme = 'Y')

/                            

MERGE INTO plch_empdept

     USING (SELECT * FROM plch_newrecs) src

        ON (    plch_empdept.empid = src.empid

            AND plch_empdept.deptid = src.deptid)

WHEN NOT MATCHED

THEN

   INSERT     (empid, deptid)

       VALUES (src.empid, src.deptid)

        WHERE src.deleteme = 'N'

/

(D)

MERGE INTO plch_empdept

     USING (SELECT * FROM plch_newrecs) src

        ON (    plch_empdept.empid = src.empid

            AND plch_empdept.deptid = src.deptid)

WHEN MATCHED

THEN

   DELETE WHERE src.deleteme = 'Y'

WHEN NOT MATCHED

THEN

   INSERT     (empid, deptid)

       VALUES (src.empid, src.deptid)

        WHERE src.deleteme = 'N'

/

2011-12-24 答案BC.

A: MERGE语句的匹配列(即ON后面的列)是不可以修改的。

D: MATCHED里面单独的DELETE目前还不支持,必须和UPDATE一起使用。这个一点道理也没有,希望ORACLE以后能改进。

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

转载于:http://blog.itpub.net/26844646/viewspace-749066/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值