【问题标题】:Using the Oracle database parser from Java using JDBC使用 JDBC 从 Java 中使用 Oracle 数据库解析器
【发布时间】:2013-12-23 13:55:17
【问题描述】:

我正在用 Java 编写一个工具,它将语句提交到数据库,然后运行。我正在使用 JDBC 连接到数据库。数据库是Oracle 10g。

在将语句写入数据库之前,我想解析它们以检查它们何时运行以后不会出现问题。我考虑使用 ANTLR 解决方案,因为有可用的语法,但如果我有与数据库的连接,肯定有一种方法可以使用内置于解析器的数据库。

所以基本上我的问题是:

有没有一种使用 JDBC 的方法,我可以调用数据库解析器,向它传递一条 SQL 语句,它会返回一些反馈,告诉我它是否成功或任何错误消息?

非常感谢任何帮助, 非常感谢。

编辑:

使用 connection.prepareStatement 似乎不起作用,例如此输出解析成功!

String statement = "WHERE DISTINCT SELECT";
    Connection connection;
    try {
        connection = this.controller.getDataSource().getConnection();
        connection.prepareStatement(statement);
        connection.close();
        mainPanel.setPositiveText("Parsed Successfully!");
    } catch (Exception e) {
        mainPanel.setNegativeText("ERROR: " + e.getMessage());
        return;
    }

我使用的soultion如下:

    String statement = "DECLARE "
            + "myNumber NUMBER; "
            + "BEGIN "
            + "myNumber := SYS.dbms_sql.open_cursor; "
            + "SYS.DBMS_SQL.PARSE(myNumber, '" + text + "', SYS.DBMS_SQL.NATIVE); "
            + "END;";

    Connection connection;
    try {
        connection = this.controller.getDataSource().getConnection();
        PreparedStatement preparedStatement = connection.prepareStatement(statement);
        preparedStatement.execute();
        connection.close();
        mainPanel.setPositiveText("Parsed Successfully!");
    } catch (Exception e) {
        mainPanel.setNegativeText("ERROR: " + e.getMessage());
        System.out.println(e.getMessage());
        return;
    }

【问题讨论】:

  • Statement execQuery 或 execUpdate 方法会抛出异常。

标签: java oracle jdbc


【解决方案1】:

我不知道你到底想达到什么目的,但也许你可以尝试使用包DBMS_SQL 和它的方法PARSE。这仅适用于 DML 语句。这就是 Oracle SQL Developer 所做的。

这个parser 也可能用于 DML 语句。对于 PL/SQL,它需要一些调整。据我所知,没有人花足够的时间为 Oracle 的 DDL 创建真正的完全验证解析器。

Here 是我如何使用它的一个例子:

declare 
 l_cursor number := dbms_sql.open_cursor; 
 l_offset number := -1 ; 
begin 
  begin 
    dbms_sql.parse( l_cursor, :st, dbms_sql.native ); 
  exception when others then
   l_offset := dbms_sql.last_error_position;
  end;
dbms_sql.close_cursor( l_cursor );
  :off := l_offset;
end;

只需执行此块。传递一个 VARCHAR2(String) 类型的输入参数(最大 32KB)和一个输出参数 NUMBER。

【讨论】:

  • 嗨,Ivan,dbms_sql.parse 似乎正是我所需要的。你能给我一个它的用法的小例子吗?我希望任何变量都是临时的,执行语句后数据库中应该没有任何东西。
  • 这个可以和jdbc一起使用吗,我相信我们需要执行execute()。那么,会有帮助吗?
  • 如果使用 JDBC 作为匿名 PL/SQL 块,则必须执行。
  • 当心你真的应该在 PL/SQL 块中调用dbms_sql.close_cursor( l_cursor );。否则,您将在数据库服务器端泄漏资源。 (见数据库参数OPEN_CURSORS
【解决方案2】:

如果不执行查询,您将无法获得反馈(或结果集,关于它。Connection.preparedStatement 只需返回一个 PreparedStatement 对象,它只是一个处理程序。

PreparedStatement.executeQuery() 只是实际执行查询,推送到数据库。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-24
    • 2021-07-11
    • 1970-01-01
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多