Wywołanie procedury składowanej z wartością zwracaną


82

Próbuję wywołać procedurę składowaną z mojej aplikacji C # systemu Windows. Procedura składowana działa na lokalnym wystąpieniu programu SQL Server 2008. Mogę wywołać procedurę składowaną, ale nie mogę odzyskać wartości z procedury składowanej. Ta procedura składowana ma zwrócić następną liczbę w sekwencji. Zrobiłem badania online i wszystkie witryny, które widziałem, wskazywały, że to rozwiązanie działa.

Kod procedury składowanej:

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

Kod wywołujący procedurę składowaną:

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

Próbowałem również użyć DataSetdo pobrania wartości zwracanej z tym samym wynikiem. Czego mi brakuje, aby uzyskać wartość zwracaną z mojej procedury składowanej? Jeśli potrzebujesz więcej informacji, daj mi znać.

Odpowiedzi:


165

Musisz dodać parametr powrotu do polecenia:

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
Czy musisz również dodać @ReturnValdo procedury składowanej?
muttley91

4
Nie, nie musisz dodawać do sp (instrukcja return wyzwala wypełnienie parametru oznaczonego wartością ReturnValue)
ufosnowcat

10
Tak przy okazji, nie ma znaczenia, jak nazwiesz parametr wartości zwracanej wartości.
Clay

wielkie dzięki, szukałem sposobu na prawidłowe uzyskanie wartości zwrotu, to naprawdę zadziałało. niesamowite!
Oswaldo Zapata

4
Wartość zwracana przez procedurę składowaną powinna być używana tylko do wskazania sukcesu (zero) lub niepowodzenia / ostrzeżenia (niezerowa), a nie zwracania danych. W tym celu użyj OUTPUTparametru lub zestawu wyników.
Dan Guzman,

5

Wiem, że to jest stare, ale natknąłem się na to z Google.

Jeśli masz wartość zwracaną w procedurze składowanej, powiedz „Return 1” - nie używając parametrów wyjściowych.

Możesz wykonać następujące czynności - „@RETURN_VALUE” jest dyskretnie dodawane do każdego obiektu polecenia. NIE MUSISZ WYRAŹNIE DODAĆ

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

2
Cześć Gary. Czy masz cytat?
Michael

5
Nie wierzę, że wystąpienie cmd będzie miało parametr nazwany w RETURN_VALUE w SqlParameterCollection, chyba że zostanie dodany jawnie. Dlatego jeśli rozważasz zastosowanie powyższego podejścia przez Gary'ego, upewnij się, że dodano cmd.Parameters.Add (new SqlParameter ("@ RETURN_VALUE", SqlDbType.Int)); cmd.Parameters ["@ RETURN_VALUE"]. Direction = ParameterDirection.ReturnValue; Uważam jednak, że NIE trzeba dodawać @RETURN_VALUE do definicji procedury składowanej. Może to miał na myśli Gary.
jbooker

4

Wersja EnterpriseLibrary na moim komputerze miała inne parametry. To działało:

        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

ExecuteScalar(); będzie działać, ale parametr wyjściowy byłby lepszym rozwiązaniem.


7
Funkcja ExecuteScalar () nie działa, chyba że „wybierzesz” zwracaną wartość.
Soori


2

Miałem podobny problem z wywołaniem SP zwracającym błąd, że oczekiwany parametr nie został uwzględniony. Mój kod był następujący.
Procedura składowana:

@Result int OUTPUT

I C#:

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

Podczas rozwiązywania problemów zdałem sobie sprawę, że procedura składowana RZECZYWISTE szukała kierunku „InputOutput”, więc następująca zmiana rozwiązała problem.

            r

Result.Direction = ParameterDirection.InputOutput;


1
„Parametry wyjściowe” to nie to samo, co wartości zwracane procedury składowanej.
Dai

0

Lub jeśli używasz EnterpriseLibrary zamiast standardowego ADO.NET ...

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

To jest bardzo krótki przykład zwracania pojedynczej wartości z procedury:

SQL:

CREATE PROCEDURE [dbo].[MakeDouble] @InpVal int AS BEGIN 
SELECT @InpVal * 2; RETURN 0; 
END

Kod C #:

int inpVal = 11;
string retVal = "?";
using (var sqlCon = new SqlConnection(
    "Data Source = . ; Initial Catalog = SampleDb; Integrated Security = True;"))
{
    sqlCon.Open();
    retVal = new SqlCommand("Exec dbo.MakeDouble " + inpVal + ";", 
        sqlCon).ExecuteScalar().ToString();
    sqlCon.Close();
}
Debug.Print(inpVal + " * 2 = " + retVal); 
//> 11 * 2 = 22

-8

Widzę, że druga jest zamknięta. Więc w zasadzie tutaj jest przybliżony mój kod. Myślę, że brakuje ci komentarza cmd. Na przykład, jeśli moja procedura magazynu to call: DBO.Test. Musiałbym napisać cmd = "DBO.test". Następnie wpisz polecenie równe procedurze przechowywania i bla bla bla

Connection.open();
String cmd="DBO.test"; //the command
Sqlcommand mycommand;
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.