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

时间:2016-04-15 09:02:48

标签: java plsql oracle11g

我正在尝试在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());
        }
    }
}

提前致谢: - )

2 个答案:

答案 0 :(得分: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和循环完全消失了。

答案 1 :(得分:0)

您的示例有以下问题:

  1. 匿名PL / SQL块无法返回任何内容。
  2. PL / SQL块中声明的变量无法转义范围。在您的示例中,l_console_message变量仅在匿名PL / SQL块中可见,而不在Java代码中可见。
  3. 如果要从PL / SQL代码返回值(或结果集),则需要独立或包子程序。或者使用由@ mario-tank链接的idea,其中您的主机环境(您的Java代码)绑定输出变量。

    Internet和StackOverflow有很多例子如何从Java调用PL / SQL代码。