将 plsql 变量值从匿名块打印到 Java

Posted

技术标签:

【中文标题】将 plsql 变量值从匿名块打印到 Java【英文标题】:print plsql variable value from anonymous block to Java 【发布时间】:2016-04-15 09:02:47 【问题描述】:

我正在尝试用 Java 打印 plsql 变量值 (l_console_message)。但是,这种方法似乎不起作用。我相信 ResultSet 位出现问题。我在这里遗漏了一些东西。任何想法,出了什么问题?

     PreparedStatement statement = null;
     try 
        statement = connection.prepareStatement("\n" +
            " declare " + "\n" +
            " p_schema_name varchar2(400):= upper('" + schema + "'); " + "\n" + 
            " p_temp_table_name varchar2(400) := upper('temp_table_jobs_name'); " + "\n" +
            " l_result varchar2(400); " + "\n" +
            " l_owner varchar2(200); " + "\n" +
            " l_job_name varchar2(200); " + "\n" +
            " l_enabled varchar2(200); " + "\n" +
            " l_console_message varchar2(4000); " + "\n" +
            " cursor c1_temp_table_name is " + "\n" +
                " select " + "\n" +
                    " table_name " + "\n" +  
                " from all_tables " + "\n" +
                " where table_name = p_temp_table_name; " + "\n" +
            " begin " + "\n" +
                " open c1_temp_table_name; " + "\n" +
                " fetch c1_temp_table_name into l_result; " + "\n" +
                " if c1_temp_table_name %notfound then " + "\n" +
                    " execute immediate ' " + "\n" +
                        " create table '||p_schema_name||'.'||p_temp_table_name||' ( " + "\n" +
                            " schema_name varchar2 (1000), " + "\n" +
                            " job_name varchar2(1000), " + "\n" +
                            " status varchar2(100) " + "\n" +
                        " )'; " + "\n" +
                    " l_console_message := p_temp_table_name||' created.'; " + "\n" +
                    " dbms_output.put_line (l_console_message); " + "\n" +
                " end if; " + "\n" +
                " close c1_temp_table_name; " + "\n" +
            " exception when others then " + "\n" +
                " null; " + "\n" +
            " end;");
    ResultSet rs = statement.execute(); 
    while (rs.next())
        System.out.println(rs.getString(l_console_message));
           
 
catch (SQLException e) 
    System.out.println("ERROR: Unable to run SQL statements for schema " + schema + " in beforeMigrate: " + e.getMessage());
 
finally 
    if (null != statement) 
        try 
            statement.close();
         
        catch (SQLException se) 
            System.out.println("ERROR: Unable to close statement in beforeMigrate: " + se.getMessage());
        
    

提前致谢:-)

【问题讨论】:

***.com/questions/5101529/… 谢谢。该示例具有参考光标。现在,就我而言。我根本没有。我确实尝试做一些更改,但我开始收到“无效的列索引”错误。 该示例确实有一个引用游标,但它也有一个字符串,因此它有两个 OUT 绑定变量,以及一个 IN 绑定变量。您只需要一个 OUT 变量,因此您的注册/获取索引仅为 1。 【参考方案1】:

评论中链接的问题显示了您需要做什么的示例,但您似乎很难将其转化为您的情况。

您的匿名块不(也不能)返回结果集,因此它不应该作为查询执行,也不应该是准备好的语句;你需要有一个可调用的语句:

 CallableStatement statement = null;
 try 
    statement = connection.prepareStatement("\n" +
 ...

然后您需要将 PL/SQL 变量的值分配给绑定变量占位符:

 ...
                " l_console_message := p_temp_table_name||' created.'; " + "\n" +
                " ? := l_console_message; " + "\n" +
            " end if; " + "\n" +
 ...

或者根本没有l_console_message(所以它甚至不需要声明),只需将字符串直接分配给绑定变量占位符:

 ...
                " ? := p_temp_table_name||' created.'; " + "\n" +
            " end if; " + "\n" +
 ...

无论哪种方式,dbms_output 调用在这里都没有用。 (实际上可能是您从 Java 中检索 dbms_output 缓冲区,但工作量更大)。

然后你需要声明一个OUT绑定变量来接收字符串,并用execute()而不是executeQuery()调用语句:

    statement.registerOutParameter(1, Types.VARCHAR);
    statement.execute();

然后就可以取回已经放入绑定变量的字符串值了;例如直接打印到控制台:

    System.out.println(statement.getString(1));

ResultSetrs 和循环已完全消失。

【讨论】:

谢谢亚历克斯。 Java 中的变量绑定对我来说是新事物。现在我该如何循环执行。我需要做 statement.registerOutParameter(1, Types.CURSOR); ? 循环执行什么?您想使用不同的模式值多次执行同一个块吗?每次执行仍然会返回一个字符串。【参考方案2】:

您的示例存在以下问题:

    匿名 PL/SQL 块不能返回任何内容。 在 PL/SQL 块中声明的变量无法逃脱范围。在您的示例中,l_console_message 变量仅在匿名 PL/SQL 块中可见,在您的 Java 代码中不可见。

如果您想从 PL/SQL 代码中返回一个值(或结果集),那么您需要一个独立的或打包的子程序。或者使用由@mario-tank 链接的idea,您的主机环境(您的Java 代码)将绑定输出变量。

Internet 和 *** 有大量如何从 Java 调用 PL/SQL 代码的示例。

【讨论】:

以上是关于将 plsql 变量值从匿名块打印到 Java的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在不指定类型的情况下将变量值打印到调试?

如何在javascript中维护父变量值[重复]

plsql developer11怎么用

匿名函数获取变量值

Node.js:如何将 JS 变量值从脚本传递到终端?

通过子程序将一组变量值传递给没有公共块的函数都有哪些方法?