HSQLDB / Oracle - IN子句中的1000多个项目

时间:2014-09-05 07:14:03

标签: sql hibernate jpa oracle11g hsqldb

我们在数据库中有很多数据,有时我们需要在IN子句中调用超过1000个项目的sql语句。我知道那些sql语句应该被重构,并且IN子句不应该有那么多项,但有时候并不容易注意每个sql查询。所以我有几个问题。

  1. 有什么可能解决这个问题?我发现很少:
    • 重构sql语句 - 并不总是那么容易
    • 为项目创建临时表,因此IN子句看起来像这样... IN (SELECT id from temptable) - 可能是个好主意
    • IN条款划分为IN
    • 等少数... id IN (...) or id IN (...)条款
  2. Oracle db对IN子句有限制,但我没有找到我们用于单元测试的HSQLDB限制。是否可以通过HSQLDB中的某些配置或其他方式设置此限制?
  3. 关于IN子句的临时表 - 如何使用HQL创建临时表(我们在应用程序中使用Hibernate 4.2)?有可能吗?
  4. 目前,一些IN子句的数量不会超过1000个,因为我们在db中没有那么多数据。但是在应用程序将开始生产(它仍在开发过程中)之后会有更多的数据,所以我们希望为此做好准备。
  5. 您对此问题的体验是什么?你是怎么解决的?

    有关我们环境的详细信息:

    • Hibernate 4.2
    • HSQLDB 2.3.2
    • ORACLE 11g

2 个答案:

答案 0 :(得分:2)

问题2,HSQLDB没有对IN子句中的项目数施加限制,也没有限制。

答案 1 :(得分:0)

我认为问题1已经得到了很多回答,但这里是Oracle Community优雅解决方案的链接。

基本上,您创建一个表类型和一个将逗号分隔的字符串转换为表的函数。这允许您加入返回的表数据。

以下是我们如何实现逗号分隔的数字/ ID列表:

 create or replace function in_number_list (in_list in varchar2)  --send string
 return num_table                                      --return table of numbers
 as
 l_tab   num_table := num_table();           -- blank table
 l_text  varchar2(32767) := in_list || ',';  -- passed string + extra ','
 l_idx   number;                             -- a counter

 begin
 loop
   l_idx := instr(l_text, ',');              -- find the first comma position
   exit when nvl(l_idx,0) = 0;               -- if no more, break out of loop
   l_tab.extend;                             -- add a new row to table
   l_tab(l_tab.last) := to_number(trim(substr(l_text,1,l_idx-1)));
                                        -- add entry to table based on number
                                        -- split from string 
   l_text := substr(l_text,l_idx+1);         -- reset the original string
                                        -- trimming off what we've processed
 end loop;
 return l_tab;                               -- send back table of numbers
 end;