2011-06-02 28 views
52

Estoy intentando llamar a un procedimiento almacenado desde mi aplicación de Windows C#. El procedimiento almacenado se ejecuta en una instancia local de SQL Server 2008. Puedo llamar al procedimiento almacenado pero no puedo recuperar el valor del procedimiento almacenado. Se supone que este procedimiento almacenado devuelve el siguiente número de la secuencia. He hecho investigaciones en línea y todos los sitios que he visto han señalado que esta solución funciona.Llamar al procedimiento almacenado con el valor de retorno

código de procedimiento almacenado:

ALTER procedure [dbo].[usp_GetNewSeqVal] 
     @SeqName nvarchar(255) 
as 
begin 
     declare @NewSeqVal int 
     set NOCOUNT ON 
     update AllSequences 
     set @NewSeqVal = CurrVal = CurrVal+Incr 
     where SeqName = @SeqName 

     if @@rowcount = 0 begin 
print 'Sequence does not exist' 
      return 
     end 

     return @NewSeqVal 
end 

Código llamar al procedimiento almacenado:

SqlConnection conn = new SqlConnection(getConnectionString()); 
conn.Open(); 

SqlCommand cmd = new SqlCommand(parameterStatement.getQuery(), conn); 
cmd.CommandType = CommandType.StoredProcedure; 

SqlParameter param = new SqlParameter(); 

param = cmd.Parameters.Add("@SeqName", SqlDbType.NVarChar); 
param.Direction = ParameterDirection.Input; 
param.Value = "SeqName"; 

SqlDataReader reader = cmd.ExecuteReader(); 

También he intentado usar un DataSet para recuperar el valor de retorno con el mismo resultado. ¿Qué me falta para obtener el valor de retorno de mi procedimiento almacenado? Si necesita más información, hágamelo saber.

Respuesta

99

es necesario agregar parámetro de respuesta al comando:

using (SqlConnection conn = new SqlConnection(getConnectionString())) 
using (SqlCommand cmd = conn.CreateCommand()) 
{ 
    cmd.CommandText = parameterStatement.getQuery(); 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Parameters.AddWithValue("SeqName", "SeqNameValue"); 

    var returnParameter = cmd.Parameters.Add("@ReturnVal", SqlDbType.Int); 
    returnParameter.Direction = ParameterDirection.ReturnValue; 

    conn.Open(); 
    cmd.ExecuteNonQuery(); 
    var result = returnParameter.Value; 
} 
+3

¿Tiene que agregar '@ ReturnVal' al Procedimiento almacenado también? – muttley91

+3

No, no tiene que agregar al sp (la declaración de retorno activa el llenado del parámetro marcado con ReturnValue) – ufosnowcat

+0

thanx Necesito este – varsha

3

ExecuteScalar() funcionará, pero un parámetro de salida sería una solución superior.

+3

ExecuteScalar() no funciona, a menos que "seleccione" el valor de retorno. – Soori

0

O si está usando EnterpriseLibrary en lugar de ADO.NET estándar ...

Database db = DatabaseFactory.CreateDatabase(); 
using (DbCommand cmd = db.GetStoredProcCommand("usp_GetNewSeqVal")) 
{ 
    db.AddInParameter(cmd, "SeqName", DbType.String, "SeqNameValue"); 
    db.AddParameter(cmd, "RetVal", DbType.Int32, ParameterDirection.ReturnValue, null, DataRowVersion.Default, null); 

    db.ExecuteNonQuery(cmd); 

    var result = (int)cmd.Parameters["RetVal"].Value; 
} 
4

Sé que esto es viejo, pero me encontré con ella en Google.

Si tiene un valor de retorno en su procedimiento almacenado, diga "Volver 1" - sin utilizar los parámetros de salida.

Puede hacer lo siguiente: "@RETURN_VALUE" se agrega silenciosamente a cada objeto de comando. NO NECESITA AÑADIR EXPLÍCITAMENTE

cmd.ExecuteNonQuery(); 
    rtn = (int)cmd.Parameters["@RETURN_VALUE"].Value; 
+2

Hola Gary. ¿Tiene una cita? – Michael

+1

No creo que la instancia de cmd tenga un parámetro denominado en RETURN_VALUE en SqlParameterCollection a menos que se agregue explícitamente. Por lo tanto, si está considerando tomar el enfoque anterior de Gary, asegúrese de haber agregado cmd.Parameters.Add (nuevo SqlParameter ("@ RETURN_VALUE", SqlDbType.Int)); cmd.Parameters ["@ RETURN_VALUE"]. Dirección = ParameterDirection.ReturnValue; Sin embargo, creo que NO es necesario que agregue @RETURN_VALUE a la definición del procedimiento almacenado. Tal vez eso es lo que Gary quiso decir. – joey

-6

Veo que el otro está cerrado. Así que, básicamente, aquí está el rudo de mi código. Creo que te falta el comentario de cmd de cadena. Por ejemplo, si el procedimiento de mi tienda es llamar: DBO.Test. Necesitaría escribir cmd = "DBO.test". A continuación, realice tipo de comando igual al procedimiento de almacenamiento, y bla, bla, bla

Connection.open(); 
String cmd="DBO.test"; //the command 
Sqlcommand mycommand; 
+0

Estoy a punto de dormir, por lo tanto, ahora no puedo obtener el código completo. Pero créanme, hay una manera más fácil que las otras personas que comentaron. – Rain

2

La versión de EnterpriseLibrary en mi máquina tenía otros parámetros. Este estaba trabajando:

 SqlParameter retval = new SqlParameter("@ReturnValue", System.Data.SqlDbType.Int); 
     retval.Direction = System.Data.ParameterDirection.ReturnValue; 
     cmd.Parameters.Add(retval); 
     db.ExecuteNonQuery(cmd); 
     object o = cmd.Parameters["@ReturnValue"].Value; 
+0

Esta es la respuesta correcta - para mí :-) Gracias. –

0

He tenido un problema similar con la llamada SP devolver un error que un parámetro esperado no se incluyó. Mi código era el siguiente.
procedimiento almacenado:

@Result int SALIDA

y C#:

  SqlParameter result = cmd.Parameters.Add(new SqlParameter("@Result", DbType.Int32)); 
      result.Direction = ParameterDirection.ReturnValue; 

En la resolución de problemas, me di cuenta de que el procedimiento almacenado en realidad estaba buscando una dirección de "InputOutput", por lo que el siguiente cambio solucionó el problema.

  r 

Result.Direction = ParameterDirection.InputOutput;

Cuestiones relacionadas