在 Java 中调用 Oracle PL/SQL 中的过程或函数。返回结果集 false

Posted

技术标签:

【中文标题】在 Java 中调用 Oracle PL/SQL 中的过程或函数。返回结果集 false【英文标题】:In Java calling procedure or function in Oracle PL/SQL. Return Resultset false 【发布时间】:2016-07-20 11:08:56 【问题描述】:

我有一个函数plsql,在plsql中运行函数返回游标有数据 但是我在java问题中调用这个函数返回光标为空 帮我处理这个问题

这是函数oracle plsql

FUNCTION get_canh_bao
      ( p_toolname      in  varchar2,
        p_toolid        in  varchar2,
        p_toolurl       in  varchar2,
        p_parent        in  varchar2)
      RETURN  sys_refcursor IS

    s           varchar2(32000);
    ptype       varchar2(32000);
    pday        varchar2(32000);
    psql        varchar2(32000);
    pcreate     varchar2(32000);
    re          sys_refcursor;
    pwhere      varchar2(32000);
BEGIN
--
    pwhere := '';
    s := 'select b.TYPE_REPORT, b.DAY_NHAPLIEU, a.sql_cmd, a.name_createdate'
        ||' from cpcdata.tbl_config_nhaplieu a'
        ||' left join cpcdata.tbl_mainmenu b'
        ||' on a.tool_id = b.ID '
        ||' where b.show_all = 0 and b.flag = 1 and b.ID = '''||p_toolid||'''';
    execute immediate s INTO ptype, pday, psql, pcreate;
            -- Tinh ngay canh bao
            if (INSTR(psql,'where') > 0 ) then
                pwhere := ' and ';
            else
                pwhere := ' where ';
            end if;
            CASE
                WHEN ptype = 'day'    THEN
                    s := psql ||pwhere|| ' to_char('||pcreate||',''dd/mm/yyyy'') = to_char(sysdate - '||pday||',''dd/mm/yyyy'')';
                WHEN ptype = 'week'   THEN
                    s := psql ||pwhere||pcreate||' between to_date(TRUNC (sysdate, ''iw''),''dd/mm/yyyy'') and'
                              || ' to_date(TRUNC(sysdate, ''iw'') + 7 - 1/86400- '||pday||',''dd/mm/yyyy'')';
                WHEN ptype = 'month'  THEN
                    s := psql ||pwhere||pcreate||' between to_date(TRUNC (sysdate, ''mm''),''dd/mm/yyyy'') and'
                              || ' to_date(LAST_DAY(TRUNC (sysdate, ''mm'')) + 1 - 1/86400 - '||pday||',''dd/mm/yyyy'')';
                WHEN ptype = 'quy'    THEN
                    s := psql ||pwhere||pcreate||' between to_date(TRUNC(sysdate, ''Q''),''dd/mm/yyyy'') and'
                              || ' to_date(add_months(trunc(sysdate,''Q''),3)- 1 - '||pday||', ''dd/mm/yyyy'')';
                WHEN ptype = 'year'   THEN
                    s := psql ||pwhere||pcreate||' between to_date(TRUNC (SYSDATE , ''YEAR''),''dd/mm/yyyy'') and'
                              || ' to_date(ADD_MONTHS(TRUNC (SYSDATE,''YEAR''),12) - 1 - '||pday||', ''dd/mm/yyyy'')';
                ELSE return null;
            END CASE;
    dbms_output.put_line(''||s);
    open re for s;
    RETURN re ;
    exception when others then
        declare
            s_err       varchar2(2000);
            str         varchar(2000);
            c_err       sys_refcursor;
        begin
            s_err := 'loi khi lay du lieu '|| sqlerrm;
            str := 'select '||s_err||' from dual';
            open c_err for str;
            return c_err;
        end;
END;

这是代码java调用函数

ArrayList arr = new ArrayList();
            sql = "begin ? := config_pkg.get_canh_bao(?,?,?,?); end;";
            cs = conn.prepareCall(sql);
            cs.registerOutParameter(1, OracleTypes.CURSOR);
            cs.setString(2, "");
            cs.setString(3, "502");
            cs.setString(4, "");
            cs.setString(5, "");
            cs.executeQuery();
            ResultSet rs = (ResultSet)cs.getObject(1);
            System.out.println("------------Exception---------------"+rs.next());
            while (rs.next()) 

              System.out.println("a");
              String[] str =
              "1" ;
              arr.add(str);
            

【问题讨论】:

光标为“空”是什么意思?你的意思是它不返回任何行,或者它是无效的,还是失败了?此外,trunc(date) 返回一个dateto_date() 仅适用于字符串,因此 to_date(date) 使用会话默认值隐式将日期转换为字符串,然后再次将其转换回日期,这可能会产生意想不到的结果。 我确定,它没有返回游标数据。 为什么在 Oracle PL/SQL 中调用过程或函数时。它返回游标包含数据 【参考方案1】:

你应该使用绑定变量,类似这样:

pwhere := '';
s := 'select b.TYPE_REPORT, b.DAY_NHAPLIEU, a.sql_cmd, a.name_createdate'
    ||' from cpcdata.tbl_config_nhaplieu a'
    ||' left join cpcdata.tbl_mainmenu b'
    ||' on a.tool_id = b.ID '
    ||' where b.show_all = 0 and b.flag = 1 and b.ID = :toolId';
execute immediate s INTO ptype, pday, psql, pcreate USING toolId;
        -- Tinh ngay canh bao
        if (INSTR(psql,'where') > 0 ) then
            pwhere := ' and ';
        else
            pwhere := ' where ';
        end if;
        s := psql ||pwhere||pcreate||' between :aDate AND :bDate';

        CASE
            WHEN ptype = 'day'    THEN ...
            WHEN ptype = 'week'   THEN
                open re for s USING TRUNC (sysdate, 'iw'), TRUNC(sysdate, 'iw') + 7 - 1/86400- pday;
            WHEN ptype = 'month'  THEN ...
        END CASE;

【讨论】:

谢谢你,我尝试使用绑定变量但函数没有返回数据记录

以上是关于在 Java 中调用 Oracle PL/SQL 中的过程或函数。返回结果集 false的主要内容,如果未能解决你的问题,请参考以下文章

如何使用参数从 Oracle PL/SQL 执行 Java jar 文件?

从 Java 应用程序调用时,Oracle PL/SQL 包错误(ORA-04063 和 ORA-06508)

Oracle PL/SQL - 由其他团队调用的用于插入数据的过程。正在从 Java 调用过程

pl/sql编程基础

oracle SQL语句中怎么样调用存储过程

在 ORACLE 的 select 语句中从 PL/SQL 调用函数