Сохраненная процедура или функция ожидает параметра, который не поставляется
Я пытаюсь вставить данные в базу данных SQL Server, вызвав хранимую процедуру, но я получаю сообщение об ошибке
Процедура или функция "SHOWuser" ожидает параметра "@userID", который не был предоставлен.
Моя хранимая процедура называется SHOWuser
. Я проверил его полностью и никаких параметров не было.
Мой код:
public void SHOWuser(string userName, string password, string emailAddress, List<int> preferences)
{
SqlConnection dbcon = new SqlConnection(conn);
try
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = dbcon;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandText = "SHOWuser";
cmd.Parameters.AddWithValue("@userName", userName);
cmd.Parameters.AddWithValue("@password", password);
cmd.Parameters.AddWithValue("@emailAddress", emailAddress);
dbcon.Open();
int i = Convert.ToInt32(cmd.ExecuteScalar());
cmd.Parameters.Clear();
cmd.CommandText = "tbl_pref";
foreach (int preference in preferences)
{
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("@userID", Convert.ToInt32(i));
cmd.Parameters.AddWithValue("@preferenceID", Convert.ToInt32(preference));
cmd.ExecuteNonQuery();
}
}
catch (Exception)
{
throw;
}
finally
{
dbcon.Close();
}
а хранимая процедура:
ALTER PROCEDURE [dbo].[SHOWuser]
(
@userName varchar(50),
@password nvarchar(50),
@emailAddress nvarchar(50)
)
AS
BEGIN
INSERT INTO tbl_user(userName, password, emailAddress)
VALUES (@userName, @password, @emailAddress)
SELECT
tbl_user.userID, tbl_user.userName,
tbl_user.password, tbl_user.emailAddress,
STUFF((SELECT ',' + preferenceName
FROM tbl_pref_master
INNER JOIN tbl_preferences ON tbl_pref_master.preferenceID = tbl_preferences.preferenceID
WHERE tbl_preferences.userID = tbl_user.userID
FOR XML PATH ('')), 1, 1, ' ' ) AS Preferences
FROM
tbl_user
SELECT SCOPE_IDENTITY();
END
Это вторая хранимая процедура tbl_pref
, которая используется в той же функции:
ALTER PROCEDURE [dbo].[tbl_pref]
@userID int,
@preferenceID int
AS
BEGIN
INSERT INTO tbl_preferences(userID, preferenceID)
VALUES (@userID, @preferenceID)
END
Ответы
Ответ 1
Ваша хранимая процедура ожидает 5 параметров ввода
@userID int,
@userName varchar(50),
@password nvarchar(50),
@emailAddress nvarchar(50),
@preferenceName varchar(20)
Итак, вы должны добавить все 5 параметров к этому вызову SP:
cmd.CommandText = "SHOWuser";
cmd.Parameters.AddWithValue("@userID",userID);
cmd.Parameters.AddWithValue("@userName", userName);
cmd.Parameters.AddWithValue("@password", password);
cmd.Parameters.AddWithValue("@emailAddress", emailAddress);
cmd.Parameters.AddWithValue("@preferenceName", preferences);
dbcon.Open();
PS: Не понятно, для чего предназначены эти параметры. Вы не используете эти параметры в своем теле SP, чтобы ваш SP выглядел следующим образом:
ALTER PROCEDURE [dbo].[SHOWuser] AS BEGIN ..... END
Ответ 2
В моем случае я получил это исключение, даже если все значения параметров были правильно поставлены, но тип команды не был указан:
cmd.CommandType = System.Data.CommandType.StoredProcedure;
Это явно не так в вопросе выше, но описание исключения в этом случае не очень ясное, поэтому я решил указать это.
Ответ 3
Я столкнулся с этим вопросом вчера, но ни одно из решений здесь не работало точно, однако они указали мне в правильном направлении.
Наше приложение - это инструмент рабочего процесса, написанный на С#, и, в упрощенном виде, содержит несколько хранимых процедур в базе данных, а также таблицу метаданных о каждом параметре, используемом каждой хранимой процедурой (имя, порядок, тип данных, размер, и т.д.), что позволяет нам создавать столько новых хранимых процедур, сколько нам нужно, не меняя С#.
Анализ проблемы показал, что наш код устанавливал все правильные параметры в объекте SqlCommand
, однако, как только он был выполнен, он выдал ту же ошибку, что и OP.
Дальнейший анализ показал, что некоторые параметры имели значение null
. Поэтому я должен сделать вывод, что объекты SqlCommand
игнорируют любой объект SqlParameter
в их коллекции .Parameters
со значением null
.
Есть два решения этой проблемы, которые я нашел.
-
В наших хранимых процедурах укажите значение по умолчанию для каждого параметра, поэтому от @Parameter int
до @Parameter int = NULL
(или какого-либо другого значения по умолчанию, если требуется).
-
В нашем коде, который генерирует отдельные объекты SqlParameter
, назначая DBNull.Value
вместо null
, где предполагаемое значение представляет собой SQL null
делает трюк.
Исходный кодер перешел, и код был первоначально написан с учетом решения 1, и, взвесив преимущества обоих, я думаю, что я придерживаюсь решения 1. Намного проще указать значение по умолчанию для специфической хранимой процедуры при ее записи, а не всегда null
, как определено в коде.
Надеюсь, что это поможет кому-то.
Ответ 4
В моем случае он возвращал один выходной параметр и не возвращал какое-либо значение.
Поэтому он изменил его на
param.Direction = ParameterDirection.Output;
command.ExecuteScalar();
а затем он выбрасывал ошибку размера. поэтому пришлось также установить размер
SqlParameter param = new SqlParameter("@Name",SqlDbType.NVarChar);
param.Size = 10;
Ответ 5
В моем случае я получил ошибку на выходном параметре, даже если я правильно его установил на стороне С#, я понял, что забыл дать значение по умолчанию для вывода параметра в хранимой процедуре
ALTER PROCEDURE [dbo].[test]
(
@UserID int,
@ReturnValue int = 0 output --Previously I had @ReturnValue int output
)