查看: 7719|回复: 8

[PL/SQL] Oracle存储过程,以游标的方式返回一个记录集

[复制链接]
论坛徽章:
0
跳转到指定楼层
1#
发表于 2007-6-5 11:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请帮我看段java调用返回游标 名为proc_get_alarmtrend_class的存储过程的代码:
conn = DbConnect.getInstance().getConnection();
proc = conn.prepareCall("{ call proc_get_alarmtrend_class(?,?) }";
proc.setLong(1, 1175875000000L);
proc.registerOutParameter(2,oracle.jdbc.OracleTypes.CURSOR);
proc.execute();
rs = (ResultSet)proc.getObject(2);

// rs = proc.executeQuery();
while(rs.next())
{
System.out.println("ok:";
}
该存储过程传入一个长整型的数据,返回一个游标,在pl/sql里面测试没有问题。在java调用时,出现错误:
严重: 存储过程执行失败: java.lang.ClassCastException: $Proxy3
存储过程里面的语句已经执行,是到了 rs = (ResultSet)proc.getObject(2);出现上面的错。为什么?是版本不一致吗?
论坛徽章:
64
会员2007贡献徽章
日期:2007-09-26 18:42:10NBA常规赛纪念章
日期:2008-04-18 19:48:16欧洲冠军杯纪念徽章
日期:2008-05-23 14:31:342009新春纪念徽章
日期:2009-01-04 14:52:28NBA常规赛纪念章
日期:2009-04-16 14:28:42NBA季后赛纪念徽章
日期:2009-06-16 11:28:172010新春纪念徽章
日期:2010-01-04 08:33:08
2#
发表于 2007-6-5 13:33 | 只看该作者
其实将使用游标返回结果集 修改为使用临时创建表来存储结果集的方式,java调用起来将方便多了.

使用道具 举报

回复
论坛徽章:
18
生肖徽章2007版:虎
日期:2008-04-11 18:37:24奥运会纪念徽章:击剑
日期:2008-07-03 11:38:17迷宫蛋
日期:2011-05-10 13:03:40茶鸡蛋
日期:2011-05-10 13:05:16蜘蛛蛋
日期:2011-05-10 13:07:01灰彻蛋
日期:2012-12-10 11:47:16鲜花蛋
日期:2013-07-07 10:07:20
3#
发表于 2007-6-5 13:43 | 只看该作者
将procedure更改为function,
具体请参考下面Link中所说
http://www.itpub.net/787056.html

使用道具 举报

回复
论坛徽章:
115
生肖徽章:狗
日期:2007-01-06 21:14:12马上有车
日期:2014-03-06 16:45:08马上加薪
日期:2014-05-09 12:27:582014年世界杯参赛球队: 英格兰
日期:2014-07-03 13:10:44青年奥林匹克运动会-竞技体操
日期:2014-09-10 15:30:57马上有钱
日期:2014-10-31 13:56:48美羊羊
日期:2015-03-04 14:48:582015年新春福章
日期:2015-03-06 11:57:31懒羊羊
日期:2015-04-23 19:26:10金牛座
日期:2015-09-17 08:21:44
4#
发表于 2007-6-5 13:48 | 只看该作者
[PHP]
create or replace package pkg_test
as
  type pagination is ref cursor;
  procedure page
  (
    p_count             in out pls_integer,
    p_page              in out pagination
  );
end;
/

create or replace package body pkg_test
as
  procedure page
  (
    p_count             in out pls_integer,
    p_page              in out pagination
  )
  is
  begin
    execute immediate 'select count(*) from test' into p_count;
    open p_page for 'select id from test';
  end;
end;
/
.
[/PHP]
        public Object[] page_test()
        {
                int count = 0;
                try
                {
                conn = DriverManager.getConnection("jdbcracle:thin:@192.168.1.1:1521:数据库SID","用户名","密码";
                cstmt = (OracleCallableStatement)conn.prepareCall("begin pkg_test.page(?,?); end;";
                cstmt.registerOutParameter(1,OracleTypes.INTEGER);
                cstmt.registerOutParameter(2,OracleTypes.CURSOR);
                cstmt.execute();
                count = cstmt.getInt(1);
                rs = (ResultSet)cstmt.getObject(2);
                }
                catch(SQLException et)
                {System.err.println("Error: "+et.getMessage());}
                return new Object[] {new Integer(count), rs};
        }

使用道具 举报

回复
论坛徽章:
0
5#
 楼主| 发表于 2007-6-6 15:15 | 只看该作者
原来是在eclipse下测试java调用存储过程会报类映射异常,在jboss环境下测试不会报错,可能跟环境有关,但是这样也比较麻烦,不能在eclipse下直接测试。
不只用临时表的原因是:项目使用postgresql数据库,但有可能要部署到oracle数据库,而且是分布式部署,所以直接在存储过程中返回值,而不用临时表直接返回。

使用道具 举报

回复
论坛徽章:
115
生肖徽章:狗
日期:2007-01-06 21:14:12马上有车
日期:2014-03-06 16:45:08马上加薪
日期:2014-05-09 12:27:582014年世界杯参赛球队: 英格兰
日期:2014-07-03 13:10:44青年奥林匹克运动会-竞技体操
日期:2014-09-10 15:30:57马上有钱
日期:2014-10-31 13:56:48美羊羊
日期:2015-03-04 14:48:582015年新春福章
日期:2015-03-06 11:57:31懒羊羊
日期:2015-04-23 19:26:10金牛座
日期:2015-09-17 08:21:44
6#
发表于 2007-6-6 15:58 | 只看该作者
这个和什么环境没有关系的
eclipse只是一个开发部署工具,JBOSS是应用服务器,不是一个概念
我的方法是可行的,如果有问题,你自己改一下
其实google一把也很多

使用道具 举报

回复
论坛徽章:
24
生肖徽章:狗
日期:2006-09-07 10:14:43数据库板块每日发贴之星
日期:2008-07-26 01:02:20生肖徽章2007版:兔
日期:2008-10-13 11:10:11奥运会纪念徽章:铁人三项
日期:2008-10-24 13:27:21开发板块每日发贴之星
日期:2008-12-27 01:01:09生肖徽章2007版:马
日期:2009-11-18 10:45:032010新春纪念徽章
日期:2010-03-01 11:21:02ITPUB9周年纪念徽章
日期:2010-10-08 09:28:51ERP板块每日发贴之星
日期:2011-05-18 01:01:01ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15
7#
发表于 2007-6-6 19:51 | 只看该作者
那天看看java了!

使用道具 举报

回复
论坛徽章:
115
生肖徽章:狗
日期:2007-01-06 21:14:12马上有车
日期:2014-03-06 16:45:08马上加薪
日期:2014-05-09 12:27:582014年世界杯参赛球队: 英格兰
日期:2014-07-03 13:10:44青年奥林匹克运动会-竞技体操
日期:2014-09-10 15:30:57马上有钱
日期:2014-10-31 13:56:48美羊羊
日期:2015-03-04 14:48:582015年新春福章
日期:2015-03-06 11:57:31懒羊羊
日期:2015-04-23 19:26:10金牛座
日期:2015-09-17 08:21:44
8#
发表于 2007-6-9 18:13 | 只看该作者
给你一个调试通过的例子
[PHP]
SQL> desc aa
Name                                      Null?    Type
----------------------------------------- -------- ----------------------------
ID                                                 VARCHAR2(2)

SQL> select * from aa;

ID
--
1
2
3
4
5
6
7
8
9
10
11

11 rows selected.

---------------
建立PACKAGE
---------------
create or replace package pkg_test
as
  type pagination is ref cursor;
  procedure page_test
  (
    p_count             in out pls_integer,
    p_page              in out pagination,
    p_beg               in pls_integer,
    p_end               in pls_integer,
    p_id                in varchar2
  );
end;
/

create or replace package body pkg_test
as
  procedure page_test
  (
    p_count             in out pls_integer,
    p_page              in out pagination,
    p_beg               in pls_integer,
    p_end               in pls_integer,
    p_id                in varchar2
  )
  is
    sql_count           varchar2(1000)  := '';
    sql_page            varchar2(30000) := '';
  begin
    sql_count := 'select count(*) from aa';
    sql_page  := 'select id from aa where rownum<=10';
    execute immediate sql_count into p_count;
    open p_page for sql_page;
  end;
end;
/

---------
test.java
---------
[/PHP]

import java.sql.*;
import java.util.*;
import oracle.jdbc.driver.*;
import oracle.sql.*;

public class test
{
        public static void main(String args[]) throws Exception
        {
                DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
                Connection conn = DriverManager.getConnection("jdbcracle:thin:@192.168.1.1:1521:数据库SID","用户名","密码";
                OracleCallableStatement cstmt = (OracleCallableStatement)conn.prepareCall("begin pkg_test.page_test(?,?,?,?,?); end;";
                cstmt.registerOutParameter(1,OracleTypes.VARCHAR);  //返回记录数
                cstmt.registerOutParameter(2,OracleTypes.CURSOR);   //返回结果集
                cstmt.setInt(3,1);                                  //起始记录号
                cstmt.setInt(4,10);                                 //结束记录号
                cstmt.setString(5,"10";                            //WHERE 条件
                cstmt.execute();
                ResultSet rs = (ResultSet)cstmt.getObject(2);
                while (rs.next())
                {
                        System.out.println(rs.getString(1));
                }
        }
}

使用道具 举报

回复
论坛徽章:
24
生肖徽章:狗
日期:2006-09-07 10:14:43数据库板块每日发贴之星
日期:2008-07-26 01:02:20生肖徽章2007版:兔
日期:2008-10-13 11:10:11奥运会纪念徽章:铁人三项
日期:2008-10-24 13:27:21开发板块每日发贴之星
日期:2008-12-27 01:01:09生肖徽章2007版:马
日期:2009-11-18 10:45:032010新春纪念徽章
日期:2010-03-01 11:21:02ITPUB9周年纪念徽章
日期:2010-10-08 09:28:51ERP板块每日发贴之星
日期:2011-05-18 01:01:01ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15
9#
发表于 2007-6-10 19:13 | 只看该作者
学习!

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表