Виклик збереженої процедури із повернутим значенням


82

Я намагаюся викликати збережену процедуру з моєї програми C # windows. Зберігається процедура працює на локальному екземплярі SQL Server 2008. Я можу викликати збережену процедуру, але не можу отримати значення назад із збереженої процедури. Ця збережена процедура повинна повертати наступне число в послідовності. Я проводив дослідження в Інтернеті, і всі сайти, які я бачив, вказували на те, що це рішення працює.

Збережений код процедури:

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

Код, що викликає збережену процедуру:

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

Я також спробував використовувати a DataSetдля отримання поверненого значення з тим самим результатом. Що мені не вистачає, щоб отримати повернене значення з моєї збереженої процедури? Якщо потрібна додаткова інформація, будь ласка, повідомте мене.

Відповіді:


165

Вам потрібно додати параметр return до команди:

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
Вам також потрібно додати @ReturnValдо збереженої процедури?
muttley91

4
Ні, вам не потрібно додавати до sp (спрацьовує оператор return, що заповнює параметр, позначений функцією ReturnValue)
ufosnowcat

10
Неважливо, що ви називаєте параметром return val, до речі.
Клей

велике спасибі, я шукав спосіб правильно отримати повернену вартість, це справді спрацювало для мене. чудово!
Освальдо Сапата,

4
Повернене значення збереженої процедури слід використовувати лише для позначення успіху (нуль) або помилки / попередження (ненульове значення), а не повернення даних. Для цього використовуйте OUTPUTпараметр або набір результатів.
Ден Гусман,

5

Я знаю, що це старе, але я натрапив на це з Google.

Якщо у вашій збереженій процедурі є значення повернення, скажіть "Повернення 1" - не використовуючи вихідні параметри.

Ви можете зробити наступне - "@RETURN_VALUE" мовчки додається до кожного об'єкта команди. НЕ ПОТРІБНО ЯСНО ДОДАТИ

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

2
Привіт, Гері. У вас трапляється цитата?
Майкл

5
Я не вірю, що екземпляр cmd матиме параметр з іменем RETURN_VALUE у SqlParameterCollection, якщо він не доданий явно. Отже, якщо ви плануєте скористатися наведеним вище підходом Гері, то переконайтеся, що ви додали cmd.Parameters.Add (новий SqlParameter ("@ RETURN_VALUE", SqlDbType.Int)); cmd.Parameters ["@ RETURN_VALUE"]. Direction = ParameterDirection.ReturnValue; Однак я впевнений, що вам НЕ потрібно додавати @RETURN_VALUE до визначення збереженої процедури. Можливо, саме це мав на увазі Гері.
jbooker

4

Версія EnterpriseLibrary на моїй машині мала інші параметри. Це працювало:

        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(); буде працювати, але вихідний параметр буде найкращим рішенням.


7
ExecuteScalar () не працює, якщо ви не "вибрали" значення, що повертається.
Сурі


2

У мене була подібна проблема із викликом SP, що повертає помилку, оскільки очікуваний параметр не був включений. Мій код був таким.
Зберігається процедура:

@Result int OUTPUT

І C #:

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

Під час усунення несправностей я зрозумів, що збережена процедура НАСТІЙШО шукала напрямок "InputOutput", тому наступна зміна вирішила проблему.

            r

Result.Direction = ParameterDirection.InputOutput;


1
"Вихідні параметри" - це не те саме, що повертаються значення збереженої процедури, до речі.
Dai

0

Або якщо ви використовуєте EnterpriseLibrary, а не стандартну 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

Це дуже короткий зразок повернення одного значення з процедури:

SQL:

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

Код 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

Бачу, інший закритий. Отже, в основному ось приблизний код мого коду. Я думаю, вам не вистачає рядка cmd comment. Наприклад, якщо моєю процедурою магазину є виклик: DBO.Test. Мені потрібно було б написати cmd = "DBO.test". Потім виконайте тип команди, рівний процедурі зберігання, і бла-бла-бла

Connection.open();
String cmd="DBO.test"; //the command
Sqlcommand mycommand;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.