Как установить для NCHAR значение null с помощью оператора обновления (команда C# sql)

Мне интересно, как установить для столбца nchar значение null с помощью оператора обновления. Я нашел это: значение NULL для int в операторе обновления

в котором говорится, что вы должны выполнить приведение, чтобы установить для полей, отличных от int, значение NULL.

Итак, я попробовал следующее:

commandText = 
  @"UPDATE Brukere 
      SET Engangskode = CAST(NULL AS NCHAR) 
    WHERE Navn = @navn AND Mobilnr = @mobilnr";

Однако, когда я выполняю это, он все равно не обновит столбец до NULL. Я неправильно рисую или дело в другом? Любая помощь будет оценена по достоинству :)

Более длинный фрагмент кода, если необходимо: http://pastebin.com/8auKuk6Q


person user2875994    schedule 04.09.2015    source источник
comment
Нет необходимости в каких-либо приведениях - просто используйте UPDATE Brukere SET Engangskode = NULL WHERE Navn = @navn AND Mobilnr = @mobilnr. Это должно работать отлично, если столбец действительно позволяет NULL ...   -  person marc_s    schedule 04.09.2015
comment
@marc_s См. ответ Михаю ниже. Также не уверен, почему вы отредактировали это. Я понимаю, что вы предпочитаете такое форматирование, но это не формат моего исходного кода.   -  person user2875994    schedule 04.09.2015
comment
Ответ, в котором говорится, что по умолчанию в SQL Server NULL является INT, неверен.   -  person juharr    schedule 04.09.2015
comment
А что произойдет, если вы используете = NULL напрямую? Вы получаете сообщение об ошибке - если да, то какую ошибку??   -  person marc_s    schedule 04.09.2015
comment
@juharr Спасибо за внимание. Странно, что тогда он лежит как принятый ответ с множеством голосов. Но я пробовал без кастинга, как упоминалось в моем комментарии к Михаю ниже.   -  person user2875994    schedule 04.09.2015
comment
Из вашего кода Pastebin я считаю, что ваш код С# просто неверен, а не SQL....   -  person marc_s    schedule 04.09.2015
comment
@marc_s Нет ошибки (если вы посмотрите на мой исходный код, я установил точку останова в блоке catch, чтобы всегда получать паузу в случае возникновения ошибки). Таблица просто не обновляется с полем, установленным в NULL.   -  person user2875994    schedule 04.09.2015
comment
@marc_s Ну, С# тоже не выдает ошибок.   -  person user2875994    schedule 04.09.2015
comment
Вы не устанавливаете command.CommandText в операторе обновления. Изменение локальной переменной commandText не меняет command.CommandText.   -  person juharr    schedule 04.09.2015
comment
@juharr О. Огромное спасибо! Предполагается, что заданный текст команды был по ссылке, а не по копии. Настройте это как ответ, и я приму его (вероятно, следует указать, что это не по ссылке, для будущих посетителей вопросов).   -  person user2875994    schedule 04.09.2015
comment
@user2875994 user2875994 Это ссылка, но вы меняете локальную переменную, чтобы она ссылалась на новое значение, и это не меняет никаких других ссылок. Также, как говорит marc_s, было бы лучше просто создать отдельный файл SQLCommand.   -  person juharr    schedule 04.09.2015
comment
@juharr А, понятно. Все еще изучаю :)   -  person user2875994    schedule 04.09.2015
comment
Кроме того, в SO обычно считается лучшей практикой размещать свой код вместо публикации ссылки на него.   -  person juharr    schedule 04.09.2015
comment
@juharr Я буду иметь это в виду. Я просто предположил, что это будет немного спамить, а pastebin — довольно нейтральный сайт.   -  person user2875994    schedule 04.09.2015
comment
Я бы сказал, что это нормально, если кода много, и вы публикуете только соответствующие части вопроса и ссылку на полный код.   -  person juharr    schedule 04.09.2015
comment
@juharr Вот что я пытался сделать. Я предположил, что остальной код не имел прямого отношения к делу, но я включил его на случай, если это окажется так, чтобы вам не пришлось просить меня опубликовать его (что и произошло).   -  person user2875994    schedule 04.09.2015


Ответы (3)


Проблема в том, что вы устанавливаете локальную переменную commandText в оператор обновления вместо command.CommandText. Измените его на следующее

command.CommandText = "UPDATE Brukere SET Engangskode=NULL WHERE Navn=@navn AND Mobilnr=@mobilnr";

И я думаю, что это сработает с кастингом или без него.

person juharr    schedule 04.09.2015
comment
Я просто сделал это после изменения строки: command.CommandText = commandText; Как упоминалось выше, я думал, что это по ссылке, а не по значению. Спасибо за вашу помощь. - person user2875994; 04.09.2015
comment
Сотрите эталонный бит. - person user2875994; 04.09.2015
comment
Это по ссылке. Вы устанавливаете ссылку commandText на новый string. Это не влияет на другие ссылки. И поскольку string неизменяем, вы также не можете изменить объект, на который они оба ссылаются. - person juharr; 04.09.2015
comment
Да я понял, читай твой ответ выше. У меня сложилось впечатление, что если вы изменили значение переменной, вы изменили его в той же ячейке памяти (поэтому все ссылки на него будут видеть обновленное значение). Я предполагаю, что дело в том, что вы создаете новое значение в новой ячейке памяти и меняете ссылку на него, таким образом, не обновляя другие ссылки. - person user2875994; 04.09.2015
comment
Да, строки особенны тем, что строковый литерал создает новый объект без использования ключевого слова new и ctor. - person juharr; 04.09.2015
comment
Ааааа, я вижу. Так будет ли моя предыдущая интерпретация правильной для других типов данных. Скажи, если бы это был int? - person user2875994; 04.09.2015
comment
Ну, int — это тип значения, так что нет. Возможно, вы захотите прочитать о ссылочных типах и типах значений в C#. jonskeet.uk/csharp/references.html - person juharr; 04.09.2015
comment
Всего несколько вопросов, чтобы увидеть, правильно ли я понял это, надеюсь, вы не возражаете. 1) Вы не можете передать ссылку на тип значения (поэтому вы говорите, что это не работает для int). Вам нужно будет обернуть его в класс, а затем передать его, если вы хотите передать его по ссылке. Правильный? 2) Например: я сам делаю объект, хранящий строку. Затем это отправляется по ссылке на что-то еще. Если я затем напрямую изменю строку в объекте, будет ли ссылка, отправленная на что-то еще, также указывать на обновленный объект или его копию, содержащую старую строку? - person user2875994; 04.09.2015
comment
Было бы лучше, если бы вы просто задали новый вопрос, а не продолжали его в комментариях. - person juharr; 04.09.2015
comment
Думаю, тогда я просто проверю это. Просто подумал, что смогу получить быстрый ответ, пока привлекаю ваше внимание, хе-хе. Ну, хорошего дня. - person user2875994; 04.09.2015

Я бы порекомендовал НЕ "повторно использовать" SqlCommand в вашем примере - создайте новую конкретную команду для оператора UPDATE, что-то вроде этого:

using (SqlConnection con = new SqlConnection(connectionString))
{
    con.Open();

    string bruker = Request.Cookies["Navn"].Value;
    string mobilnr = Request.Cookies["Mobilnr"].Value;

    string commandText = "SELECT Engangskode FROM Brukere WHERE Navn=@navn AND Mobilnr=@mobilnr";

    bool correctCode = false;

    try
    {
        using (SqlCommand command = new SqlCommand(commandText, con))
        {
            .....

            if (correctCode)
            {
                // DO NOT "reuse" the previous SqlCommand - create a new, specific one!
                string updateQuery = "UPDATE Brukere SET Engangskode = NULL WHERE Navn = @navn AND Mobilnr = @mobilnr;";

                using (SqlCommand updateCmd = new SqlCommand(updateQuery, con)
                {
                    updateCmd.Parameters.Add("@navn", SqlDbType.NVarChar, 20).Value = bruker;
                    updateCmd.Parameters.Add("@mobilnr", SqlDbType.NChar, 10).Value = mobilnr;

                    updateCmd.ExecuteNonQuery();

                    Response.Redirect("Kvittering.aspx",  false);
                }
            }
        }                                    
    }
    catch( .... )
    {
        .......
    }
}            
person marc_s    schedule 04.09.2015
comment
Повторное использование работает нормально. См. мой ответ Юхарру выше :) Тем не менее, проголосуйте. - person user2875994; 04.09.2015

Нет необходимости бросать. Просто установите столбец = null. БЕЗ кавычек, ага!

person Mihai Ovidiu Drăgoi    schedule 04.09.2015
comment
К сожалению, ни один кастинг не приводит к одному и тому же результату. Это то, что я пробовал изначально. Думаю, я должен был упомянуть. - person user2875994; 04.09.2015
comment
Тогда либо where отфильтровывает все строки, либо определение столбца не допускает пустых значений. - person Mihai Ovidiu Drăgoi; 04.09.2015
comment
Если вы посмотрите на более крупный фрагмент кода, я использую точно такой же поиск WHERE ранее в коде, и там он находит правильную строку. Так что фильтрация должна быть правильной. И столбец допускает NULL - person user2875994; 04.09.2015