System.Data.SqlClient.SqlException, генерируемый Dapper, когда результат запроса имеет более 1000 записей

1

Вызов метода ниже завершился неудачей с сообщением "Преобразование типа данных 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 строк? Будет ли в этом случае более подходящая хранимая процедура?

  • 1
    Что такое тип данных BeginDate и EndDate? Какой формат данных он содержит? Также без заказа, нет никакой гарантии, что 2000 строк вы получите.
  • 0
    Я серьезно сомневаюсь, что это как- то связано с Даппером. Это исключение совершенно не связано.
Показать ещё 1 комментарий
Теги:
sql-server
dapper
dapper-extensions

2 ответа

2
Лучший ответ

Похоже, что ваши поля даты хранятся в столбце 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 записей обнаружили, что все они содержат допустимые даты.

  • 0
    Я постараюсь изменить предложение WHERE, как вы предложили, и посмотрю, излечит ли это ошибку.
  • 0
    Большое спасибо за Вашу помощь. Когда я обновил предложение WHERE до того, что вы предложили, ошибки больше не было. Я все еще не уверен, почему SSMS не дал мне ошибку с предыдущим запросом, но ваше предложение решило мою проблему.
1

Это ошибка сервера базы данных: dapper не знает о varchar и не принимает в терминах varchar - он говорит о.net String s. Итак: одна из ваших дат-хранимых-как-varchar нарушена и не содержит допустимого значения.

В основном: попробуйте этот запрос в SSMS: я ожидаю, что он тоже сломается!

Изменение на хранимую процедуру не изменит это вообще. Что нужно изменить, так это сломанные данные - и (что более важно) - плохой выбор хранения данных даты и времени в текстовом столбце.

  • 0
    Выбор типа данных не мой выбор, к сожалению. Я протестировал запрос в SSMS и не получил никаких ошибок, прежде чем добавить его в свой код.
  • 0
    @ ScottA.Lawrence, а ты проверял это на реальных данных? или только против ваших локальных / dev данных?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню