Передача значения BIT в серверную хранимую процедуру sql - PullRequest
2 голосов
/ 25 марта 2020

У меня есть хранимая процедура:

CREATE PROCEDURE myproc(@a nvarchar(50), @b nvarchar(100), @c bit)
AS ...

   SELECT @retVal;

У меня есть следующий код aspx:

SqlCommand cmd = new SqlCommand("myproc", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@a", a);
cmd.Parameters.AddWithValue("@b", b);
cmd.Parameters.Add("@c", SqlDbType.Bit).Value = false;

SqlParameter returnValue = new SqlParameter("@retVal", SqlDbType.NVarChar, 9999999);
returnValue.Direction = ParameterDirection.Output;
cmd.Parameters.Add(returnValue);
conn.Open();
cmd.ExecuteNonQuery();
retVal = (string)cmd.Parameters["@retVal"].Value;   
conn.Close();

Это дает мне ошибку:

Procedure or function myproc has too many arguments specified.

Если Я удаляю строку:

cmd.Parameters.Add("@c", SqlDbType.Bit).Value = false;

Я получаю эту ошибку:

Procedure or function 'myproc' expects parameter '@c', which was not supplied

Я пробовал эти альтернативы для этой строки:

cmd.Parameters.AddWithValue("@c", 0);
cmd.Parameters.AddWithValue("@c", false);

Как пройти этот БИТ параметр?

Ответы [ 3 ]

2 голосов
/ 25 марта 2020

Ваша хранимая процедура не определяет выходной параметр. @c не ваша проблема, проблема @retVal.

Вам нужно что-то вроде этого:

CREATE PROCEDURE myproc(@a nvarchar(50), @b nvarchar(100), @c bit, @retVal NVARCHAR([LEN]) OUTPUT)
AS...

... где [LEN] - это то, что вам нужно, я сомневаюсь, что это 9,999,999, но вы можете сделать MAX, если хотите.

Затем сохраните [YOUR RESULT] в новом блестящем выходном параметре:

SELECT @retVal = [YOUR RESULT]

... в этот момент я считаю, ваш код C# будет работать правильно.

2 голосов
/ 25 марта 2020

Я представляю 3 способа получения данных из процедуры:

Вот sp, который возвращает значение

CREATE PROCEDURE x AS
BEGIN
  return 1
END

Вы должны получить это 1 в своем c# добавив параметр с направлением ReturnValue и типом int (это может быть только int), и прочитав параметр .Value после вас ExecuteNonQuery

Обычно мы используем returnvalue, чтобы указать состояние операция, а НЕ некоторые данные в таблице. Например, AddUser pro c, который возвращает 0 для успеха, 1 для сбоя, потому что пользователь существует, 2 для сбоя, потому что пароль слишком слаб и т. Д. c, мы не будем использовать returnvalue для возврата идентификатора пользователя только что добавленного пользователя


Вот sp, имеющий выходной параметр

CREATE PROCEDURE x
    @y INT OUTPUT
AS BEGIN
  SET @y = 1
END

Вы должны получить это 1 в c#, добавив параметр с именем @y и direction Output и прочитайте значение параметра после ExecuteNonQuery. Если вы также используете параметр для ввода, объявите направление как InputOutput


Вот sp, который возвращает набор результатов

CREATE PROCEDURE x
AS BEGIN
  SELECT 1 AS y
END

Вы должны получить это 1 выполнение ExecuteScalar или ExecuteReader

ExecuteScalar возвращает верхнюю левую ячейку набора результатов; хорошо для этого примера. Если вы планируете возвращать больше строк и столбцов, чем просто одно значение, используйте ExecuteReader


Похоже, вы что-то путаете; решить, как ваш sp будет возвращать свои значения, и соответствующим образом кодировать c#.

Вы можете смешивать и сопоставлять их и иметь spro c, который имеет выходной параметр, возвращаемое значение и выбирает набор результатов, но вы должно быть ясно, какие биты c# собирают какие данные, из каких битов spro c

1 голос
/ 25 марта 2020

Попробуйте изменить это:

    returnValue.Direction = ParameterDirection.Output;

на это:

    returnValue.Direction = ParameterDirection.ReturnValue;

ОК, если @retVal не является целым числом, то вы не можете использовать ParameterDirection.ReturnValue. Оставайтесь с SELECT @retVal, но измените cmd.ExecuteNonQuery() на var result = Convert.ToString(cmd.ExecuteScalar());, а также не определяйте параметр @retVal в C#.

...