Мой SqlParameter неправильно передает значение NULL
-
06-09-2019 - |
Вопрос
У меня есть эта веб-форма C #, в которой есть поле выбора даты.Если для даты установлено значение nothing (по умолчанию) Я хочу, чтобы оно передавало NULL в базу данных.Это происходит внутри моего параметризованного запроса.
SqlParameter CMActionDate = new SqlParameter();
CMActionDate.ParameterName = "@ActionDate";
if (ActionDate.Equals(""))
{
CMActionDate.Value = System.Data.SqlTypes.SqlDateTime.Null;
}
else
{
CMActionDate.Value = ActionDate;
}
Когда я включаю отладку, я вижу, что дата действительно "", поэтому она переходит в инструкцию IF и присваивает actiondate.value значение {Null}, как я думаю, так и должно быть.
Однако.
Когда затем он переходит к выполнению не-запроса, я нажимаю на увеличительное стекло и вижу это:
UPDATE table SET [action_date] = '' WHERE [id] = 2488
То, что я хотел бы видеть, это:
UPDATE table SET [action_date] = 'Null' WHERE [id] = 2488
Поскольку action_date на самом деле никогда не присваивается значение NULL, то значение в поле datetime возвращается к "01/01/1900 12:00:00AM", и это само по себе является проблемой.
Я попытался установить CMActionDate.Значение в следующие значения безрезультатно (я получаю тот же результат, что и выше.):
- DBNull.Значение;
- "НУЛЕВОЙ";
- SqlDateTime.Значение Null;
- ноль;
Справка.
Редактировать
Может быть, я не совсем ясно выразился?Да, конечно, параметризованный запрос выглядит следующим образом:
"UPDATE CM_Codebase SET [action_date] = '" + @ActionDate + "' WHERE [id] = " + @CM_id + "";
Но когда я отлаживаю эту штуку в VS, я ставлю точку останова прямо перед ExecuteNonQuery();таким образом, я могу видеть SQL, который он пытается запустить.Именно там я вижу фактический SQL и вижу бит, где action_date=".
Помогает ли это?
Решение
Вы не должны видеть ни ", ни "Null".Если вы правильно используете параметризованные запросы, это должно выглядеть примерно так:
ОБНОВИТЬ набор таблиц [action_date] = @ActionDate, ГДЕ [id] = @ID
В весь смысл параметризованного запроса заключается в том, что фактическое значение параметра равно никогда подставляется непосредственно в строку запроса.
Ваш код запроса должен выглядеть примерно так:
string sql = "UPDATE table SET [action_date]= @ActionDate WHERE [id]= @CM_id";
using (var cn = new SqlConnection("your connection string here."))
using (var cmd = new SqlCommand(sql, cn))
{
cmd.Parameters.Add("@ActionDate", SqlDbTypes.DateTime).Value =
ActionDate.Equals("")? DBNull.Value : DateTime.Parse(ActionDate);
cmd.Parameters.Add("@CM_id", SqlDbTypes.Int).Value = 2488;
cn.Open();
cmd.ExecuteNonQuery();
}
Результатом выполнения этого кода является то, что параметры вашего запроса отправляются на сервер в виде данных.Ни в какой момент вашего кода на C # вы никогда не сможете просмотреть строку запроса с вашими данными, подставленными в:он отправляется на сервер отдельно.
Это предотвращает любую возможность того, что сервер выполнит значение параметра в виде кода из-за ошибки при очистке вашего значения параметра.Данные полностью разделены, и в первую очередь их не нужно очищать для этого контекста.Это также позволяет серверу кэшировать и повторно использовать план выполнения запроса, что приводит к (небольшому) повышению производительности.
Другие советы
Ваш параметризованный запрос должен показывать
UPDATE table SET [action_date] = @ActionDate WHERE [id] = @id
И значение параметра должно иметь эквивалентное нулю значение.
Ваш sql - это
"UPDATE CM_Codebase SET [action_date] = '" + @ActionDate + "'
WHERE [id] = " + @CM_id + "";
Что на самом деле не имеет смысла.Вы должны позволить sql заменить @ActionDate и @CM_ID, а не создавать динамический sql-запрос.
Ваш sql должен буквально быть:
String sql = "UPDATE table SET [action_date] = @ActionDate WHERE [id] = @CM_id"
Вокруг переменных не должно быть конкатенации строк, и они не должны быть заключены в кавычки.
Ваш запрос, безусловно, не похож на те, что были опубликованы.
Ваш параметр @ должен находиться внутри вашей строки, чтобы его можно было правильно прочитать.Вы видите ActionDate = " скорее всего, потому что @ActionDate не существует.
Вам нужно что-то вроде
string sql = "UPDATE CM_Codebase SET [action_date] = @ActionDate WHERE [id] = @CM_id";
Обратите внимание, что конкатенации строк не происходит.