简体   繁体   English

TSQL正常运行,但不能通过sp_executesql

[英]TSQL that works normally but not through sp_executesql

I have some C# code that looks like this: 我有一些看起来像这样的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())
            {
              //...
            }
          }
        }
      }

Which generates an sp_executesql statement (which I pulled from the SQL profiler) that looks like this: 它将生成一个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'

Which results in 2 errors: The conversion of a nvarchar data type to a datetime data type resulted in an out-of-range value. 导致2个错误: The conversion of a nvarchar data type to a datetime data type resulted in an out-of-range value. and Conversion failed when converting date and/or time from character string. Conversion failed when converting date and/or time from character string.

That leads me to believe that something is causing an overflow in the table I'm selecting from. 这使我相信,某些原因导致我从中选择的表溢出。 However, if I extract the query out of the sp_executesql statement so it looks like this: 但是,如果我从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

The query works as expected. 该查询按预期方式工作。

The stranger thing is that this exact code used to work in SQL 2000, but we have migrated the system to use SQL 2008 and now we are getting this problem. 奇怪的是,这种确切的代码曾经在SQL 2000中可用,但是我们已经迁移了系统以使用SQL 2008,现在就遇到了这个问题。 I had an issue in SQL 2000 where the query straight up refused to run unless the datetime equality condition was the last one in the list, so once we moved it to the bottom of the list it worked fine for months. 在SQL 2000中,我遇到一个问题,除非日期时间相等条件是列表中的最后一个条件,否则查询将直接拒绝运行,因此一旦将其移到列表的底部,它可以正常工作数月。

I have checked and double checked and I cannot see anything wrong with the data I'm giving it, as well as the data in the table. 我已经检查并仔细检查过,我看不到我提供的数据以及表格中的数据有任何问题。 I can convert every value in UserField1 (which is an nvarchar(256) ) to a datetime no problem in a separate query. 我可以将UserField1中的每个值(这是一个nvarchar(256) )转换为日期时间,在单独的查询中没有问题。

Am I missing something? 我想念什么吗?

The schema of the table is quite large, so I won't post the whole thing here, but it basically boils down to UserField1-20 nvarchar(256), null , TOWControlID int null , and ItemTypeEXT nvarchar(50), null 该表的架构很大,因此我不会在此处发布整个内容,但基本上可以归结为UserField1-20 nvarchar(256), nullTOWControlID int nullItemTypeEXT nvarchar(50), null

I should also note that if I remove the AND CAST(LTRIM(RTRIM(A.UserField1)) AS DATETIME) < @ProcessingDate from the sp_executesql statement the query runs, but it doesn't get the right results. 我还应注意,如果我从sp_executesql语句中删除AND CAST(LTRIM(RTRIM(A.UserField1)) AS DATETIME) < @ProcessingDate ,则查询将运行,但不会获得正确的结果。

Everything is pointing to a data error in the table, but if I run this: 一切都指向表中的数据错误,但是如果运行此命令:

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'

The query executes fine. 查询执行得很好。

You need to set the date format explicitly, see https://msdn.microsoft.com/en-us/library/ms189491.aspx 您需要显式设置日期格式,请参阅https://msdn.microsoft.com/zh-cn/library/ms189491.aspx

Did the default language change after the upgrade to SQL2008, see 升级到SQL2008后,默认语言是否发生更改,请参阅

How to change the language and date format in SQL Server? 如何在SQL Server中更改语言和日期格式?

do a subselect to get the converted date, or an error date if it can't convert and then compare against that 进行子选择以获取转换后的日期,如果无法转换则返回错误日期,然后与之进行比较

CASE 
WHEN ISDATE(LTRIM(RTRIM(A.UserField1))) = 1 
THEN CONVERT(datetime, LTRIM(RTRIM(A.UserField1))) 
ELSE @ProcessingDate END as convertedDate

and convertedDate < @ProcessingDate

it seems the where clause evaluation order is not specified. 似乎未指定where子句的评估顺序。 so non dates which should be excluded by the other clauses, may be evaluated as dates unless the excusion clause happens to run first 因此,应将其他条款排除在非日期之外的非日期视为日期,除非该免责条款恰好首先运行

Using case statements with IsDate in a SQL where clause 在SQL where子句中将Case语句与IsDate一起使用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM