当前位置: 首页 > 知识库问答 >
问题:

从java运行Oracle sql脚本会产生SQLSyntaxErrorException:ORA-00900:无效的sql语句

郎思远
2023-03-14

我正在使用Oracle 11g,我正在通过java代码执行Oracle sql脚本。我的SQL脚本可能包含SQL语句(DDL或DML)或PL/SQL块,所以我不想在我的java代码中解析脚本,而是使用此解决方案一次执行完整的脚本。下面是示例代码,其中SQLExec类位于ant jar中。

此解决方案适用于大多数情况,但如果sql脚本包含create或replace trigger,则会因java.sql.SQLSyntaxErrorException:ORA-00900:invalid sql语句而失败。我还指定了失败的sql脚本片段。

请注意,如果我通过SQLDeveloper运行相同的脚本,它运行良好。

以下是Java代码:

private void executeSql(String sqlFilePath) {
    final class SqlExecuter extends SQLExec {
        public SqlExecuter() {
            Project project = new Project();
            project.init();
            setProject(project);
            setTaskType("sql");
            setTaskName("sql");
        }
    }

    SqlExecuter executer = new SqlExecuter();
    executer.setSrc(new File(sqlFilePath));
    executer.setDriver(args.getDriver());
    executer.setPassword(args.getPwd());
    executer.setUserid(args.getUser());
    executer.setUrl(args.getUrl());
    executer.execute();
}

SQL脚本片段:

......
......
CREATE OR REPLACE TRIGGER MY_TRG
   BEFORE INSERT ON MY_TABLE
   FOR EACH ROW
   BEGIN
    :NEW.MYNUMBER := MY_SEQUENCENUM.NEXTVAL;
   END;

以下是异常跟踪:

Exception in thread "main" java.sql.SQLSyntaxErrorException: ORA-00900: invalid SQL statement

    at org.apache.tools.ant.taskdefs.SQLExec.execute(SQLExec.java:398)
    at com.kuldeep.OracleConnectionTest.executeSql(OracleConnectionTest.java:160)
    at com.kuldeep.OracleConnectionTest.main(OracleConnectionTest.java:25)
Caused by: java.sql.SQLSyntaxErrorException: ORA-00900: invalid SQL statement

    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:439)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:395)
    at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:802)
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:436)
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:186)
    at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:521)
    at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:194)
    at oracle.jdbc.driver.T4CStatement.executeForRows(T4CStatement.java:1000)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1307)
    at oracle.jdbc.driver.OracleStatement.executeInternal(OracleStatement.java:1882)
    at oracle.jdbc.driver.OracleStatement.execute(OracleStatement.java:1847)
    at oracle.jdbc.driver.OracleStatementWrapper.execute(OracleStatementWrapper.java:301)
    at org.apache.tools.ant.taskdefs.SQLExec.execSQL(SQLExec.java:499)
    at org.apache.tools.ant.taskdefs.SQLExec.runStatements(SQLExec.java:470)
    at org.apache.tools.ant.taskdefs.SQLExec$Transaction.runTransaction(SQLExec.java:664)
    at org.apache.tools.ant.taskdefs.SQLExec$Transaction.access$000(SQLExec.java:627)
    at org.apache.tools.ant.taskdefs.SQLExec.execute(SQLExec.java:370)

共有3个答案

蒋高超
2023-03-14

我想你需要改变你的触发器来设置你的新ID

create or replace trigger MY_TRG
BEFORE insert MY_TABLE
for each row
begin
  if (:new.MYNUMBER  is null) then
    select MY_SEQUENCENUM.nextval
    into :new.MYNUMBER 
    from DUAL;
  end if;
end;
/

或者这个:

create or replace trigger TG_BIU_TABLE1
before insert or update on TABLE1
for each row
begin
    if (:new.ID1 is null) then
        select SQ_TABLE1.nextval
        into :new.ID1
        from DUAL
    end if
end
/
斜昊空
2023-03-14

正如@Reza Goodarzi提到的无效SQL语句的原因是分号被用作语句分隔符。所以为了解决我的问题,我用slash(/)作为分隔符分隔每个语句,并遵循我自己创建的规则:

>

SQL语句(不是PL/SQL块的一部分)不应以分号(;)结尾。我刚刚删除了语句末尾的分号。

对于PL/SQL块,不要从块的末尾以及块中包含的任何语句中删除分号(;)。

通过在我的SQL脚本中进行这些更改,我通过解析一次执行(使用jdbc)每个PL/SQL块和每个SQL语句(不是PL/SQL块的一部分)文件自己而不是使用SQLExec或任何其他外部api/库。

单于骁
2023-03-14

在留档里写着:

可以提供多个语句,用分号(或定义的分隔符)分隔。

因此,使用分号字符(;)作为默认分隔符,SQLEXEC脚本CREATE TRIGGER语句解释为两条语句,并将此错误消息作为结果。

 类似资料:
  • 问题内容: 我正在使用Oracle 11g,正在通过Java代码执行Oraclesql脚本。我的SQL脚本可能包含SQL语句(DDL或DML)或PL /SQL块,因此我不想解析Java代码中的脚本,但使用此解决方案立即执行了完整的脚本。以下是示例代码,其中包含SQLExec类。 此解决方案在大多数情况下都有效,除了如果sql脚本包含它会失败,并显示 java.sql.SQLSyntaxErrorE

  • 我已使用以下代码创建了一个Oracle SP。如果我从SQLDeveloper执行它,那么它运行时不会出现任何错误/问题。但是,当我尝试从.NET代码调用同一SP时,将引发一个异常,并显示消息“Oracle.DataAccess.Client.OracleException:ORA-00900:invalid SQL statement”。 Oracle SP代码: 我的VB.NET代码: 有什么

  • 当我打开SQL开发人员时,相同的列以完全相同的名称存在。它发生在一些UAT和prod DB中,但在一些UAT数据库中工作。 请帮助我 另请说明以下例外情况的区别 < li>ORA-00904:"列名":无效的标识符 < li>ORA-00904:"表名"。" columnName ":无效标识符

  • 不确定是什么导致了这个错误... 我有一个名为StudentUnit的类,它可以包含一系列单元。 如果我只得到StudentUnit对象,结果是ok的,但是如果我尝试获得这些单元(添加fetchType==eager),那么我得到的是java.sql。SQLSyntaxErrorException:ORA-01722:无效数字 但请注意,我映射到单位上的字段(unitCode,unitNm)都是字

  • 在Oracle的SQL developer中,我创建了一个名为BBS_COUNT_base的表,其定义如下: 我还使用以下语句在表中插入了一条记录: 现在,使用SQLDeveloper,我可以使用 将基本edn值更新为(在本测试案例中)相同的值。 但是,当我试图将此语句传递给clojure.java.jdbc/query时,JDBC驱动程序错误输出,标题中显示了错误。有人知道为什么JDBC驱动程序

  • 我在尝试从Java运行R脚本时遇到了一个问题。我真的在互联网上寻找这个问题的答案,但什么都不管用。 求你帮帮我 这是java代码 以下是当我添加Runtime.getRuntime(). exec("Rcript"rScriptFileName)时抛出的错误消息: