0

我正在尝试做一个类似下面的游标,在不同的方法中苦苦挣扎,但没有结果。看来,我一个人也做不了,决定请你帮忙。下面的代码显示了我想要实现的目标,而不是现成的方法。请帮忙。

我不知道这很重要,但请注意,我需要循环更新 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;
4

2 回答 2

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;
于 2013-01-27T19:53:43.457 回答
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;

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

于 2013-01-28T02:07:53.397 回答