【发布时间】:2018-10-17 20:01:11
【问题描述】:
我正在 java 中创建一个批量加载实用程序,它将从源数据库的表中读取行并在目标数据库为空时填充目标数据库中的数据。
我从下面的 select 语句开始:这将返回批次,因为 order by 子句保证了订单。假设在此批量实用程序处理过程中没有插入具有过去日期 (created_date) 的记录,则一切正常。
SELECT * FROM dbo.${batch.name}
ORDER BY created_date
OFFSET ${batch.offset} ROWS
FETCH NEXT ${batch.batchSize} ROWS ONLY;
但后来我意识到有些表没有 created_date 列。
如果您不指定明确的 order by 子句,则无法保证 SQL-Server 的顺序。所以我不能删除 order by,但是由于 created_date 不在所有表中,所以这个查询会失败。
考虑到所有表都没有用于 order by 子句的公共列或任何可以按插入顺序返回行的查询,是否有通用选择查询可以按顺序返回行?
以下查询是否有效?如果在此批处理实用程序使用以下查询进行时插入了更多行怎么办?
SELECT * FROM dbo.${batch.name}
ORDER BY (SELECT 1)
OFFSET ${batch.offset} ROWS
FETCH NEXT ${batch.batchSize} ROWS ONLY;
谢谢。
【问题讨论】:
-
简短回答...不...也就是说,所有表都应该有一个主键。为什么不简单地使用它?
-
我无法在 where 子句中指定主键来选择行,因为应用程序没有主键。我只想通过批量选择行来将整个表复制到另一个数据库。
-
为什么要使用批处理?为什么不只使用单个查询打开一个 ResultSet 并遍历行呢? docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html
-
在这种情况下,使用 ResultSet/Cursor 逐行处理不是一个有效的解决方案,因为数据量很大。还要考虑是否有几行无法插入我不想重新开始的目标数据中心。主要是因为游标的性能问题,而不是使用基于 ResultSet/Cursor 的方法的多线程,我想到了批处理。使用批处理我可以使用多个线程一次读取/写入多行并独立处理。如果任何批次失败,我不需要重新开始,只需要处理该批次。
标签: sql sql-server database select jdbc