在 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)
返回一个date
。 to_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)