2009-02-24 7 views
1

У меня есть веб-форма C#, у которой есть блок выбора даты. Если дата не установлена ​​(по умолчанию), я хочу передать NULL в базу данных. Это происходит в моем параметризованном запросе.Мой SQLParameter не передает 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}, как я думаю, что это должно быть.

Однако.

Когда затем идет выполнить nonquery, я нажимаю лупу и увидеть это:

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:00 AM», и это само по себе.

Я попытался установить CMActionDate.Value следующие значения не дало никаких результатов (я получить тот же результат, что и выше.):

  • DBNull.Value;
  • "NULL";
  • SqlDateTime.Null;
  • null;

Помощь.

EDIT

Может быть, я не ясно? Да, конечно, параметризованные запросы выглядят следующим образом:

"UPDATE CM_Codebase SET [action_date] = '" + @ActionDate + "' WHERE [id] = " + @CM_id + ""; 

Но когда я отладки этой вещи в VS, я поставил точку останова прямо перед ExecuteNonQuery(); поэтому я могу увидеть SQL, который он пытается запустить. Там я вижу фактический SQL и вижу бит где action_date = ''.

Помогло ли это?

+0

Вы делаете это неправильно. Прочтите код в моем ответе снова. По-прежнему вам приходится пытаться использовать параметр, такой как переменная подстановки, и с точки зрения кода C#, что просто не так. –

+0

Обратите внимание, что в моем коде не существует одиночных кавычек вокруг @ActionDate, и я включаю @ActionDate в запрос как еще одну часть строкового литерала. –

ответ

13

Вы не должны видеть ни '' или 'Null'. Если вы используете параметризованные запросы правильно, это должно выглядеть следующим образом:

UPDATE таблица SET [ACTION_DATE] = @ActionDate WHERE [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# вы никогда не сможете просмотреть строку запроса с замененными данными: она отправляется на сервер отдельно.

Это предотвращает любую возможность выполнения сервером значения параметра как кода из-за ошибки в дезинфекции вашего значения параметра. Данные полностью раздельны и в первую очередь не нуждаются в санитарной обработке для этого контекста. Он также позволяет серверу кэшировать и повторно использовать план выполнения запроса, что приводит к небольшому увеличению производительности.

+0

см. Мое редактирование выше, я думаю, я был недостаточно ясен. – somacore

+0

Это сделало это. Спасибо за ваше объяснение в комментариях выше. Это помогло мне понять, что я делаю неправильно. В какой-то момент все что-то новое. – somacore

+0

Не стоит беспокоиться: просто так вы получите его в конце :) –

1

Ваш parametized запрос должен показать

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" 

Там не должен быть никакой конкатенации вокруг переменных, и они не должны быть обернуты в кавычках.

+0

Почему -1? Мой ответ такой же, как у Джоэла, но без дополнительного кода. – cjk

+0

Я поддержал это до 0 для вас, но см. Мое редактирование выше для уточнения. – somacore

+0

«Мой ответ такой же, как у Джоэля, но без дополнительного кода» - Да, и именно поэтому я и пропустил ваш ответ. –

0

Ваш запрос, безусловно, не похож на опубликованные.

Ваш @parameter должен находиться внутри вашей строки, чтобы ее правильно читать. Вы видите ActionDate = '', потому что @ActionDate не существует, скорее всего.

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

string sql = "UPDATE CM_Codebase SET [action_date] = @ActionDate WHERE [id] = @CM_id"; 

Обратите внимание, что нет конкатенация происходит.