所以这是我的问题:我需要获取批量行(select语句)以便迁移到另一个数据库(除了oracle之外)。
建议的解决方案:我采用多批行(可能使用rowid?)示例:
batch1: 0-10000,
batch2: 10000 - 20000,
batchn: 10000(n) - 10000(n+1)
那么我的查询应该是什么?
batch1: select * from table_name where rownum >= 0 and rownum < 10000,
batch2: select * from table_name where rownum >= 10000 and rownum < 20000,
batch n: select * from table_name where rownum >= 10000*n and rownum < 10000*(n+1)
这不起作用(只有第一个选择才有效)。
PS,我从nodejs应用程序中提取这些数据,因此我在for循环中发送这些批处理查询。
答案 0 :(得分:1)
使用rownum
并不是一个好主意,因为不能保证在不同的查询中为相同的行分配相同的rownum值。
如果表具有唯一标识行的列的任意组合,则最好根据该列生成排名并使用该排名来标识批次行。例如:
SELECT * FROM (
SELECT table.*, RANK() OVER (ORDER BY column1, column2) as my_rank
FROM table
)
WHERE my_rank >= 10000 AND my_rank < 20000
这适用于任何范围,并且只要所用列中的值不更改并唯一标识行,就可以重现。 (实际上,我认为即使它们不能唯一地标识一行,它也是可用的,只要它们能够将行分成足够小的批次。)
缺点是MY_RANK将包含在输出中。您可以通过明确列出您想要选择的列来避免这种情况;或者,当您将数据加载到其他数据库时,可能更容易将其过滤掉。
答案 1 :(得分:1)
说明我的评论:
-- Between rows --
SELECT * FROM
( SELECT deptno, ename, sal, ROW_NUMBER() OVER (ORDER BY ename) Row_Num
FROM scott.emp
)
WHERE Row_Num BETWEEN 5 and 10
/
如果需要,您可以在&lt; =和&gt; =之间替换运算符。 这是我在输出中看到的内容:
DEPTNO ENAME SAL ROW_NUM
20 FORD 3000 5
30 JAMES 950 6
20 JONES 2975 7
10 KING 5000 8
30 MARTIN 1250 9
10 MILLER 1300 10
答案 2 :(得分:0)
如果要保留rowid,请使用以下SQL。这个SQL需要4分20秒才能在2 CPU服务器上运行2.18亿行表,其中18 GB用于数据库。
CREATE TABLE rowids
AS
WITH
aset
AS
(SELECT ROWID AS row_id, row_number () OVER (ORDER BY ROWID) r
FROM amiadm.big_table)
SELECT *
FROM aset
WHERE MOD (r, 10000) = 0;
创建此表后,使用以下内容循环显示:
BEGIN
FOR recs
IN ( SELECT row_id
, LAG (row_id) OVER (ORDER BY row_id) prev_row_id
, LEAD (row_id) OVER (ORDER BY row_id) next_row_id
FROM rowids
ORDER BY row_id)
LOOP
IF prev_row_id IS NULL
THEN
SELECT *
FROM big_table
WHERE ROWID <= recs.row_id;
ELSIF next_row_id IS NULL
THEN
SELECT *
FROM big_table
WHERE ROWID > row_id;
ELSE
SELECT *
FROM big_table
WHERE ROWID > prev_row_id
AND ROWID <= row_id;
END IF;
END LOOP;
END;