如何使用jmeter测试具有sys_refcursor返回类型的Oracle存储过程?

如何使用jmeter测试具有sys_refcursor返回类型的Oracle存储过程?,oracle,testing,stored-procedures,jmeter,sys-refcursor,Oracle,Testing,Stored Procedures,Jmeter,Sys Refcursor,我想用jmeter测试一个Oracle存储过程。除了参数,我什么都做过 下面是我的SQL查询: 申报 瓦查尔2(20); 输出表系统参考光标; 开始 {调用RK_JSCX(?,)}; 结束 Oracle中的outtable是一个游标。我使用resultSet在java中包含它。但是,无论我在参数类型中设置了什么,它都表示类型无效 样本开始时间:2012-10-25 16:06:41 CST 加载时间:0 延迟:0 大小(字节):25 标题大小(以字节为单位):0 正文大小(字节):25 样本数量

我想用jmeter测试一个Oracle存储过程。除了参数,我什么都做过

下面是我的SQL查询:

申报 瓦查尔2(20); 输出表系统参考光标; 开始 {调用RK_JSCX(?,)}; 结束

Oracle中的outtable是一个游标。我使用resultSet在java中包含它。但是,无论我在参数类型中设置了什么,它都表示类型无效

样本开始时间:2012-10-25 16:06:41 CST 加载时间:0 延迟:0 大小(字节):25 标题大小(以字节为单位):0 正文大小(字节):25 样本数量:1 错误计数:1 响应代码:null 0 响应消息:java.sql.SQLException:无效数据类型:游标

响应标题: oracle.jdbc.driver。T4CConnection@58ba09

SampleResult字段: ContentType:文本/纯文本 数据编码:UTF-8

你怎么能修好它? 谢谢

以下是我的java代码:

public String RK_JSCX() throws Exception {

    RK_JSCX_Response response = null;
    List<RK_JSCX_Outtable> list = null;
    Connection con = null;
    CallableStatement cs = null;
    ResultSet rs = null;
    String sql = null; 
    try {
        sql = "{call RK_JSCX(?,?)}";
        con = ConnectionUtils.getInstance().getConnect();

        if (con.isClosed()) {
            throw new IllegalStateException("ERROR.THE   CONNECTION   ISCLOSED");
        }

        cs = con.prepareCall(sql);
        cs.registerOutParameter(1, oracle.jdbc.OracleTypes.CURSOR);
        cs.registerOutParameter(2, Types.VARCHAR);

        cs.execute();

        rs = (ResultSet) cs.getObject(1);
        list = new ArrayList<RK_JSCX_Outtable>();
        while (rs.next()) {

            RK_JSCX_Outtable out = new RK_JSCX_Outtable(rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getInt(5), rs.getString(6));

            list.add(out);
        }
        String outInfo = cs.getString(2);
        response = new RK_JSCX_Response(list, outInfo);

    } catch (SQLException e) {

        e.printStackTrace();

    } catch (Exception e) {
        e.printStackTrace();

    }finally {

        try {
            if (rs != null) {
                rs.close();
                if (cs != null) {
                    cs.close();
                }
                if (con != null) {
                    con.close();
                }
            }
        } catch (SQLException e) {

            System.out.println("Exception2");
            e.printStackTrace();
        }
    }
    return JSON.toJSONString(response);
}
公共字符串RK_JSCX()引发异常{
RK_JSCX_Response Response=null;
List=null;
连接con=null;
CallableStatement cs=null;
结果集rs=null;
字符串sql=null;
试一试{
sql=“{调用RK_JSCX(?)}”;
con=ConnectionUtils.getInstance().getConnect();
if(con.isClosed()){
抛出新的IllegalStateException(“错误。连接已关闭”);
}
cs=con.prepareCall(sql);
registerOutParameter(1,oracle.jdbc.OracleTypes.CURSOR);
registerOutParameter(2,Types.VARCHAR);
cs.execute();
rs=(ResultSet)cs.getObject(1);
列表=新的ArrayList();
while(rs.next()){
RK_JSCX_输出表=新RK_JSCX_输出表(rs.getString(1)、rs.getString(2)、rs.getString(3)、rs.getString(4)、rs.getInt(5)、rs.getString(6));
列表。添加(输出);
}
String outInfo=cs.getString(2);
响应=新的RK_JSCX_响应(列表,OUTIFO);
}捕获(SQLE异常){
e、 printStackTrace();
}捕获(例外e){
e、 printStackTrace();
}最后{
试一试{
如果(rs!=null){
rs.close();
如果(cs!=null){
cs.close();
}
如果(con!=null){
con.close();
}
}
}捕获(SQLE异常){
系统输出打印项次(“例外2”);
e、 printStackTrace();
}
}
返回JSON.toJSONString(响应);
}

尝试以下更改

更改将过程调用为的语法

cs = con.prepareCall("BEGIN RK_JSCX(?, ?); END;");
我相信你的先出参数是VARCHAR2,对吗?所以

