ExecuteScalar возвращает null или DBNull (сервер разработки или производства)

Я пытаюсь добавить столбец в существующий DataRow на С#. После этого столбец будет заполнен одним значением из моей базы данных.

DataRow dr уже существует, и столбец «COLNAME» также существует.
comTBP — это мой SqlCommand.

dr["COLNAME"] = Convert.ToInt32(comTBP.ExecuteScalar());

Все это прекрасно работает, если в моей базе данных есть значение, и ExecuteScalar() может получить это значение. Если я тестирую этот код на своем сервере разработки (локальном), он также работает, если ExecuteScalar() возвращает null или DBNull, а значение моего нового столбца равно 0. Но проблема возникает, если я развертываю свой код на рабочем сервере. Если я делаю все то же самое, с той же базой данных выдается исключение с сообщением о том, что он не может преобразовать DBNull в Int32.
Мой вопрос: почему эта ошибка появляется на рабочем сервере, а не на моем локальном сервере разработки? ?


person Yoni    schedule 28.10.2011    source источник
comment
Скорее всего разные данные по производству и разработке.   -  person leppie    schedule 28.10.2011


Ответы (3)


Очевидно, что в процессе производства у вас либо NULL возвращается из выполнения команды, либо что-то другое в строке подключения или что-то еще; как правило, вы всегда должны проверять DBNull перед приведением/преобразованием непосредственно в другой тип результата ExecuteScalar.

Проверьте ответ Рейна здесь (и проголосуйте за него) за его хорошее предложенное решение:

Невозможно преобразовать объект типа 'System.DBNull' на тип 'System.String`

person Davide Piras    schedule 28.10.2011
comment
Convert.ToInt32 из null приводит к 0. - person Piotr Auguscik; 28.10.2011
comment
Тогда либо он не говорит всей правды, либо вы ошибаетесь ;-) У меня были подобные проблемы в прошлом, и я решил их, всегда проверяя DBNULL перед преобразованием/приведением - person Davide Piras; 28.10.2011
comment
Я знаю, что он возвращает NULL в производстве. Он также возвращает NULL в разработке, потому что это одна и та же БД. Мой вопрос заключался в том, почему он возвращает NULL в разработке и DBNull в производстве? При разработке приведение от NULL к Int32 приведет к 0, но в производстве оно пытается привести от DBNull к Int32 и выдает исключение. - person Yoni; 28.10.2011
comment
Ну, это написано в документации: Return Value: A 32-bit signed integer equivalent to value, or zero if value is Nothing. - person Piotr Auguscik; 28.10.2011
comment
AFAIK null в С# НЕ является DbNull.Value !! - person Davide Piras; 28.10.2011
comment
Я знаю... и это мой вопрос?? В разработке возврат равен NULL, а в производстве возврат равен DBNull. - person Yoni; 28.10.2011
comment
являются ли строки подключения и все уровни, такие как версии .NET, пакеты обновлений, драйверы БД, ОС и все остальное, одинаковыми, и вы подключаетесь к одному и тому же точному компьютеру SQL Server, базе данных, таблице и хранимой процедуре? Где-то должна быть разница! Релиз против сборки отладки....?! в любом случае у вас есть решение, как справиться с этим, в ответе, который я указал выше. - person Davide Piras; 28.10.2011
comment
Я предполагаю, что проблема, как вы говорите, с версиями. Для разработки используется Windows 7, а для производства — Windows Server 2008 R2. Release vs Debug не может быть проблемой, потому что я также попробовал выпущенную версию на своем локальном компьютере, и строка подключения такая же, как и на том же компьютере с SQL Server. Я думаю, что мое единственное (и самое безопасное) решение - использовать метод, предложенный вами выше, и проверять значения DBNull или NULL. - person Yoni; 28.10.2011
comment
да, вы всегда должны проверять значение null и DBNull... перед использованием полученного объекта, а не только при преобразовании в Int32 - person Davide Piras; 28.10.2011

ExecuteScalar возвращает DBNull для нулевого значения из query и null для отсутствия результата. Возможно, на вашем сервере разработки этого никогда не происходило (null результат из query).

person Piotr Auguscik    schedule 28.10.2011

Используйте функцию ISNULL() в вашем SQL.

ISNULL (check_expression, replace_value)

ie...

ВЫБЕРИТЕ ISNULL (СУММА (Цена), 0) ИЗ Заказа

person Chris Catignani    schedule 25.09.2014