Вызов метода ниже завершился неудачей с сообщением "Преобразование типа данных varchar в тип данных datetime приводит к значению вне диапазона".:
public IEnumerable<SomeResult> GetResults(SqlConnection connection, string attribute)
{
var sql = string.Format(@"
SELECT TOP 2000
r.Id
,r.LastName
,r.FirstName
,r.Ssn
,r.CurrentId
,BeginDate = case when isdate(rli.BeginDate) = 1 then convert(datetime, rli.BeginDate) else NULL end
,EndDate = case when isdate(rli.EndDate) = 1 then convert(datetime, rli.EndDate) else NULL end
,rli.LcknTyCd
,rli.ProvId
FROM
[dbo].[Span] rli
INNER JOIN [dbo].Recipient r
ON rli.SysId = r.SysId
INNER JOIN [dbo].ValidRecipient lc
ON r.SysId = lc.SysId
WHERE
BeginDate <= GETDATE()
AND EndDate >= GETDATE()
AND rli.LcknTyCd = @LcknTyCd);
return connection.Query<SomeResult>(sql, new { LcknTyCd = attribute}).ToList();
}
public struct SomeResult
{
public string Id{ get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public string Ssn { get; set; }
public string CurrentId{ get; set; }
public DateTime? BeginDate { get; set; }
public DateTime? EndDate { get; set; }
public string LcknTyCd{ get; set; }
public string ProvId{ get; set; }
}
Если набор результатов содержит 1000 (или меньше) записей, код работает правильно. Когда я выполняю запрос в SQL Server Management Studio (выпуск 2014 года), я тоже не получаю ошибку. Даже когда я удаляю TOP из выбора и выполняю его в SSMS, ошибка не возникает (12, 000+ записи возвращаются, как и ожидалось).
Что я должен делать вместо вышеупомянутой реализации для успешного извлечения наборов результатов с более чем 1000 строк? Будет ли в этом случае более подходящая хранимая процедура?
Похоже, что ваши поля даты хранятся в столбце varchar. В идеале вы должны изменить их на поля datetime. Если это не вариант, измените WHERE
следующим образом:
WHERE
case when isdate(rli.BeginDate) = 1 then convert(datetime, rli.BeginDate) else NULL end <= GETDATE()
AND case when isdate(rli.EndDate) = 1 then convert(datetime, rli.EndDate) else NULL end >= GETDATE()
AND rli.LcknTyCd = @LcknTyCd);
Причина, по которой он преуспел в вашем последнем запросе 1000, вероятен, потому что первые 1000 записей обнаружили, что все они содержат допустимые даты.
Это ошибка сервера базы данных: dapper не знает о varchar и не принимает в терминах varchar - он говорит о.net String
s. Итак: одна из ваших дат-хранимых-как-varchar нарушена и не содержит допустимого значения.
В основном: попробуйте этот запрос в SSMS: я ожидаю, что он тоже сломается!
Изменение на хранимую процедуру не изменит это вообще. Что нужно изменить, так это сломанные данные - и (что более важно) - плохой выбор хранения данных даты и времени в текстовом столбце.