【问题标题】:stored procedure returns just one row of multiple rows存储过程只返回多行中的一行
【发布时间】:2013-05-07 09:48:05
【问题描述】:

我会先给你我的表格内容

这是我的存储过程:

ALTER PROCEDURE dbo.getFoodsForOrder
    (
    @orderID INT,
    @ID INT OUTPUT,
    @food_restaurantID INT OUTPUT,
    @count INT OUTPUT,
    @description VARCHAR(200) OUTPUT
    )
AS
SET NOCOUNT ON
BEGIN
    SELECT [ID],
    [food_restaurantID],
    [count],
    [description]
    FROM Order_Food
    WHERE orderID = @orderID
END

我的问题

当我像这样从 JDBC 调用存储过程时

Connection con = Database.getConnection();
        CallableStatement callableStatement = null;
        try {
            callableStatement = con
                    .prepareCall("{call getFoodsForOrder(?,?,?,?,?)}");
            callableStatement.setInt(1, getID());
            callableStatement.registerOutParameter(2, java.sql.Types.INTEGER);
            callableStatement.registerOutParameter(3, java.sql.Types.INTEGER);
            callableStatement.registerOutParameter(4, java.sql.Types.INTEGER);
            callableStatement.registerOutParameter(5, java.sql.Types.VARCHAR);
            System.out.println("ID   = " + getID());
            boolean haveResult = callableStatement.execute();
            while (haveResult) {
                System.out.println("here I am");
                haveResult = callableStatement.getMoreResults();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if (callableStatement != null)
                    callableStatement.close();
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

它只打印一次here I am,一次,即使(如图片所示)我有超过 15 行是真的。

你的问题会问我是否确定 getID() 方法,是的,我确定,即使我用明确的 10 替换它,结果也不会改变。

有些东西可能会有所帮助

当我从我的 Visual Studio 调用该存储过程时,我得到了 17 个这样的结果:

任何帮助将不胜感激

【问题讨论】:

  • 我猜这与你的问题stackoverflow.com/questions/16505812/…有关;如果您想作为结果集进行处理,请不要使用OUTPUT 参数。输出参数的CallableStatement 部分似乎是为处理单个结果而设计的。
  • @MarkRotteveel 这个问题对我没有帮助,我只是接受它,因为我不想开始一个新线程
  • 请帮帮忙

标签: java sql-server stored-procedures jdbc


【解决方案1】:

callableStatement.execute() 表示如果有一个结果集可用。

getMoreResults() 仅指示是否有 another ResultSet 可用,而不是“最后一个”结果集是否有更多行(这是 - 我认为 - 很清楚来自 JavaDocs)。如果您的过程中有多个 select 语句,getMoreResults() 将返回 true

如果execute() 表示一个ResultSet 可用,您需要使用callableStatement.getResultSet() 获取它,然后遍历它返回的行。

类似:

boolean haveResult = callableStatement.execute();
if (haveResult) {
   ResultSet rs = callableStatement.getResultSet();
   while (rs.next()) {
      System.out.println(rs.getInt(1));
   }
} else {
  System.out.println("Nothing returned");
}

但您知道它会返回一个结果集,您也可以立即调用getResultSet(),甚至无需担心execute() 调用的返回值。

【讨论】:

  • 您使用了我的确切代码,没有添加任何新内容,我仍然找不到解决方案,请您帮帮我
  • @MarcoDinatsoli:不,我没有使用“你的代码”。请阅读我对execute() 调用的返回值含义的解释。另外,您的代码中的任何地方都没有getResult()getResult() 与您正在使用的 getMoreResult() 完全不同。请仔细阅读这些方法的 JavaDocs。这种差异是让它发挥作用的部分。
【解决方案2】:

您需要从存储过程中删除OUTPUT 变量,并且不再在代码中注册它们。然后您需要使用executeQuery() 来获取结果集并遍历结果集以获取行。

假设表结构为:

CREATE TABLE [dbo].[Order_Food](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [OrderID] [int] NULL,
    [food_restaurantID] [int] NULL,
    [count] [int] NULL,
    [description] [nvarchar](255) NULL,
 CONSTRAINT [PK_Order_Food] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

表格内容:

INSERT INTO [dbo].[Order_Food] 
     ([OrderID], [food_restaurantID], [count], [description])
     VALUES (513, 2, 3, 'Description xyz'), (513, 2, 3, 'Description xyz'), 
        (132, 1, 2, 'Description abc');

存储过程为:

CREATE PROCEDURE dbo.getFoodsForOrder
    (
    @orderID INT
    )
AS
SET NOCOUNT ON
BEGIN
    SELECT [ID],
    [food_restaurantID],
    [count],
    [description]
    FROM Order_Food
    WHERE orderID = @orderID
END

查询代码为:

public static void main(String[] args) throws SQLException {
    try (
        Connection con = DriverManager.getConnection("jdbc:sqlserver://localhost\\SQLEXPRESS;databaseName=Scratchspace;integratedSecurity=true");
        CallableStatement callableStatement = 
            con.prepareCall("{call getFoodsForOrder(?)}");
    ){
        callableStatement.setInt(1, 513);
        System.out.println("ID   = " + 513);
        ResultSet rs = callableStatement.executeQuery();
        while (rs.next()) {
            System.out.printf("%d %d %d %s%n",
                    rs.getInt("ID"), rs.getInt("food_restaurantID"),
                    rs.getInt("count"), rs.getString("description"));
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

在我的电脑上,这会产生输出:

ID   = 513
1 2 3 Description xyz
2 2 3 Description xyz

【讨论】:

  • 我在调试你的代码时遇到了这个异常:Parameter ID was not defined for stored procedure getFoodsForOrder2.
  • @MarcoDinatsoli 我今晚会进一步测试并告诉你
  • @MarcoDinatsoli 我对它进行了测试,我的原始代码可以正常工作,只是为了修复明显的语法错误(比如在next 之后忘记了())并删除了对部分代码的一些引用我没有'没有。我现在使用 SQL Server JDBC 4.0 版驱动程序在我的机器上针对 SQL Server 20102 执行的表、内容、存储过程和代码更新了我的答案。我还在更新的代码中使用了 Java 7 try-with-resources
猜你喜欢
  • 2012-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-31
  • 1970-01-01
  • 2016-04-14
  • 2011-12-29
  • 1970-01-01
相关资源
最近更新 更多