Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 在同一个表上的select语句中插入_Oracle_Plsql_Oracle Sqldeveloper_Oracle11gr2 - Fatal编程技术网

Oracle 在同一个表上的select语句中插入

Oracle 在同一个表上的select语句中插入,oracle,plsql,oracle-sqldeveloper,oracle11gr2,Oracle,Plsql,Oracle Sqldeveloper,Oracle11gr2,我当前正在将数据从旧系统迁移到当前系统 我在存储过程中有一个INSERT语句 INSERT INTO TABLE_1 (PRIMARY_ID, SEQUENCE_ID, DESCR) SELECT LEGACY_ID PRIMARY_ID , (SELECT COUNT(*) + 1 FROM TABLE_1 T1 WHERE T1.PRIMARY_ID = L1.LEGACY_ID) SEQUENCE_ID , L1.DESCR FROM LEGACY_TABLE L1;

我当前正在将数据从旧系统迁移到当前系统

我在存储过程中有一个
INSERT
语句

INSERT INTO TABLE_1
(PRIMARY_ID, SEQUENCE_ID, DESCR)
SELECT LEGACY_ID PRIMARY_ID
 , (SELECT COUNT(*) + 1
    FROM TABLE_1 T1
    WHERE T1.PRIMARY_ID = L1.LEGACY_ID) SEQUENCE_ID
 , L1.DESCR
FROM LEGACY_TABLE L1;
但是,每当我从
LEGACY_TABLE
中获得多个
LEGACY_ID
值时,对
序列_ID
的查询不会递增

为什么会这样?我似乎找不到任何关于
INSERT-INTO-SELECT
语句在幕后如何工作的文档。我猜它会从正在选择的表中选择所有值,然后同时插入它们,这就是为什么它不会增加
COUNT(*)
值的原因

我还能做什么其他的变通办法?我无法创建
序列
,因为
序列ID
必须基于存在的
主ID
的数量。它们都是主ID


提前感谢。

是的,将首先执行
选择
,然后才执行
插入

下面一个简单的PL/SQL块将是一个更简单的方法,尽管效率不高

DECLARE
    V_SEQUENCE_ID NUMBER;
    V_COMMIT_LIMIT:= 20000;
    V_ITEM_COUNT := 0;
BEGIN
    FOR REC IN (SELECT LEGACY_ID,DESCR FROM LEGACY_TABLE)
    LOOP
        V_SEQUENCE_ID:= 0;

        SELECT COUNT(*)+1 INTO V_SEQUENCE_ID FROM TABLE_1 T1
         WHERE T1.PRIMARY_ID = REC.LEGACY_ID


        INSERT INTO TABLE_1
        (PRIMARY_ID, SEQUENCE_ID, DESCR)
        VALUES
        (REC.LEGACY_ID,V_SEQUENCE_ID,REC.DESCR);

        V_ITEM_COUNT := V_ITEM_COUNT + 1;

        IF(V_ITEM_COUNT >= V_COMMIT_LIMIT)
        THEN
             COMMIT;
             V_ITEM_COUNT := 0;
        END IF;

    END LOOP;
    COMMIT;
END;
/
编辑:使用CTE:

PS:对于数百万行,这将创建一个临时表 在执行过程中具有相同的大小。在实际执行之前,请解释计划


没有别的办法吗?我需要优化插入到表中,因为我需要插入5000多万条记录。这不是一种坏的方法。但对你来说很容易维护。我们可以批量引入
COMMIT
。如果您有
表1
主ID
的索引,则此块将以最少的资源运行良好。我确实有
表1
主ID
的索引。但是,对于该表,主键是
primary\u ID
SEQUENCE\u ID
。此外,我还需要将
LEGACY_表
中的其他字段插入到其他表中,如
TABLE2
TABLE3
。如果是这样,您肯定应该使用
PL/SQL
,并批量提交。您有异常处理,您可以记录它以进行btter调试等。实际上,我目前正在为此使用
PL/SQL
。我以前已经尝试过这种方法,但我的领导希望这样做。如果我不能解决任何问题,我建议用这个来代替。我将暂时接受你的回答。谢谢
WITH TABLE_1_PRIM_CT(PRIMARY_ID, SEQUENCE_ID) AS
(
    SELECT L1.LEGACY_ID,COUNT(*) 
    FROM LEGACY_TABLE L1 
      LEFT OUTER JOIN TABLE_1 T1 
        ON(L1.LEGACY_ID = T1.PRIMARY_ID)
    GROUP BY L1.LEGACY_ID
)
INSERT INTO TABLE_1
(SELECT L1.LEGACY_ID,
       CTE.SEQUENCE_ID+ (ROW_NUMBER() OVER (PARTITION BY L1.LEGACY_ID ORDER BY null)), 
       L1.DESCR
FROM TABLE_1_PRIM_CT CTE, LEGACY_TABLE L1
WHERE L1.LEGACY_ID = CTE.PRIMARY_ID);