我有一些看起来像这样的C#代码:
string strSql = "SELECT DISTINCT A." + strProcessingDateColumn
+ " FROM GA_Item A "
+ " WHERE A.TOWControlID = @TOWControlID"
+ " AND A.ItemTypeExt = 'PDF' "
+ " AND A." + strSourceColumn + " = 'Teller Report' "
+ " AND A." + strReportNumberColumn + " = @ReportNum "
+ " AND A." + strIBTColumn + " <> '9999' "
+ " AND ISNULL(A." + strMergedColumn + ", 'N') = 'N'"
+ " AND CAST(LTRIM(RTRIM(A." + strProcessingDateColumn + ")) AS DATETIME) < @ProcessingDate";
using (SqlCommand command = new SqlCommand(strSql, conn))
{
command.Parameters.AddWithValue("@TOWControlID", iTOWControlID);
command.Parameters.AddWithValue("@ReportNum", iReportNumber.ToString());
command.Parameters.AddWithValue("@ProcessingDate", dtCurrentDate);
try
{
using (SqlDataReader datereader = command.ExecuteReader())
{
while (datereader.Read())
{
//...
}
}
}
}
这会生成一个sp_executesql语句(我从SQL分析器中提取),如下所示:
exec sp_executesql N'SELECT DISTINCT A.UserField1 FROM GA_Item A
WHERE A.TOWControlID = @TOWControlID
AND A.ItemTypeExt = ''PDF''
AND A.UserField4 = ''Teller Report''
AND A.UserField3 = @ReportNum
AND A.UserField2 <> ''9999''
AND ISNULL(A.UserField5, ''N'') = ''N''
AND CAST(LTRIM(RTRIM(A.UserField1)) AS DATETIME) < @ProcessingDate'
,N'@TOWControlID int,@ReportNum nvarchar(1),@ProcessingDate datetime'
,@TOWControlID=9999
,@ReportNum=N'6'
,@ProcessingDate='2015-03-24 00:00:00'
导致2个错误:The conversion of a nvarchar data type to a datetime data type resulted in an out-of-range value.
和Conversion failed when converting date and/or time from character string.
这让我相信某些东西正在导致我正在选择的表中出现溢出。但是,如果我从sp_executesql语句中提取查询,那么它看起来像这样:
declare @TOWControlID int = 9999,
@ReportNum nvarchar = '6',
@ProcessingDate datetime = '2015-03-24'
SELECT DISTINCT A.UserField1 FROM GA_Item A
WHERE A.TOWControlID = @TOWControlID
AND A.ItemTypeExt = 'PDF'
AND A.UserField4 = 'Teller Report'
AND A.UserField3 = @ReportNum
AND A.UserField2 <> '9999'
AND ISNULL(A.UserField5, 'N') = 'N'
AND CAST(LTRIM(RTRIM(A.UserField1 AS DATETIME))) < @ProcessingDate
查询按预期工作。
奇怪的是,这个确切的代码曾经在SQL 2000中运行,但是我们已经迁移了系统以使用SQL 2008,现在我们遇到了这个问题。我在SQL 2000中遇到了一个问题,其中查询直接拒绝运行,除非日期时间相等条件是列表中的最后一个,所以一旦我们将它移动到列表的底部,它就能正常工作几个月。
我已经检查并仔细检查过,我看不出我给它的数据有什么问题,以及表格中的数据。我可以将UserField1中的每个值(这是nvarchar(256)
)转换为单独查询中的日期时间没问题。
我错过了什么吗?
表的架构非常大,所以我不会在这里发布整个内容,但它基本上归结为UserField1-20 nvarchar(256), null
,TOWControlID int null
和ItemTypeEXT nvarchar(50), null
我还应该注意,如果我从sp_executesql语句中删除AND CAST(LTRIM(RTRIM(A.UserField1)) AS DATETIME) < @ProcessingDate
,则查询会运行,但它无法获得正确的结果。
所有内容都指向表中的数据错误,但是如果我运行它:
declare @TOWControlID int = 9999,
@ReportNum nvarchar = '6',
@ProcessingDate datetime = '2015-03-24'
SELECT CAST(LTRIM(RTRIM(A.UserField1)) FROM GA_Item A
WHERE A.TOWControlID = @TOWControlID
AND A.ItemTypeExt = 'PDF'
AND A.UserField4 = 'Teller Report'
AND A.UserField3 = @ReportNum
AND A.UserField2 <> '9999'
AND ISNULL(A.UserField5, 'N') = 'N'
查询执行正常。
答案 0 :(得分:2)
您需要明确设置日期格式,请参阅https://msdn.microsoft.com/en-us/library/ms189491.aspx
升级到SQL2008后,默认语言是否发生了变化,请参阅
答案 1 :(得分:1)
进行子选择以获取转换日期,如果无法转换,则执行错误日期,然后与之进行比较
CASE
WHEN ISDATE(LTRIM(RTRIM(A.UserField1))) = 1
THEN CONVERT(datetime, LTRIM(RTRIM(A.UserField1)))
ELSE @ProcessingDate END as convertedDate
and convertedDate < @ProcessingDate
似乎未指定where子句评估顺序。因此,其他条款应排除的非日期可以作为日期进行评估,除非排除条款恰好先运行