Java中调用存储过程或存储函数的方法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Java中调用存储过程或存储函数的方法.txt机会就像秃子头上一根毛,你抓住就抓住了,抓不住就没了。我和你说了10分钟的话,但却没有和你产生任何争论。那么,我们之间一定有个人变得虚伪无比!过错是短暂的遗憾,错过是永远的遗憾。相遇是缘,相知是份,相爱是约定,相守才是真爱。1.调用存储过程:
CallableStatement clstmt = null;
try {
clstmt = conn.prepareCall("{call package_name.procedure_name(?,?,?,?,?)}");
clstmt.setString(1, bill.getBillType());
clstmt.setString(2, bill.getId());
clstmt.setInt(3, bill.getNum());
clstmt.registerOutParameter(4, Types.CHAR);
clstmt.registerOutParameter(5, Types.VARCHAR);
clstmt.execute();
out_opresult = clstmt.getString(4).trim();
out_operror = clstmt.getString(5).trim();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
2.调用存储函数:
CallableStatement clstmt = null;
try {
clstmt = conn.prepareCall("{? = call package_name.function_name(?,?,?,?)}");
clstmt.registerOutParameter(1, Types.VARCHAR);
clstmt.setString(2, bill.getBillType());
clstmt.setString(3, bill.getId());
clstmt.registerOutParameter(4, Types.CHAR);
clstmt.registerOutParameter(5, Types.VARCHAR);
clstmt.execute();
out_opresult = clstmt.getString(4).trim();
out_operror = clstmt.getString(5).trim();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
* 存储过程编写时应注意:
1.输出参数不能作为查询条件;
eg:假设,out_id已赋值,
SELECT name
INTO out_name
FROM tb_test
WHERE id = out_id;
这样写PL/SQL中会正常通过,而在Java程序调用该存储过程时会报错,需要改成: v_id CHAR(8) := '';
先对v_id赋值,
SELECT name
INTO out_name
FROM tb_test
WHERE id = v_id;
这样PL/SQL和Java程序中都可正常通过和调用。
2.如存储过程中带有Date、Boolean型参数,Java程序调用时会出错,
报类型不匹配,目前只能不用Date、Boolean型作为存储过程参数,
可能的原因:JDBC不支持。。。
测试程序如下:
存储函数如下:
FUNCTION my_test(in_test1 IN CHAR,
in_test2 IN BOOLEAN,
out_test3 OUT VARCHAR) RETURN VARCHAR IS
v_test CHAR(3) := '';
BEGIN
select 'aaa' into v_test from dual;
Return 'OK';
EXCEPTION
WHEN OTHERS THEN
out_test3 := SQLCODE;
Return SQLCODE;
END;
Java代码如下:
try {
clstmt = conn.prepareCall("{? = call my_test(?,?,?)}");
clstmt.registerOutParameter(1, Types.VARCHAR);
clstmt.setString(2, "1111111");
clstmt.setBoolean(3, false);
clstmt.registerOutParameter(4, Types.VARCHAR);
clstmt.execute();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
一个简单的调用,报错:
ORA-06550: line 1, column 13:
PLS-00306: wrong number or types of arguments in call to 'MY_TEST' ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
得出结论的测试程序:
建一个只有一个boolean型返回的funciton,然后用
for (int i=-3000;i<=3000;i++){
clstmt.registerOutParameter(1, i);
}
去逐个测试,遗憾的是,在-3000-3000中,没有一种合适的!
也就是说现有的JDBC没有对Boolean类型提供足够的支持。
目前只对Boolean型做了测试。
3.每次重新编译存储过程后,Java程序调用存储过程都报:
ORA-04068: existing state of packages这个错。
查了一下这个存储过程的package,发现:
flag_op_fail CONSTANT CHAR(1) := '1';
flag_op_succ CONSTANT CHAR(1) := '0';
not_existed CONSTANT CHAR(1) := '0';
existed CONSTANT CHAR(1) := '1';
PROCEDURE get_hos_info(in_hospital_id IN CHAR,
out_existed OUT CHAR,
out_name OUT CHAR,
out_hos_class OUT CHAR,
out_opresult OUT CHAR,
out_operror OUT VARCHAR2) IS
BEGIN
out_opresult := flag_op_fail;
out_operror := 'NULL';
BEGIN
SELECT name, hos_class
INTO out_name, out_hos_class
FROM tb_dic_yljg
WHERE hospital_id = in_hospital_id;
out_existed := existed;
out_opresult := flag_op_succ;
out_operror := 'NO_ERROR';
RETURN;
由于开始的4个变量即(flag_op_fail, flag_op_succ, not_existed,existed) 在整个package中各个存储过程都有用到,所以单独声明在外面,