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

时间:2016-07-15 14:16:32

标签: sql oracle oracle11g integration-testing mybatis

我需要使用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. 使用临时表并将查询重写为:select * from FOO foo join SOME_TEMPORARY_ID tempids on foo.id = tempids.id
  3. 我决定选择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子句?

3 个答案:

答案 0 :(得分:2)

感谢您描述您的主要问题。 检查,可能这可以帮到你

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

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

答案 1 :(得分:1)

好的,所以我决定如果我真的想要/必须使用oracle专有的功能/语法,那么让我们对现场的oracle进行测试。

因此,如果您不关心执行时间并碰巧有权访问CI服务器上的Docker,那么我建议您使用以下优秀的库: https://mvnrepository.com/artifact/org.testcontainershttps://github.com/testcontainers/testcontainers-java),包括oracle-xe模块。

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

答案 2 :(得分:0)

单个INSERT语句的长度限制(即您可以指定值的记录数)表示此操作最好用 multiple {{执行1}}陈述。

您是否可以迭代程序中的insert值列表,一次一个(或几个)插入临时表,然后您可以继续加入以进行最终查询?

当然,这最终类似于您原来的选项#1,但实际上它是#1和#2的组合我猜。无论如何,它会工作! :)