0

I will start by giving you my table content

enter image description here

This is my stored procedure:

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

My Problem

when I call the stored procedure from JDBC like this

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();
            }
        }

it just print here I am once, just once, even If (like the picture said) I have more than 15 rows are ture.

you problem will ask me if I am sure about the getID() method, Yes I am sure and even when I replace it with explicit 10 , the result doesn't change.

Something might help

when I call that stored procedure from my Visual studio , I got 17 results like this:

enter image description here

Any help will be appreciated

Marco Dinatsoli
  • 10,322
  • 37
  • 139
  • 253
  • I guess it is related to your question http://stackoverflow.com/questions/16505812/resultset-nullpointerexception ; if you want to process as a resultset, don't use `OUTPUT` parameters. The `CallableStatement` part for output parameters seems to be designed for processing a single result. – Mark Rotteveel May 13 '13 at 11:52
  • @MarkRotteveel that question didnt help me , I just made it accepted because I want t start a new thread – Marco Dinatsoli May 13 '13 at 12:47
  • pleaaaaaaaaaaaaaaase help – Marco Dinatsoli May 13 '13 at 13:02

2 Answers2

3

The callableStatement.execute() indicates if a result set is available.

getMoreResults() only indicates if there are is another ResultSet available, not if the "last" result set has more rows (which is - I think - pretty clear from the JavaDocs). getMoreResults() would return true if you had more than one select statement in your procedure.

If execute() indicates a ResultSet is available you need to obtain it using callableStatement.getResultSet() and then iterate over the rows returned by that.

Something like:

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");
}

But as you know it returns a result set you can also call getResultSet() right away without even bothering about the return value of the execute() call.

Matthias Wiehl
  • 1,799
  • 16
  • 22
  • you used my exact code, nothing new you add, i still can't find a solution , would you help me please – Marco Dinatsoli May 14 '13 at 06:25
  • @MarcoDinatsoli: no I did not use "your code". Please read my explanation on what the return value of the `execute()` call means. Plus you do not have a `getResult()` anywhere in your code. `getResult()` is something **completely** different than `getMoreResult()` which you are using. Please read the JavaDocs for those methods carefully. That difference is the part that will make it work. –  May 14 '13 at 06:41
1

You need to remove the OUTPUT variables from your stored procedure and no longer register them in your code. You then need to use executeQuery() to get the resultset and iterate over the resultset to get rows.

Assuming a table structure of:

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]

Table content:

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');

A stored procedure as:

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

And query code as:

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();
    }
}

On my computer this produces the output:

ID   = 513
1 2 3 Description xyz
2 2 3 Description xyz
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • I got this exception when debugging your code: `Parameter ID was not defined for stored procedure getFoodsForOrder2.` – Marco Dinatsoli May 14 '13 at 06:31
  • @MarcoDinatsoli I will test it further tonight and let you know – Mark Rotteveel May 14 '13 at 07:17
  • @MarcoDinatsoli I tested it and my original code worked except for minor modifications to fix obvious syntax errors (like forgetting `()` after `next`) and removing some reference to parts of your code I didn't have. I have now updated my answer with the table, content, stored procedure and code I executed on my machine against SQL Server 20102 using the SQL Server JDBC version 4.0 driver. I also used the Java 7 try-with-resources in the updated code – Mark Rotteveel May 14 '13 at 18:38