支持专有 INSERT ALL oracle 语法的内存数据库

In-memory database supporting proprietary INSERT ALL oracle syntax

我需要使用 oracle、java 和 mybatis 编写一个简单的查询:

select * from FOO foo where foo.id IN (ids)

现在,ids 是一个很大的字符串集合,大约有 7000 个。不幸的是,oracle 对 IN 子句有 1000 个元素的限制。

为了克服这个问题,我可以:

  1. 动态连接查询,使其变为: select * from FOO foo where foo.id IN (chunk1) or foo.id IN (chunk2) ... 我不确定它是否有效,我真的怀疑它的表现如何
  2. 使用临时 table 并将查询重写为:select * from FOO foo join SOME_TEMPORARY_ID tempids on foo.id = tempids.id

我决定选择 2 个选项。在执行查询之前,我需要以某种方式对 Oracle 进行高效的批量插入。不幸的是,Oracle 有专有语法来进行批量插入:

INSERT ALL
INTO some_table VALUES ('foo')
INTO some_table VALUES ('foo1')
INTO some_table VALUES ('foo2')
....
INTO some_table VALUES ('foo12345')
SELECT * FROM DUAL

现在,我没有提到,但我想为此编写一个集成测试,最好使用 H2 或任何其他内存数据库。 当然 H2 不支持这种语法。 HSQLDB 也没有。

您知道完全支持专有 oracle 语法的内存数据库吗?或者至少这个特定的 INSERT ALL 子句?

感谢您描述了您的主要问题。 检查一下,这可能对您有帮助

where (foo.id, 0) in (('1', 0), ('2', 0),...)

这个简单的解决方法没有限制。如果这个答案不合适,请告诉我。我删除了这个答案并再次考虑你的 child 问题。

单个 INSERT 语句的长度限制(即您可以为其指定值的记录数)暗示该操作最好用 multiple insert 个语句。

你能否在程序中迭代 id 值列表,一次插入一个(或几个)到你的临时 table,然后你可以继续加入 for您的最终查询?

当然,这最终类似于您最初的选项#1,但我猜它实际上是#1 和#2 的组合。不管怎样,它会起作用的! :)

好的,所以我决定,如果我真的 want/have 使用 oracle 专有 features/syntax,那么让我们针对实时 oracle 进行测试。

因此,如果您不关心执行时间并且碰巧可以在 CI 服务器上访问 do Docker,那么我向您推荐这些优秀的库: https://mvnrepository.com/artifact/org.testcontainers (https://github.com/testcontainers/testcontainers-java),包括 oracle-xe 模块。

我能够在集成测试期间启动 oracle-xe 容器并针对实时 oracle 实例进行测试。