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.