有谁知道forall和merge的不同之处吗?最好是每个给个例子,另外我需要一个forall和merge一起使用的例子!请高手帮忙!!

解决方案 »

  1.   

    我的理解是:forall只能用于单独的insert或者Update;而merge却可以即insert又可以update.
    另外,forall只支持一行的sQL语句!
      

  2.   

    forall是按照数据块进行修改,而不是一条一条的sql语句,可以获得性能的很大提高.
    merge主要用于数据仓库中大了数据的转移.
      

  3.   

    下面是原文的例子:
    FORALL <index_name> IN <bounds_clause>
    <sql_statement>
    SAVE EXCEPTIONS;Bounds_Clause
    <lower_bound> .. <upper_bound>
    or
    INDICES OF <collection> BETWEEN <lower_bound> AND <upper_bound>
    or
    VALUES OF <index_collection> 
    CREATE TABLE t1 (pnum INTEGER, pname VARCHAR2(15));
    CREATE TABLE t2 AS SELECT * FROM t1;CREATE OR REPLACE PROCEDURE forall_delete(iterations PLS_INTEGER) ISTYPE NumTab IS TABLE OF t1.pnum%TYPE INDEX BY PLS_INTEGER;
    TYPE NameTab IS TABLE OF t1.pname%TYPE INDEX BY PLS_INTEGER;
    pnums NumTab;
    pnames NameTab;a INTEGER; 
    b INTEGER; 
    c INTEGER;BEGIN
      FOR j IN 1..iterations LOOP -- load index-by tables
        pnums(j) := j;
        pnames(j) := 'Part No. ' || TO_CHAR(j);
      END LOOP;  a := dbms_utility.get_time;  FOR i IN 1..iterations LOOP -- use FOR loop
        INSERT INTO t1 VALUES (pnums(i), pnames(i));
      END LOOP;  b := dbms_utility.get_time;  FORALL i IN 1 .. iterations -- use FORALL statement
      INSERT INTO t2 VALUES (pnums(i), pnames(i));  c := dbms_utility.get_time;  dbms_output.put_line('Execution Time (secs)');
      dbms_output.put_line('---------------------');
      dbms_output.put_line('FOR loop: ' || TO_CHAR((b - a)/100));
      dbms_output.put_line('FORALL: ' || TO_CHAR((c - b)/100));
      COMMIT;
    END;
    /set serveroutput on
    exec forall_delete(500);
    exec forall_delete(5000);
    exec forall_delete(50000); FORALL with Part of a Collection CREATE TABLE test (
    deptno  NUMBER(3,0),
    empname VARCHAR2(20));INSERT INTO test VALUES (100, 'Morgan');
    INSERT INTO test VALUES (200, 'Cline');
    INSERT INTO test VALUES (101, 'Lofstrom');
    INSERT INTO test VALUES (102, 'Havemeyer');
    INSERT INTO test VALUES (202, 'Starr');
    INSERT INTO test VALUES (201, 'Math');
    INSERT INTO test VALUES (103, 'Scott');
    INSERT INTO test VALUES (104, 'Nishimura');
    INSERT INTO test VALUES (105, 'Shastri');
    INSERT INTO test VALUES (106, 'Mirza');
    COMMIT;SELECT * FROM test;CREATE OR REPLACE PROCEDURE collection_part ISTYPE NumList IS VARRAY(10) OF NUMBER;depts NumList := NumList(100,200,101,102,202,201,103,104,105,106);BEGIN
      FORALL j IN 4..7 -- use only part of varray
      DELETE FROM test WHERE deptno = depts(j);
      COMMIT;
    END collection_part;
    /SELECT * FROM test; 
      

  4.   

    MERGE <hint> INTO <table_name>
    USING <table_view_or_query>
    ON (<condition>)
    WHEN MATCHED THEN <update_clause>
    WHEN NOT MATCHED THEN <insert_clause>; 
    CREATE TABLE employee (
    employee_id NUMBER(5),
    first_name  VARCHAR2(20),
    last_name   VARCHAR2(20),
    dept_no     NUMBER(2),
    salary      NUMBER(10))
    TABLESPACE data_sml;INSERT INTO employee VALUES (1, 'Dan', 'Morgan', 10, 100000);
    INSERT INTO employee VALUES (2, 'Jack', 'Cline', 20, 100000);
    INSERT INTO employee VALUES (3, 'Elizabeth', 'Scott', 20, 50000);
    INSERT INTO employee VALUES (4, 'Jackie', 'Stough', 20, 40000);
    INSERT INTO employee VALUES (5, 'Richard', 'Foote', 20, 30000);
    INSERT INTO employee VALUES (6, 'Joe', 'Johnson', 20, 70000);
    INSERT INTO employee VALUES (7, 'Clark', 'Urling', 20, 90000);
    COMMIT;CREATE TABLE bonuses (
    employee_id NUMBER, bonus NUMBER DEFAULT 100)
    TABLESPACE data_sml;INSERT INTO bonuses (employee_id) VALUES (1);
    INSERT INTO bonuses (employee_id) VALUES (2);
    INSERT INTO bonuses (employee_id) VALUES (4);
    INSERT INTO bonuses (employee_id) VALUES (6);
    INSERT INTO bonuses (employee_id) VALUES (7);
    COMMIT;MERGE INTO bonuses B
    USING (
       SELECT employee_id, salary
       FROM employee
       WHERE dept_no =20) E
    ON (B.employee_id = E.employee_id)
    WHEN MATCHED THEN
       UPDATE SET B.bonus = E.salary * 0.1
    WHEN NOT MATCHED THEN
       INSERT (B.employee_id, B.bonus)
       VALUES (E.employee_id, E.salary * 0.05);