SqlDataReader.HasRows возвращает false с момента обновления SQL 2008
У меня есть веб-сайт ASP.NET 2.0, который подключается к базе данных SQL. Я обновил SQL-сервер с 2000 до 2008, и с тех пор одна страница отказывается работать.
Я решил, что проблема в том, что вызов SqlDataReader.HasRows возвращает false, даже если набор данных не пустой, а удаление проверки позволяет циклу через reader.Read() получить доступ к ожидаемым данным.
_connectionString = WebConfigurationManager.ConnectionStrings["SQLServer"].ConnectionString;
SqlConnection connection = new SqlConnection(_connectionString);
SqlCommand command = new SqlCommand(searchtype, connection);
SqlParameter _parSeachTerm = new SqlParameter("@searchterm", SqlDbType.VarChar, 255);
_parSeachTerm.Value = searchterm;
command.Parameters.Add(_parSeachTerm);
command.CommandType = CommandType.StoredProcedure;
try
{
connection.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows) //this always returns false!?
{
while (reader.Read())
{...
Кто-нибудь знает, что происходит? На других страницах есть похожие блоки кода, где HasRows возвращает правильное значение.
РЕДАКТИРОВАТЬ - просто чтобы уточнить, хранимая процедура возвращает результаты, которые я подтвердил, потому что цикл проходит нормально, если я уберу проверку HasRows. Изменение только имени сервера SQL в строке подключения к идентичной базе данных, работающей на SQL 2000, устраняет проблему. Я проверил, что NOCOUNT выключен, так что еще может заставить HasRows возвращать false, если это не так??
EDIT2- вот SP
CREATE PROCEDURE StaffEnquirySurnameSearch
@searchterm varchar(255)
AS
SELECT AD.Name, AD.Company, AD.telephoneNumber, AD.manager, CVS.Position, CVS.CompanyArea, CVS.Location, CVS.Title, AD.guid AS guid,
AD.firstname, AD.surname
FROM ADCVS AD
LEFT OUTER JOIN CVS ON
AD.Guid=CVS.Guid
WHERE AD.SurName LIKE @searchterm
ORDER BY AD.Surname, AD.Firstname
GO
Спасибо заранее.
7 ответов
Работает ли хранимая процедура, если вы вызываете ее напрямую, скажем, в SSMS? Я бы начал с того, чтобы убедиться, что это так.
HasRows
требует прокручиваемого курсора.
Содержат ли строки, которые вы возвращаете, какие-либо большие image/BLOB
данные?
Как кто-то еще предложил, я думаю, что размещение Stored Procedure
может пролить свет на этот вопрос...
Я думаю, что у вас есть NOCOUNT задом наперед. Я считаю, что NOCOUNT должен быть включен, чтобы это работало.
В вашей хранимой процедуре добавьте SET NOCOUNT ON после AS и перед любым кодом. В противном случае он возвращает два набора результатов. Один с количеством и один с фактическими данными. Вам нужен только набор результатов с фактическими данными.
Вы случайно не используете RAISEERROR? Мы обнаружили некоторые проблемы, используя тот же шаблон, что и выше (проверьте HasRows, затем reader.Read()) и обнаружили, что если бы RAISEERROR использовался с определенным кодом ошибки (я полагаю, выше 16), то HasRows вернул бы false, и мы получили бы проблемы ловли исключения.
Я снова размышляю.
У вас есть несколько открытых для чтения данных случайно?
Добавить MARS_Connection= да; ИЛИ MultipleActiveResultSets=true для строки подключения, если это помогает.
Кроме того, использование вами соединения и устройства чтения данных не является рекомендуемым способом ведения дел.
более простой способ написать это может быть
using (connection cnn = new Connection(...)
{
using (SqlDataReader rdr = ....
{
//some code which deals with datareader
}
}
Это закроет соединение и устройство чтения данных после завершения операции.
Сначала проверьте процедуру, как говорит @tvanfosson. Во-вторых, проверка для HasRows() на самом деле не нужна в фрагменте кода.
Это либо строка вашего подключения, хранимая процедура, либо ошибка в драйвере sql. Большинство людей угадывают хранимую процедуру. Так покажи нам код. Пока вы это делаете, покажите нам строку подключения и переменные типа поиска.