需要变量的Oracle游标

时间:2013-01-27 18:38:22

标签: oracle cursor temp-tables

我正在尝试做一个像下面这样的游标,在不同的方法中挣扎而没有结果。似乎,我自己无法做到,并决定向你寻求帮助。 下面的代码显示了我想要实现的目标,而不是现成的方法。请帮忙。

我不知道这很重要但请注意,我需要在循环中更新CUSTOMERS。我还需要在此循环中从引用客户的另一个表中选择一些数据,然后将内容插入第三个表并更新客户表。

DECLARE
  CURSOR MY_CURSOR
  IS
    SELECT CUSTOMERID FROM CUSTOMERS WHERE ACTIVE = 1 ;
  MY_RECORD MY_CURSOR%ROWTYPE;
BEGIN
  FOR MY_RECORD IN MY_CURSOR
  LOOP

 DECLARE TEMPORARY_TABLE TABLE (A DATE, B NUMBER, C VARCHAR)

 INSERT INTO @TEMPORARY_TABLE(A,B,C) (SELECT CREATEDDATE, ID, NAME FROM ACCOUNT WHERE CUSTOMER = MY_RECORD.CUSTOMERID)

 INSERT INTO SOME_EVENT_TABLE(ID, NAME, DATE, ACCOUNT_ID) VALUE (some_seq.NEXTVAL, @TEMPORARY_TABLE[C], @TEMPORARY_TABLE[A], @TEMPORARY_TABLE[B])

     UPDATE CUSTOMERS SET LAST_ACCOUNT_CHECK_NAME=@TEMPORARY_TABLE(C), LAST_INSERTED_EVENT_ID = some_seq.CURRVAL  WHERE ID = MY_RECORD.CUSTOMERID


  END LOOP;
  COMMIT;
END;

2 个答案:

答案 0 :(得分:1)

首先,您不能像在SQL Server中那样在Oracle中声明临时表。但是,无论如何,你真的不需要它。

这样的事情应该有效:

FOR MY_RECORD IN MY_CURSOR LOOP
  FOR  R IN (SELECT CREATEDDATE, ID, NAME 
               FROM ACCOUNT WHERE CUSTOMER = MY_RECORD.CUSTOMERID) LOOP
    INSERT INTO some_event_table(ID, NAME, DATE, ACCOUNT_ID)
    VALUES (some_seq.NEXTVAL, R.NAME, R.CREATEDATE, R.ID);

    UPDATE customers 
       SET last_account_check_name = R.name
         , last_inserted_event_id = some_seq.CURRVAL
     WHERE id = MY_RECORD.CUSTOMER_ID;
  END LOOP;
END LOOP;
COMMIT;

答案 1 :(得分:0)

SQL中的逐行操作非常低效。如果以基于集合的方式执行此操作,您将获得更好的性能。

INSERT INTO some_event_table(ID, NAME, DATE, ACCOUNT_ID)
SELECT some_seq.NEXTVAL, a.name, a.createdate, a.id
  FROM ACCOUNT a
 INNER JOIN customers c ON c.customerid = a.customerid
 WHERE c.active = 1;

UPDATE customers 
   SET last_account_check_name = 
          ( SELECT a.name FROM account a WHERE a.customerid = c.customerid ),
       last_inserted_event_id = some_seq.CURRVAL
 WHERE c.active = 1;

可能存在并发性问题(如果在两个语句之间更新客户会发生什么?),但这可能足以满足您的需求。