Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2548363
  • 博文数量: 2110
  • 博客积分: 18861
  • 博客等级: 上将
  • 技术积分: 24420
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-05 18:23
文章分类

全部博文(2110)

文章存档

2011年(139)

2010年(1971)

我的朋友

分类: Oracle

2010-10-19 12:05:56

 看到很多有关    ORACLE的BULK COLLECT和FORALL  的文章被转载,但原文的作者并没有提供具体的“FORALL indx IN VALUES OF denied_list ” 与  “FORALL indx INDICES OF denied_list " 的代码

  写道

  当绑定数组为稀疏数组或者包含有间隙时,

  INDICES OF 会非常有用。该语句的语法结构为:

  FORALL indx IN INDICES

  OF sparse_collection

  INSERT INTO my_table

  VALUES sparse_collection (indx);

  VALUES OF 用于一种不同的情况:绑定数组可以是稀疏数组,也可以不是,但我只想使用该数组中元素的一个子集。那么我就可以使用VALUES OF来指向我希望在DML操作中使用的值。该语句的语法结构为:

  FORALL indx IN VALUES OF pointer_array

  INSERT INTO my_table

  VALUES binding_array (indx);

  下面给以补充:

  案例演示环境

  -- EMPLOYEE

  CREATE TABLE EMPLOYEE AS   SELECT * FROM SCOTT.EMP;

  ALTER TABLE EMPLOYEE ADD CONSTRAINT PK_EMPNO  PRIMARY KEY (EMPNO);

  --EMPLOYEE_HISTORY

  CREATE TABLE EMPLOYEE_HISTORY AS SELECT EMPNO,SAL,HIREDATE,'DENIER' ACTIVITY FROM EMPLOYEE WHERE 1=0;

  CREATE OR REPLACE PACKAGE COMP_ANALYSIS IS

  -- EMPLOYEE IS ELIGIBLE

  FUNCTION IS_ELIGIBLE(P_EMPNO IN EMPLOYEE.EMPNO%TYPE) RETURN BOOLEAN;

  -- RAISE SALES {游标迭代]

  PROCEDURE GIVE_RAISE_IN_DEPARTMENT(P_DEPTNO IN EMPLOYEE.DEPTNO%TYPE,

  P_SAL    IN EMPLOYEE.SAL%TYPE);

  -- RAISE SALES EX1 [批量处理]

  PROCEDURE GIVE_RAISE_IN_DEPARTMENT_EX1(P_DEPTNO IN EMPLOYEE.DEPTNO%TYPE,

  P_SAL    IN EMPLOYEE.SAL%TYPE);

  END COMP_ANALYSIS;

  /

  CREATE OR REPLACE PACKAGE BODY COMP_ANALYSIS IS

  -- EMPLOYEE IS ELIGIBLE

  FUNCTION IS_ELIGIBLE(P_EMPNO IN EMPLOYEE.EMPNO%TYPE) RETURN BOOLEAN IS

  V_JOB EMPLOYEE.JOB%TYPE;

  BEGIN

  SELECT JOB INTO V_JOB FROM EMPLOYEE WHERE EMPNO = P_EMPNO;

  IF V_JOB = 'SALESMAN' THEN

  RETURN TRUE;

  ELSE

  RETURN FALSE;

  END IF;

  END IS_ELIGIBLE;

  -- RAISE SALES {游标迭代]

  PROCEDURE GIVE_RAISE_IN_DEPARTMENT(P_DEPTNO IN EMPLOYEE.DEPTNO%TYPE,

  P_SAL    IN EMPLOYEE.SAL%TYPE) IS

  BEGIN

  FOR EMP IN (SELECT ROWID RD, EMPNO, SAL, HIREDATE FROM EMPLOYEE) LOOP

  IF IS_ELIGIBLE(EMP.EMPNO) THEN

  UPDATE EMPLOYEE SET SAL = SAL + P_SAL WHERE ROWID = EMP.RD;

  --AND DEPTNO = P_DEPTNO;

  ELSE

  INSERT INTO EMPLOYEE_HISTORY

  (EMPNO, SAL, HIREDATE, ACTIVITY)

  VALUES

  (EMP.EMPNO, EMP.SAL, EMP.HIREDATE, 'DENIER');

  END IF;

  END LOOP;

  COMMIT;

  END GIVE_RAISE_IN_DEPARTMENT;

  -- RAISE SALES EX1 [批量处理]

  PROCEDURE GIVE_RAISE_IN_DEPARTMENT_EX1(P_DEPTNO IN EMPLOYEE.DEPTNO%TYPE,

  P_SAL    IN EMPLOYEE.SAL%TYPE) IS

  TYPE T_EMPNO IS TABLE OF EMPLOYEE.EMPNO%TYPE INDEX BY BINARY_INTEGER;

  TYPE T_SAL IS TABLE OF EMPLOYEE.SAL%TYPE INDEX BY BINARY_INTEGER;

  TYPE T_HIREDATE IS TABLE OF EMPLOYEE.HIREDATE%TYPE INDEX BY BINARY_INTEGER;

  TYPE T_IDX IS TABLE OF PLS_INTEGER INDEX BY BINARY_INTEGER; --标识匹配数据的行号

  --驱动数组

  ALL_EMPNOS    T_EMPNO;

  ALL_SALS      T_SAL;

  ALL_HIREDATES T_HIREDATE;

  --数据数组

  APPROVED_EMPNOS T_IDX;

  DENIED_EMPNOS   T_IDX;

  --ENIDE_SALS      T_SAL;

  --DENIDE_HIREDATES T_HIREDATE;

  PROCEDURE RETRIEVE_EMPLOYEE_INFO IS

  BEGIN

  SELECT EMPNO, SAL, HIREDATE BULK COLLECT

  INTO ALL_EMPNOS, ALL_SALS, ALL_HIREDATES

  FROM EMPLOYEE;

  --WHERE DEPTNO = P_DEPTNO;

  END RETRIEVE_EMPLOYEE_INFO;

  PROCEDURE PARTITION_BY_ELIGIBILITY IS

  BEGIN

  FOR I IN 1 .. NVL(ALL_EMPNOS.LAST, 0) LOOP

  IF IS_ELIGIBLE(ALL_EMPNOS(I)) THEN

  APPROVED_EMPNOS(I) := I;

  ELSE

  DENIED_EMPNOS(I) := I;

  --DENIDE_SALS(I) := ALL_SALS(I);

  --DENIDE_HIREDATES(I) := ALL_HIREDATES(I);

  END IF;

  END LOOP;

  END PARTITION_BY_ELIGIBILITY;

  PROCEDURE ADD_TO_HISTORY IS

  BEGIN

  FORALL I IN VALUES OF DENIED_EMPNOS --下标稀疏

  INSERT INTO EMPLOYEE_HISTORY

  (EMPNO, SAL, HIREDATE, ACTIVITY)

  VALUES

  (ALL_EMPNOS(I), ALL_SALS(I), ALL_HIREDATES(I), 'DENIER');

  END ADD_TO_HISTORY;

  PROCEDURE GIVE_THE_RAISE IS

  BEGIN

  FORALL I IN VALUES OF APPROVED_EMPNOS

  UPDATE EMPLOYEE SET SAL = SAL + P_SAL WHERE EMPNO = ALL_EMPNOS(I);

  END GIVE_THE_RAISE;

  BEGIN

  RETRIEVE_EMPLOYEE_INFO;

  PARTITION_BY_ELIGIBILITY;

  ADD_TO_HISTORY;

  GIVE_THE_RAISE;

  COMMIT;

  END GIVE_RAISE_IN_DEPARTMENT_EX1;

  END COMP_ANALYSIS;

  /

阅读(472) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~