有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java Oracle异常“列表中表达式的最大数量为1000”

我将字符串列表传递给我的查询(SQL查询已写入),以获取所需的数据。 但我有一个例外:

ora-01795 maximum number of expressions in a list is 1000

我检查了列表中是否有1000多个条目传递给了query in参数


共 (6) 个答案

  1. # 2 楼答案

    dba-oracle.com

    ORA-01795: maximum number of expressions in a list is 1000 tips

    Oracle Error Tips by Burleson Consulting (S. Karam)

    The Oracle docs note this on the ora-01795 error*: ORA-01795 maximum number of expressions in a list is 1000 Cause: More than 254 columns or expressions were specified in a list. Action: Remove some of the expressions from the list. In the Oracle MOSC Forums, an Oracle user was attempting to find a way around error code ORA-01795. His question was answered by Reem Munakash of Oracle:

    The limit in Oracle8 is 1000 expressions. There is a bug 495555, filed against the error text giving the wrong number (254). However, there may be a further restriction depending on the tool you are using. The 1000 expressions is within sqlplus.

    The workaround would be to use a sub-query.

    The bug regarding the error message is fixed in 8.1.5.

  2. # 3 楼答案

    如果您使用的是Oracle DB,那么在一个“where”条件下,列表中的元素不能超过1000个。所以你可以在多个“where”条件中删去你的“where”条件,并用“or”子句连接它们

    如果您使用的是hibernate标准,那么可以使用下面的Java方法来实现这一点。 只要在使用过的地方替换代码就行了

    criteria.add(Restrictions.in(propertyName, mainList));
    

    addCriteriaIn(propertyName, mainList, criteria);
    

    方法是:

     private void addCriteriaIn (String propertyName, List<?> list,Criteria criteria)
      {
        Disjunction or = Restrictions.disjunction();
        if(list.size()>1000)
        {        
          while(list.size()>1000)
          {
            List<?> subList = list.subList(0, 1000);
            or.add(Restrictions.in(propertyName, subList));
            list.subList(0, 1000).clear();
          }
        }
        or.add(Restrictions.in(propertyName, list));
        criteria.add(or);
      }
    
  3. # 4 楼答案

    这是oracle对查询中列表传递次数的限制

    1. 你得把你的问题切掉,否则
    2. 改为在in子句中提供子查询/联接
  4. # 5 楼答案

    我解决了这个问题,将列表分成1000个大小的批次,并使用OR加入其中

    例如。 ID的eid[]数组

    如果我想执行这个查询

    String sql = select * from employee where some conditions and empid in(eid)
    

    我通过编写一小段代码重新编写了这个查询:

    String sql = select * from employee where some conditions and ( 
                                 empid in(empid[0...999]) OR
                                 empid in(empid[1000...1999]) OR
                                 empid in(empid[2000...2999]) OR .... );
    

    在使用hibernate时处理这个错误,您必须通过将列表分成100个批次,然后加入各个结果来解决这个问题(如上面的查询所示)

    我不认为hibernate不处理这个问题是有局限性的,因为这个问题可能不是另一个数据库,比如MySQL或DB2。Hibernate是一个跨数据库的ORM框架

  5. # 6 楼答案

    如果能够将查询中的db端逻辑转换为存储过程,则可以向其传递更长的数组(集合)

    Here你可以找到一个简单的例子。指向文档的链接已经过时,因此这里有一个指向9i文档的链接http://docs.oracle.com/cd/B10500_01/java.920/a96654/oraarr.htm#1040124

    import java.io.*;
    import java.sql.*;
    import oracle.sql.*;
    import oracle.jdbc.driver.*;
    
    public class ArrayDemo
    {
        public static void passArray() throws SQLException
        {
            Connection conn =
                new OracleDriver().defaultConnection();
    
            int intArray[] = { 1,2,3,4,5,6 };
    
            ArrayDescriptor descriptor =
                ArrayDescriptor.createDescriptor( "NUM_ARRAY", conn );
    
            ARRAY array_to_pass =
                new ARRAY( descriptor, conn, intArray );
    
            OraclePreparedStatement ps =
                (OraclePreparedStatement)conn.prepareStatement
                ( "begin give_me_an_array(:x); end;" );
    
            ps.setARRAY( 1, array_to_pass );
    
            ps.execute();
    
        }
    }
    

    SQL部分呢

    create or replace type NUM_ARRAY as table of number;
    
    create or replace
    procedure give_me_an_array( p_array in num_array )
    as
    begin
        for i in 1 .. p_array.count
        loop
            dbms_output.put_line( p_array(i) );
        end loop;
    end;