我正在处理网络应用程序中的pdf报告,其中我需要显示可包含1000多个列表的报告
我在 JasperReports ( iReport )中有一个主查询,看起来像这样
<queryString><![CDATA[select SITE_NAME, SITE_OWNER, SITE_CONTACT_NAME, SITE_PHONE, SITE_FAX, SITE_MAIL from **SAMPLE_VIEW** where $X{IN,site_id, siteIds} group by SITE_NAME, SITE_OWNER, SITE_CONTACT_NAME, SITE_PHONE, SITE_FAX, SITE_MAIL by SITE_NAME]]>
</queryString>
其中$ X {IN,site_id,siteIds}
siteIds - 包含超过1000个值列表。
site_id - 列视图名称
所以我面临的问题是当siteIds包含超过1000个值时,我会得到以下错误
net.sf.jasperreports.engine.JRException: Error executing SQL statement for : report name
at net.sf.jasperreports.engine.query.JRJdbcQueryExecuter.createDatasource(JRJdbcQueryExecuter.java:229)
at net.sf.jasperreports.engine.fill.JRFillDataset.createQueryDatasource(JRFillDataset.java:758)
at net.sf.jasperreports.engine.fill.JRFillDataset.initDatasource(JRFillDataset.java:623)
at net.sf.jasperreports.engine.fill.JRBaseFiller.setParameters(JRBaseFiller.java:1160)
at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:802)
at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:746)
at net.sf.jasperreports.engine.fill.JRFiller.fillReport(JRFiller.java:58)
at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:417)
at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:247)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
Caused by: java.sql.SQLException: ORA-01795: maximum number of expressions in a list is 1000
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:573)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1891)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteDescribe(TTC7Protocol.java:830)
at oracle.jdbc.driver.OracleStatement.doExecuteQuery(OracleStatement.java:2391)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2672)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:589)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:527)
at net.sf.jasperreports.engine.query.JRJdbcQueryExecuter.createDatasource(JRJdbcQueryExecuter.java:222)
... 102 more
信息 - PDF生成器耗时3667毫秒。
异常引起:java.sql.SQLException:ORA-01795:列表中的最大表达式数为1000
我已经使用
在Hibernate中解决了这个问题private static final int PARAMETER_LIMIT = 999;
public static Criterion buildInCriterion(String propertyName, List<?> collection) {
Criterion criterion = null;
List<?> subList;
int listSize = collection.size();
for (int i = 0; i < listSize; i += PARAMETER_LIMIT) {
if (listSize > i + PARAMETER_LIMIT) {
subList = collection.subList(i, (i + PARAMETER_LIMIT));
} else {
subList = collection.subList(i, listSize);
}
if (criterion != null) {
criterion = Restrictions.or(criterion, Restrictions.in(propertyName, subList));
} else {
criterion = Restrictions.in(propertyName, subList);
}
}
return criterion;
}
我可以在 JasperReports 中为$ X语句使用任何解决方案吗?
答案 0 :(得分:3)
您获得的错误消息不是特定于Jasper的,而是特定于Oracle的; Oracle在IN列表中不允许超过1000个元素。
如果不能让Jasper自动将IN列表拆分成几个子子句,您可以使用以下解决方法之一:
$X{IN,site_id, siteIds}
替换为WHERE site_id IN (SELECT site_id FROM <temporary_table_name> )
$X(IN,site_id,siteIds}
替换为WHERE site_id IN (SELECT site_id FROM TABLE(<bindvariable_with_collection_holding_siteIDs>)
(这仅在Jasper支持集合作为绑定变量时才有效)