You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BIRT 4.14代码执行报表抛SQL错误,设计器运行正常

BIRT 4.14报表代码执行时SQL/Schema错误排查方案

问题现象

BIRT 4.14设计的报表在设计器内运行正常,但通过Java代码调用时持续抛出SQL相关错误:

  • 带public前缀的SQL报语法错误:Syntax error: Encountered "public" at line 1, column 8
  • 移除public后报Schema不存在:Schema 'SA' does not exist
  • 移除SQL参数后仍触发相同Schema错误

错误日志

带public前缀时的报错:

Apr 23, 2024 6:36:39 PM org.eclipse.birt.data.engine.odaconsumer.Connection prepareOdaQuery
SEVERE: Failed to prepare the following query for the data set type (org.eclipse.birt.report.data.oda.jdbc.JdbcSelectDataSet). 
[SELECT public.users.first_name, public.users.last_name
FROM public.users
WHERE id = ?
]
org.eclipse.birt.report.data.oda.jdbc.JDBCException: Error preparing SQL statement.
SQL error #1:Syntax error: Encountered "public" at line 1, column 8

移除public后的报错:

PM org.eclipse.birt.data.engine.odaconsumer.Connection prepareOdaQuery
SEVERE: Failed to prepare the following query for the data set type (org.eclipse.birt.report.data.oda.jdbc.JdbcSelectDataSet). 
[SELECT first_name, last_name
FROM users
WHERE id = ?
]
org.eclipse.birt.report.data.oda.jdbc.JDBCException: Error preparing SQL statement.
SQL error #1:Schema 'SA' does not exist

移除参数后的报错:

Apr 23, 2024 6:40:02 PM org.eclipse.birt.data.engine.odaconsumer.Connection prepareOdaQuery
SEVERE: Failed to prepare the following query for the data set type (org.eclipse.birt.report.data.oda.jdbc.JdbcSelectDataSet). 
[SELECT first_name, last_name
FROM users

]
org.eclipse.birt.report.data.oda.jdbc.JDBCException: Error preparing SQL statement.
SQL error #1:Schema 'SA' does not exist

代码片段

public void generateReport(Integer userId, Integer courseId, HttpServletResponse response, HttpServletRequest request) throws EngineException, IOException, SQLException {
    IReportRunnable reportDesign = reportEngine.openReportDesign("UserStatistics\\user_answers_statistic_for_course.rptdesign"); // classpath in the result jar

    IRunAndRenderTask task = reportEngine.createRunAndRenderTask(reportDesign);

    response.setContentType(reportEngine.getMIMEType("pdf"));

    PDFRenderOption pdfRenderOption = new PDFRenderOption();
    pdfRenderOption.setOutputFormat(HTMLRenderOption.OUTPUT_FORMAT_PDF);

    task.setRenderOption(pdfRenderOption);
    pdfRenderOption.setOutputStream(response.getOutputStream());
    task.getAppContext().put("OdaJDBCDriverPassInConnection", dataSource.getConnection());
    task.setParameter("UserId", userId, "");
    task.setParameter("CourseId", courseId, "");
    task.run();
}

核心原因

设计器与代码运行时的数据库连接默认Schema不一致:

  • 设计器中配置的连接默认指向public Schema,因此带public前缀的SQL可正常执行;
  • 代码中dataSource.getConnection()获取的连接默认使用SA Schema(多数数据库如H2的默认用户/Schema为SA),但目标表实际在public Schema下,导致找不到表;
  • 部分数据库驱动对public.users这种Schema前缀写法支持有限,或当前连接用户无public Schema访问权限,触发语法错误。

解决方案

方案1:修改代码中JDBC连接的默认Schema

获取连接后,手动指定默认Schema为public(不同数据库语法略有差异):

Connection conn = dataSource.getConnection();
// PostgreSQL语法
conn.createStatement().execute("SET search_path TO public");
// H2语法
// conn.createStatement().execute("SET SCHEMA public");

task.getAppContext().put("OdaJDBCDriverPassInConnection", conn);

方案2:调整报表SQL并确认权限

保持报表SQL的Schema前缀写法,同时确保代码使用的数据库用户拥有public Schema的访问权限:

SELECT first_name, last_name
FROM public.users
WHERE id = ?

方案3:对齐设计器与代码的数据源配置

确保设计器中使用的数据源(用户、默认Schema)与代码中dataSource的配置完全一致,消除环境差异。

验证步骤

  1. 应用上述任一方案后重新运行代码;
  2. 若仍报错,检查数据库用户对public Schema下users表的访问权限;
  3. 打印当前连接的默认Schema,确认配置生效:
DatabaseMetaData meta = conn.getMetaData();
System.out.println("当前默认Schema: " + meta.getUserName()); // 不同数据库获取方式略有差异

内容的提问来源于stack exchange,提问作者Арина Бабаян

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 14:30:33