如何在java/jsp中执行MS SQL Server存储过程,返回表数据?

use*_*236 26 sql sql-server jsp stored-procedures jdbc

我无法从Java/jsp执行MS SQL Server存储过程.我希望返回一组表数据; 存储过程的最后一行是表中的常规select语句.

(从这一点来说,执行存储过程很简单PHP.)

我看了看这些网站的帮助:
www.2netave.com
www.stackoverflow.com

我没有意识到只有存储过程的功能,正如我使用的createStatement()那样.

现在,请理解存储过程在SQL Server Management Studio中完美执行,我在使用jsp/java执行即席查询时没有遇到任何问题createStatement().

我创建了一个不带参数的简单存储过程,只是为了缩小问题范围:

CREATE PROCEDURE sp_test AS
BEGIN
PRINT 'HELLO WORLD'
END
Run Code Online (Sandbox Code Playgroud)

这是我的jsp页面中的代码:

Class.forName("net.sourceforge.jtds.jdbc.Driver");
java.sql.Connection conn = java.sql.DriverManager.getConnection("jdbc:jtds:sqlserver://MySQLServer:1433/test", "user", "pass");
java.sql.CallableStatement cs = conn.prepareCall("{call sp_test}"); 
java.sql.ResultSet ResultSet = cs.execute();
Run Code Online (Sandbox Code Playgroud)

浏览器告诉我无法显示页面,因为发生了内部服务器错误.我知道这意味着上面的代码存在问题.

我试过这个:

java.sql.ResultSet ResultSet = cs.executeQuery();
Run Code Online (Sandbox Code Playgroud)

还有这个:

java.sql.CallableStatement cs = conn.prepareCall("{execute sp_test}");
Run Code Online (Sandbox Code Playgroud)

还有这个:

java.sql.CallableStatement cs = conn.prepareCall("{exec sp_test}");
Run Code Online (Sandbox Code Playgroud)

没有任何效果.一旦我可以使这个工作,那么我可以运行一个实际的存储过程,从select语句返回表数据.但我甚至无法使这个虚拟存储过程工作.

我在这做错了什么?

谢谢.

更新:

检查了服务器日志(IIS)和我的HTTP代理,fiddler,它没有报告任何内容.但是,IIS使用tomcat作为jsp页面的servlet引擎.并且tomcat日志文件报告如下:

An error occurred at line: 20 in the jsp file: /test.jsp
Type mismatch: cannot convert from boolean to ResultSet
17: 
18:     java.sql.CallableStatement cs = conn.prepareCall("{call sp_test}");
19:     
20:     java.sql.ResultSet ResultSet = cs.execute();
21: 
22: //  java.sql.ResultSet ResultSet = state.executeQuery(SQL); 
23: 
Run Code Online (Sandbox Code Playgroud)

我尝试将上面改为:

cs.execute();
Run Code Online (Sandbox Code Playgroud)

并报告日志文件:

- Servlet.service() for servlet jsp threw exception
java.sql.SQLException: The EXECUTE permission was denied on the object 'sp_test', database 'test', schema 'dbo'.
Run Code Online (Sandbox Code Playgroud)

所以,我已经想到了我必须对GRANT EXECUTE用户.另一个问题是从存储过程返回表数据.

如果我有这样的程序:

CREATE PROCEDURE sp_test2 AS
BEGIN
SELECT * FROM TABLE
END
Run Code Online (Sandbox Code Playgroud)

如何在jsp中操作表数据?将ResultSet工作或者是只针对即席查询,而不是存储过程,其中一个会用createStatement()执行查询?

谢谢.

UPDATE2:

解:

为了操纵表数据,我不得不使用这个:

java.sql.ResultSet RS = cs.executeQuery();
Run Code Online (Sandbox Code Playgroud)

它失败了execute(),命名ResultSet对象"ResultSet" 失败了.它过去从未对此抱怨过createStatement().但由于某种原因,使用存储过程,它不喜欢这种命名约定.

谢谢.

Bri*_*hes 35

我们的服务器像这样从Java调用存储过程 - 适用于SQL Server 2000和2008:

String SPsql = "EXEC <sp_name> ?,?";   // for stored proc taking 2 parameters
Connection con = SmartPoolFactory.getConnection();   // java.sql.Connection
PreparedStatement ps = con.prepareStatement(SPsql);
ps.setEscapeProcessing(true);
ps.setQueryTimeout(<timeout value>);
ps.setString(1, <param1>);
ps.setString(2, <param2>);
ResultSet rs = ps.executeQuery();
Run Code Online (Sandbox Code Playgroud)

  • @Brian Hughes:你从哪里得到SmartPoolFactory? (3认同)

Axe*_*rio 5

感谢Brian的代码.我试图连接到SQL服务器{call spname(?,?)}并且我遇到了错误,但是当我将代码更改为exec sp...它时,效果非常好.

我发布我的代码希望这可以帮助其他人解决我的问题:

ResultSet rs = null;
PreparedStatement cs=null;
Connection conn=getJNDIConnection();

try {
    cs=conn.prepareStatement("exec sp_name ?,?,?,?,?,?,?");
    cs.setEscapeProcessing(true);
    cs.setQueryTimeout(90);

    cs.setString(1, "valueA");

    cs.setString(2, "valueB");

    cs.setString(3, "0418");

    //commented, because no need to register parameters out!, I got results from the resultset. 
    //cs.registerOutParameter(1, Types.VARCHAR);
    //cs.registerOutParameter(2, Types.VARCHAR);

    rs = cs.executeQuery();
    ArrayList<ObjectX> listaObjectX = new ArrayList<ObjectX>();
    while (rs.next()) {

        ObjectX to = new ObjectX();
        to.setFecha(rs.getString(1));
        to.setRefId(rs.getString(2));
        to.setRefNombre(rs.getString(3));
        to.setUrl(rs.getString(4));

        listaObjectX.add(to);

    }
    return listaObjectX;
     } catch (SQLException se) {
        System.out.println("Error al ejecutar SQL"+ se.getMessage());
        se.printStackTrace();
        throw new IllegalArgumentException("Error al ejecutar SQL: " + se.getMessage());

    } finally {

        try {

            rs.close();
            cs.close();
          con.close();

        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }
Run Code Online (Sandbox Code Playgroud)