style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

Ayuda con ResultSet en Conexion Java SQL 2008 con sqljdbc y DBPool

Hola tengo un problema con la obtención del ResulSet de una base de Datos SQL 2008 únicamente, esta misma programación funciona sin problemas para SQL 2005 con cualquier Query o Store Procedure. Al cambiar a SQL 2008, si quiero obtener el ResultSet de un Query simple como "SELECT * FROM Tabla", no tiene problemas pero si quiero obtener la información que regresa un Store Procedure como el que cito abajo, que realiza algunos Updates y cambios en Tablas antes de regresar información, con este código me envía el error: "La instrucción no devolvió un conjunto de Resultados". En base a esto mi conclusión es que el problema no esta en la conexión, y me parece que el error puede deberse en alguna configuración para obtener el ResulSet, solo que por mas que he buscado no encuentro la respuesta
El Store Procedure :

CREATE PROC StoreProcedure
AS
BEGIN
    DECLARE @TablaTemporal TABLE (Clave VARCHAR(50))
    INSERT
    SELECT TOP 100 Clave FROM Tabla
        UPDATE @TablaTemporal SET Clave='Clave: '+Clave
        SELECT * FROM @TablaTemporal
END

Las clase con la conexión tiene lo siguiente:

    public synchronized static void Conexion(){
       
        if (isConnected == false){
            try {
                Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); //JDBC 2005
            } catch (Exception e) {
                e.printStackTrace();
            }
            pool =  new ConnectionPool("local",
                    100,
                    1200,
                    10000,  // milliseconds
                    "jdbc:sqlserver://servidorSQL2008:1433;SelectMethod=cursor;DatabaseName=DB_NAME",
                    "USUARIO",
                    "PASSWORD");
            pool.init(100);
            isConnected = true;
        }
    }
    public static ResultSet rsSQL(Conexion con, final String SQL) {
        Statement stmt = null;
        Statement stmtLog = null;
        ResultSet rsObt = null;
        try{
            if (con != null) {
                stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
                stmtLog = con.createStatement();
                try {
                    stmt.execute("set dateformat mdy");
                    rsObt = stmt.executeQuery(SQL);
                    System.out.println(SQL);
                } catch (Exception e) { e.printStackTrace();   }
            }
        } catch (SQLException sqle) {
            try {
                if (con!=null){  con.close();          }
            }catch(Exception ee){     ee.printStackTrace();          }
            sqle.printStackTrace();
        }        
        return rsObt;
    }

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de Eduardo Vargas

Intenta cambiar el driver y/o el Execute(...

Hola danuryx,

Intenta cambiar el driver y/o el método que estás usando para ejecutar el stored procedure.
Parece que con el driver que tienes ya no se puede trabajar de esa forma con los métodos execute...
El método executeQuery(...) está diseñado preferentemente para instrucciones SELECT y para devolver sólo un conjunto de resultados
El método execute(...) está diseñado preferentemente para instrucciones que devuelven contadores de actualización, varios conjuntos de resultados, o una combinación de estos resultados.
.

Habría que analizar qué te está devolviendo la ejecución del Stored Procedure. Si estás haciendo updates o inserts, posiblemente estás obteniendo primero un contador de actualización y por eso obtienes esa excepción.
.

Intenta utilizar el método execute(SQL) y no asignes directamente el resultado al ResultSet, asígnaselo a una variable boolean.
Si obtienes un "true" quiere decir que sí tienes un conjunto de resultados y obtienes el ResultSet ejecutando stmt.getResultSet()
.

Si obtienes un "false" entonces obtén el contador de actualización con stmt.getUpdateCount(), si el resultado es "-1" entonces no hay más resultados, de lo contrario, el número que obtengas será el resultado de la actualización.
.

El código sería más o menos así:
.

int count = 0;
boolean hasResultSet = stmt.execute(SQL);
while(count >= 0) {
if(hasResultSet) {
ResultSet rs = stmt.getResultSet();
// procesa el resultset
rs.close();
}
else {
count = stmt.getUpdateCount();
}
if(count >= 0) {
// procesa de acuerdo al contador de actualización
}

hasResultSet = stmt.getMoreResults();
}
}

Te paso una dirección web en donde hay una explicación más amplia acerca de la forma más adecuada de llamar a un stored procedure y cómo obtener los contadores y/o conjuntos de resultados:
.

http://social.msdn.microsoft.com/Forums/sqlserver/en-US/0de94153-1db4-48...
.

Gracias! :=)

Imagen de danuryx

Es Correcto

En efecto ese fue el problema que tenia, estaba obteniendo el contador de actualización y no el ResulSet, en mi caso como es una clase utilizada para cualquier tipo de Query ,desde simples select y Store procedure hasta Stores Procedures con Triggers, updates y demás sentencias, por lo que necesito utilizar execute(SQL) .

También encontré la forma de evitar el contador de actualización, lo cual no necesito desde el Programa, por lo que dentro del mismo statement antes de ejecutar el Query principal ejecuto la sentencia execute("SET NOCOUNT ON");, la cual evita dicho contador.

Muchas gracias por la ayuda Eduardo Vargas!!!

Correct!!!

Ey, this solution really works my friends, I really thank you Eduardo Vargas and Danuryx (for the SET NOCOUNT), I lost some hours with this problem, I use to do my querys in the same way than PHP or ADO, specially because I always try to unify my database access code.

Regards

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">