[英]System.Data.SqlClient.SqlException Thrown by Dapper When Query Result Has More Than 1000 Records
The method call below fails with the message "The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.": 下面的方法调用失败,并显示消息“将varchar数据类型转换为日期时间数据类型导致超出范围的值。”:
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; }
}
If the result set contains 1000 (or fewer) records, the code works correctly. 如果结果集包含1000(或更少)记录,则代码可以正常工作。 When I execute the query in SQL Server Management Studio (2014 edition), I don't get an error either. 当我在SQL Server Management Studio(2014版)中执行查询时,我也没有收到错误。 Even when I remove the TOP from the select and execute it in SSMS, no error occurs (12,000+ records are returned, as expected). 即使我从选择中删除TOP并在SSMS中执行它,也不会发生错误(按预期返回12,000条记录)。
What should I be doing instead of the above implementation to successfully retrieve result sets with more than 1000 rows? 我应该做什么而不是上面的实现来成功检索超过1000行的结果集? Would a stored procedure be more appropriate in this case? 在这种情况下,存储过程是否更合适?
Sounds like your date fields are stored in a varchar column. 听起来您的日期字段存储在varchar列中。 Ideally, you should change those to datetime fields. 理想情况下,您应该将这些更改为datetime字段。 If that's not an option, change your WHERE
clause to look like this: 如果这不是一个选项,请将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);
The reason it succeeded on your top 1000 query is likely because the top 1000 records found all contained valid dates. 它在您的前1000个查询中成功的原因可能是因为找到的前1000个记录都包含有效日期。
That is a database server error: dapper doesn't know about varchar and doesn't take in terms of varchar - it talks about .net String
s. 这是一个数据库服务器错误:dapper不知道varchar并且不考虑varchar - 它讨论.net String
s。 So: one of your dates-stored-as-varchar is broken and does not contain a valid value. 所以:你的一个date-stored-as-varchar被破坏了,并且不包含有效值。
Basically: try this query in SSMS: I expect it will break there too! 基本上:在SSMS中尝试这个查询:我希望它也会在那里打破!
Changing to a stored procedure will not change this at all. 更改为存储过程根本不会更改此设置。 What needs to change is the broken data - and (more importantly) the bad choice of storing date/time data in a text-based column. 需要改变的是破碎的数据 - 以及(更重要的是)在基于文本的列中存储日期/时间数据的错误选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.