【问题标题】:How to call parameterized stored procedure in jdbc如何在jdbc中调用参数化存储过程
【发布时间】:2014-06-30 13:31:43
【问题描述】:

我需要从 sql server 调用 java jdbc 中的参数化存储过程。 存储过程在sql中是这样的

create proc patientreg
@id int
    as
begin
    select [patient_id],[Psurname], [pFirstname], [pMiddlename], [reg_date], [DOB], [Sex], [Phone_num], [Addr],[Email],[dbo].[fncomputeage](DOB) from [dbo].[Patient_registration] where [patient_id] = @id
end

请注意dbo.fncompute(DOB)是一个函数

在 JDBC 中调用它:

try{
    String str = "{call patientreg(?)}";
    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
    con = DriverManager.getConnection("jdbcdbc:GeneralHospital");
    cstmt = con.prepareCall(str);
    cstmt.setInt(1, Integer.parseInt(t.getText()));
    cstmt.execute();

    int pid = cstmt.getInt(1);
    String sname = cstmt.getString(2);
    String fname = cstmt.getString(3);
    String mname = cstmt.getString(4);
    String regdate = cstmt.getString(5);
    String dob = cstmt.getString(6);
    String sex = cstmt.getString(7);
    String phonenum = cstmt.getString(8);
    String address = cstmt.getString(9);
    String email = cstmt.getString(10);
    int age = cstmt.getInt(11);

    l1.setText(sname+""+ fname+""+mname);
    l3.setText(Integer.toString(pid));
    l4.setText(regdate);
    l5.setText(dob);
    l6.setText(Integer.toString(age));
    l7.setText(sex);
    l8.setText(phonenum);
    l9.setText(address);
    l10.setText(email);
    cstmt.close();
}
catch(Exception ex)
{
    System.out.println("Error occured");
    System.out.println("Error:"+ex);
}

这样做之后会抛出异常:

错误:java.sql.SQLException:参数 1 不是 OUTPUT 参数

【问题讨论】:

  • 注解:请注意,从 java 版本 8 起,JDBC-ODBC 桥已从 JDK 中删除,因此您需要寻找一些纯 java 替代驱动程序

标签: java sql-server stored-procedures jdbc


【解决方案1】:

您的代码存在一些问题。

首先,不要使用 jdbc odbc 驱动程序!它不稳定,可能无法正常工作。使用微软的own jdbc driver,或者更好的是使用jTDS,它是一个优秀的Sql Server开源jdbc驱动。

其次,CallableStatement 上的getIntgetString 等方法用于从存储过程中检索输出参数。你所拥有的是一个普通的结果集。

CallableStatement cstmt = con.prepareCall("{call patientreg(?)}");

// add input parameter
cstmt.setInt(1, someInteger);

// execute and get resultset.
ResultSet rs = cstmt.executeQuery();

// read resultset
while (rs.next()) {
    int pid = rs.getInt(1);
    String sname = rs.getString(2);
    String fname = rs.getString(3);
    // etc.
}

// remember to close statement and connection

【讨论】:

    【解决方案2】:

    试试这个

    ResultSet rs = null;
    PreparedStatement cs=null;
    Connection conn=getJNDIConnection();
    try {
    cs=conn.prepareStatement("exec sp_name ?,?");
    cs.setString(1, "val1");
    cs.setString(2, "val2");
    rs = cs.executeQuery();
    ArrayList<YourClass> listYourClass = new ArrayList<YourClass>();
    while (rs.next()) {
        YourClassret= new YourClass();
        ret.set1(rs.getString(1));
        ret.set2(rs.getString(2));
        ret.set3(rs.getString(3));
        listaObjectX.add(ret);
    
    }
    return listYourClass ;
     } catch (SQLException se) {
        System.out.println("Error "+ se.getMessage());
        se.printStackTrace();
    
    } finally {
    
        try {
    
            rs.close();
            cs.close();
          con.close();
    
        } catch (SQLException ex) {
            //do ex.print
        }
    }
    

    【讨论】:

    • 对不起,我从来没有调用过 SQL-server 存储过程,但这不应该用 CallableStatement 来完成吗?
    • 是的,在调用存储过程时绝对应该使用 CallableStatement。只要您不需要检索存储过程的返回值或任何输出参数,上述方法才有效。
    猜你喜欢
    • 2016-01-08
    • 2017-09-29
    • 1970-01-01
    • 2012-08-06
    • 2022-10-21
    • 2015-05-28
    • 2014-11-24
    • 2016-05-03
    • 1970-01-01
    相关资源
    最近更新 更多