Oracle SQL:如何在FORALL LOOP中添加IF条件

时间:2018-05-12 22:33:17

标签: sql oracle plsql bulk-operations

我正在尝试将表合并到10000U,如果select_count不等于0.但是我无法在FORALL循环中添加select和if语句。任何人都可以帮我实现这个目标吗?感谢。

10000UL

以上代码抛出错误消息:

  

PLS-00201:标识符'我'必须申报。

2 个答案:

答案 0 :(得分:0)

Oracle PL / SQL FORALL语句只能覆盖一个SQL语句(无PL / SQL),因为这基本上命令Oracle SQL引擎执行批量操作,而SQL引擎不能PL / SQL blocks。

您似乎想要做的是FOR循环。像这样:

FOR i IN 1 .. v_emp.LAST
LOOP
    select count(emp_id) into select_count from emp where emp_id=v_emp(i).emp_id;
    IF select_count <> 0 THEN 
       MERGE INTO emp1 e1 using dual ON(a.id=b.id)
       WHEN MATCHED
         //Update statement
       WHEN NOT MATCHED 
         //Insert statement
    END IF;
END LOOP;

如果您仍希望通过MERGE批量执行FORALL,请先使用循环计算计数,然后从{{1}中删除零计数的条目}集合,这样你就可以使用v_emp

答案 1 :(得分:0)

  

感谢您的回答。请您添加示例代码以删除   v_emp集合中没有计数的条目?

从您的评论中挑选,您应该只在查询中的第一个位置选择那些计数不为零的记录,而不是在后期检查它。见下文。

CREATE TABLE emp(emp_NM VARCHAR2(10),
                  emp_id NUMBER,
                  sal NUMBER);
/
INSERT INTO emp VALUES ('X',1,100);                  
INSERT INTO emp VALUES ('A',2,200);
INSERT INTO emp VALUES('B',3,300);
INSERT INTO emp values ('C',4,400);
/
Select * from emp;
/

CREATE OR REPLACE TYPE ep_id IS TABLE OF NUMBER;

/

DECLARE
Type v_emp IS  TABLE OF NUMBER INDEX BY pls_integer;
  emp_var v_emp;

  --Declared a table having emp_id as in your case where you try to get this in a collection v_emp.
  v_ep_id ep_id:=ep_id(1,2,4,5,6);
BEGIN
  ---Query to select only those records whose count is greater than 0.
  SELECT COUNT(emp_id) 
  bulk collect  INTO emp_var
  FROM emp
  --WHERE emp_id IN  (SELECT * FROM TABLE(v_ep_id) ) --< You can use this as well.
  WHERE emp_id MEMBER OF v_ep_id
  GROUP BY emp_id, sal, emp_nm
  HAVING COUNT(emp_id) > 0 ;

  --Here you directly do the merge of the selected records which are not Zero
  FORALL i IN 1 .. emp_var.Count
  MERGE INTO emp1 e1 using dual ON(a.id=b.id)
  WHEN MATCHED
  //Update statement
  WHEN NOT MATCHED
  //Insert statement
  END IF; 

 Exception
 WHEN others then
 raise_application_error(-20001,'Error');
END;