web-dev-qa-db-fra.com

Appel de procédure stockée avec une valeur de retour

J'essaie d'appeler une procédure stockée à partir de mon application Windows C #. La procédure stockée s'exécute sur une instance locale de SQL Server 2008. Je peux appeler la procédure stockée, mais je ne parviens pas à récupérer la valeur à partir de la procédure stockée. Cette procédure stockée est supposée renvoyer le numéro suivant dans la séquence. J'ai effectué des recherches en ligne et tous les sites que j'ai vus ont indiqué que cette solution fonctionnait bien.

Code de procédure stockée:

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

Code appelant la procédure stockée:

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

J'ai également essayé d'utiliser un DataSet pour récupérer la valeur de retour avec le même résultat. Qu'est-ce qui me manque pour obtenir La valeur de retour de ma procédure stockée? Si plus d'informations sont nécessaires, s'il vous plaît faites le moi savoir.

63
Wesley

Vous devez ajouter un paramètre de retour à la commande:

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;
}
118
Alex Aza

ExecuteScalar () fonctionnera, mais un paramètre de sortie constituerait une solution supérieure.

4
Justin Dearing

Je sais que c'est vieux, mais je suis tombé dessus avec Google.

Si vous avez une valeur de retour dans votre procédure stockée, dites "Return 1" - n'utilisez pas de paramètres de sortie.

Vous pouvez procéder comme suit: "@RETURN_VALUE" est ajouté en silence à chaque objet de commande. AUCUN BESOIN D'AJOUTER EXPLICITEMENT

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

La version de EnterpriseLibrary sur ma machine avait d’autres paramètres . Cela fonctionnait:

        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;
3
RaSor

Vous pouvez essayer d'utiliser un paramètre de sortie. http://msdn.Microsoft.com/en-us/library/ms378108.aspx

2
Aravind

J'ai eu un problème similaire avec l'appel SP renvoyant une erreur indiquant qu'un paramètre attendu n'était pas inclus. Mon code était comme suit .
Procédure stockée: 

@Result int OUTPUT

Et C#:

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

Lors du dépannage, je me suis rendu compte que la procédure stockée recherchait ACTUELLEMENT une direction "InputOutput". Par conséquent, la modification suivante a résolu le problème.

            r

Result.Direction = ParameterDirection.InputOutput;

2
Paul

Ou si vous utilisez EnterpriseLibrary plutôt que ADO.NET standard ...

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;
}
0
Dunc