I am passing a list of Strings to my query(SQL query written) to fetch the required data. But I am getting this exception:
ora-01795 maximum number
you can create a temporary table, and insert the values you want use in your IN
statement, and join the temporary table with your real table. more information about temporary tables.
If you are able to convert your db-side logic from a query into a stored procedure, then you can pass longer arrays (collections) to it.
Here you can find a brief example how to do it. The link to the docs is outdated, so here's a link to the 9i docs 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();
}
}
and the SQL part
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;
this is a oracle limitation in the number of list pass in the query.
You cant have a list with more than 1000 elements in a single "where" condition if you are working with Oracle DB. So you can chop down your "where" condition in multiple "where" conditions and join them with "or" clause.
If you are using hibernate Criteria, you can use below Java method to do this. Just replace your code where ever you used
criteria.add(Restrictions.in(propertyName, mainList));
with
addCriteriaIn(propertyName, mainList, criteria);
which the method is :
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);
}
From 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.
I solved this by breaking the list into batch of size 1000 and joining it using OR.
e.g. eid[] array of ids.
If I want to execute this query,
String sql = select * from employee where some conditions and empid in(eid)
I have re-written this query by writing a small piece of code:
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 .... );
Dealing with this error while using hibernate, you have to tackle this issue by chopping the list into batch of 100 and then join the individual results (as shown in the query above).
I don't think that it's a limitation of hibernate for not handling this issue, because it may be the case that this issue is not a case of another DB like MySQL or DB2. Hibernate is a cross-DB ORM framework.