![](/img/trans.png)
[英]SQLSyntaxErrorException: ORA-00900: invalid SQL statement using Java
[英]PL/SQL call from JDBC resulting in “SQLSyntaxErrorException: ORA-00900”
我正在尝试使用以下代码在我的数据库服务器上运行 PL/SQL 语句。
public class Main {
public static void main(String[] args) {
String jdbcURL = "jdbc:oracle:thin:@172.22.88.9:1521/xavier.i.com";
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
String user = "bigdb";
String password = "fakepassword";
String result = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
conn = DriverManager.getConnection(jdbcURL, user, password);
result = runStatement(conn,
"{begin ANALYZE TABLE BIGDB.scr_fct_exact_access
ESTIMATE STATISTICS; end}");
} catch (Exception ex) {
System.out.println(ex.getMessage());
ex.printStackTrace();
}
}
private static String runStatement(Connection con, String statement)
throws Exception {
PreparedStatement cstmt = con.prepareStatement(statement);
cstmt.execute(); // this is line 58
cstmt.close();
return count;
}
}
在运行代码时,我得到以下异常:
java.sql.SQLSyntaxErrorException: ORA-00900: 无效 SQL 语句
在 oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:440)
在 oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
在 oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:837)
在 oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:445)
在 oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:191)
在 oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:523)
在 oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207)
在 oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.Z93F725A07423FE1C889F448B413D541F436Z010)-在 oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1315)
在 oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3576)
在 oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3677)
在 oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:17
在 Main.prepareStatement(Main.java:58)
在 Main.main(Main.java:29)
出了什么问题,我该如何解决?
ANALYZE TABLE
是一个 DDL(数据定义语言)语句。 它在 PL/SQL 的 BEGIN/END 块中无效。 如果你想在 PL/SQL 中执行它,你需要使用 EXECUTE IMMEDIATE。
要从 JDBC 运行语句,只需创建一个Statement
实例并使用executeUpdate
:
Statement stmt = con.createStatement();
stmt.executeUpdate("ANALYZE TABLE BIGDB.scr_fct_exact_access ESTIMATE STATISTICS");
stmt.close();
但更好的主意是使用DBMS_STATS
package 来分析您的表。 然后,您可以将您的方法与 BEGIN/END 一起使用。
使用CallableStatement
而不是PreparedStatement
来运行具有 JDBC 中的 PL/SQL 块语法的语句。
但是,正如 Codo 在另一个答案中所述, ANALYZE TABLE不能完全从 PL/SQL 调用。 这是一个 SQL 命令,因此不能在 PL/SQL 块中执行。 正如正确的建议,应该使用DBMS_STATS
。 这在 ANALYZE 命令的文档中也有说明:
笔记:
对于大多数统计信息的收集,请使用 DBMS_STATS package,它允许您并行收集统计信息,收集分区对象的全局统计信息,并以其他方式微调您的统计信息收集。 有关 DBMS_STATS package 的详细信息,请参阅 Oracle 数据库 PL/SQL 包和类型参考。 使用 ANALYZE 语句(而不是 DBMS_STATS)进行与基于成本的优化器无关的统计信息收集:
使用 VALIDATE 或 LIST CHAINED ROWS 子句
收集有关 freelist 块的信息
如果您真的想避免使用DBMS_STATS
(老实说,我认为没有充分的理由避免使用它),请使用EXECUTE IMMEDIATE
或DBMS_SQL
来执行ANALYZE TABLE
命令。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.