数据库: Oracle 11g
有没有一种方法可以做到以下几点:
INSERT INTO T1
(V1, V2)
COMMIT EVERY X
AS
SELECT (V1, V2) FROM T2;我知道如何循环通过游标,但我正在寻找更精简的东西。
PL/SQL很好,但没有循环。
使用SQL提示也很好。
如果这只是oracle无法处理的事情,悲伤就会随之而来(主要是我很好奇,因为我已经有了另一种方法)。
注意:应用程序有数千亿条记录。每天都有数百万人被创造出来。INSERT INTO SELECT不能处理这么大的数据集。特别是当有同样大的集合并行运行时。
发布于 2012-04-16 23:13:51
Oracle不允许语句有中间提交,不允许。这样做会违反ACID数据库的基本属性。如果语句在第N行失败,会发生什么情况?Oracle将无法回滚以前提交的行。它不会知道哪些行已经处理,哪些没有处理。因此,您的语句将部分成功,而您的数据库将处于未知状态。使用关系数据库的主要好处之一就是避免了这种结果。
为什么你首先想要做一个临时提交?这将使您的代码变慢,并导致您使用更多的资源。这将迫使你写一堆代码来使你的进程可重启(也就是说,你必须跟踪哪些行已经被处理,哪些没有被处理,这样你就可以回滚部分完成的更改,或者如果进程在中间失败了,就重新启动它)。这会让你的代码更难测试。几乎没有一个很好的理由来进行临时提交。
发布于 2012-04-16 23:19:06
Oracle不提供这样的SQL构造。使用带有游标的PL/SQL和forall语句可以为您完成这项工作...但是:
Oracle没有提供这样的悲哀,这是件好事。Oracle是一个建立在ACID原则之上的RDBMS。I代表隔离,在Oracle中,它缺省为读提交。这意味着其他并发事务无法在中途看到您的事务。它可以防止其他会话看到不一致的数据。使用RDBMS的基石之一。
这给我们带来了一个最重要的问题:为什么你会想要这样一个结构?
我希望这不是对“大”交易的恐惧。
发布于 2012-04-16 23:19:50
我没有检查它,但也许使用bulk inserts可以实现以下目标:
DECLARE
TYPE ARRAY IS TABLE OF T2%ROWTYPE;
l_data ARRAY;
x NUMBER;
CURSOR c IS SELECT V1, V2 FROM T2;
BEGIN
OPEN c;
LOOP
FETCH c BULK COLLECT INTO l_data LIMIT x;
FORALL i IN 1..l_data.COUNT
INSERT INTO T1 VALUES l_data(i);
COMMIT;
EXIT WHEN c%NOTFOUND;
END LOOP;
CLOSE c;
END;但以贾斯汀·凯夫的身份,WHy?
https://stackoverflow.com/questions/10176722
复制相似问题