从select中插入PL SQL批处理

时间:2015-12-05 09:13:53

标签: oracle plsql

我必须将数据从表A移动到表B(它们具有几乎相同的字段)。

我现在拥有的是一个游标,它遍历必须移动的记录,在目标表中插入一条记录并更新源表中的is_processed字段。 类似的东西:

BEGIN
    FOR i IN (SELECT *
                FROM A 
               WHERE A.IS_PROCESSED = 'N')
    LOOP
        INSERT INTO B(...) VALUES(i....);
        UPDATE A SET IS_PROCESSED = 'Y' WHERE A.ID = i.ID;
        COMMIT;
    END LOOP;

END;

问题是,如何使用INSERT FROM SELECT(没有循环)然后更新所有移动的行的IS_PROCESSED来做同样的事情?

3 个答案:

答案 0 :(得分:2)

INSERT ... SELECT

没有BULK COLLECT INTO

可能你可以试试这个。我认为它不比你的LOOP好。

DECLARE
  TYPE        l_src_tp IS TABLE OF t_source%ROWTYPE;
  l_src_rows  l_src_tp;
BEGIN
  SELECT *
    BULK COLLECT INTO l_src_rows
    FROM t_source;
  FORALL c IN l_src_rows.first .. l_src_rows.last 
    INSERT INTO t_dest (td_id, td_value)
         VALUES (l_src_rows(c).ts_id, l_src_rows(c).ts_value);   
  FORALL c IN l_src_rows.first .. l_src_rows.last          
    UPDATE t_source 
       SET ts_is_proccesed = 'Y'
     WHERE ts_id = l_src_rows(c).ts_id;
END;

答案 1 :(得分:2)

如果您颠倒订单并首先进行更新然后插入,您可以使用:

DECLARE
    ids sys.odcinumberlist;
BEGIN
    UPDATE a SET is_processed = 'Y' WHERE is_processed = 'N' RETURNING id BULK COLLECT INTO ids;
    INSERT INTO b (id) SELECT column_value id FROM TABLE(ids);
    COMMIT;
END;

SELECT中,您可以加入ids表,并从其他表中获取要插入b的其他数据。

答案 2 :(得分:0)

您好我应该更喜欢纯SQL而不是PLSQL。我不知道为什么这个更简单的任务需要另一个更新语句。如果这有帮助,请告诉我。

INSERT INTO <new table>
SELECT col1,col2,
.....,'Y'
FROM <old_table>
WHERE processed_in = 'N';