cs.registerOutParameter(1, Types.VARCHAR);
然后 使用以下命令强制转换CallableStatement

rs = ((OracleCallableStatement)cs).getCursor(2);
更新1

我已更改您的程序以演示工作版本

程序

CREATE OR REPLACE PROCEDURE rk_jscx (outtable   OUT sys_refcursor,
                                                 outinfo    OUT VARCHAR2
                                                )
AS
BEGIN
    OPEN outtable FOR
        SELECT  SYSDATE
          FROM  DUAL;

    outinfo := 1;
EXCEPTION
    WHEN NO_DATA_FOUND
    THEN
        outinfo := 2;
        ROLLBACK;
END rk_jscx;
Java代码

CallableStatement stmt = conn.prepareCall("BEGIN rk_jscx(?, ?); END;");
 stmt.registerOutParameter(1, OracleTypes.CURSOR); 
 stmt.registerOutParameter(2, Types.VARCHAR);
 stmt.execute();
      ResultSet rs = ((OracleCallableStatement)stmt).getCursor(1);
      while (rs.next()) {
        System.out.println(rs.getDate("sysdate")); 
      }
上述打印内容
2012-10-23


同时检查jdbc驱动程序

尝试以下更改

更改将过程调用为的语法

cs = con.prepareCall("BEGIN RK_JSCX(?, ?); END;");
我相信你的先出参数是VARCHAR2,对吗?所以

cs.registerOutParameter(1, Types.VARCHAR);
然后 使用以下命令强制转换CallableStatement

rs = ((OracleCallableStatement)cs).getCursor(2);
更新1

我已更改您的程序以演示工作版本

程序

CREATE OR REPLACE PROCEDURE rk_jscx (outtable   OUT sys_refcursor,
                                                 outinfo    OUT VARCHAR2
                                                )
AS
BEGIN
    OPEN outtable FOR
        SELECT  SYSDATE
          FROM  DUAL;

    outinfo := 1;
EXCEPTION
    WHEN NO_DATA_FOUND
    THEN
        outinfo := 2;
        ROLLBACK;
END rk_jscx;
Java代码

CallableStatement stmt = conn.prepareCall("BEGIN rk_jscx(?, ?); END;");
 stmt.registerOutParameter(1, OracleTypes.CURSOR); 
 stmt.registerOutParameter(2, Types.VARCHAR);
 stmt.execute();
      ResultSet rs = ((OracleCallableStatement)stmt).getCursor(1);
      while (rs.next()) {
        System.out.println(rs.getDate("sysdate")); 
      }
上述打印内容
2012-10-23

同时检查您的jdbc驱动程序

方法如下:

  • SQL查询:调用RK_JSCX(?,)

  • 参数值:OUT,OUT

  • 参数类型:OUT-10,OUT-VARCHAR

    -10是OracleTypes.CURSOR的int值

  • 变量名:游标、outInfo

     Names are what you want
    
JMeter允许使用比java.sql.types常量更多的类型,在本例中,您使用的不是常量名称,而是常量的整数值

文档已澄清(在下一个JMeter版本中),请参阅:

    • 这是如何做到的:

      • SQL查询:调用RK_JSCX(?,)

      • 参数值:OUT,OUT

      • 参数类型:OUT-10,OUT-VARCHAR

        -10是OracleTypes.CURSOR的int值

      • 变量名:游标、outInfo

         Names are what you want
        
      JMeter允许使用比java.sql.types常量更多的类型,在本例中,您使用的不是常量名称,而是常量的整数值

      文档已澄清(在下一个JMeter版本中),请参阅:


      您可以将代码发布到从java调用oracle存储过程的位置吗?所以您在这里遇到异常
      cs=con.prepareCall(sql);registerOutParameter(1,oracle.jdbc.OracleTypes.CURSOR);registerOutParameter(2,Types.VARCHAR)并且您的过程收到一个参数,对吗?当您从sqlplus或后端执行此操作时,返回什么<代码>声明OUTIFO varchar2(20);输出表系统参考光标;开始{调用RK_JSCX(?,)};结束运行java应用程序时一切正常。我的过程接收两个参数。一个是游标,另一个是varchar。我还没有在PL/SQL中执行此代码。您可以将代码发布到从java调用oracle存储过程的位置吗?所以您在这里遇到异常
      cs=con.prepareCall(SQL);registerOutParameter(1,oracle.jdbc.OracleTypes.CURSOR);registerOutParameter(2,Types.VARCHAR)并且您的过程收到一个参数,对吗?当您从sqlplus或后端执行此操作时,返回什么<代码>声明OUTIFO varchar2(20);输出表系统参考光标;开始{调用RK_JSCX(?,)};结束运行java应用程序时一切正常。我的过程接收两个参数。一个是游标,另一个是varchar。我还没有在PL/SQL中执行此代码。存在ClassCastException。因为con.prepareCall()返回CallableStatement,并且无法将其强制转换为oracle.jdbc.OracleCallableStatement您从哪里获得ClassCastException?在这一行
      rs=((Oracl