存储过程中的相同代码错误,适用于 T-SQL

Same code errors in a Stored Procedure, works in T-SQL

我有一个调用链接服务器的存储过程,如下所示。 'datestr' 列的类型为 char(8),并且其格式并不总是正确。它通常是 yyyymmdd 但由于我不控制数据的格式,我使用 TRY_CAST 只获取可以将其格式化为日期的行。

执行 SP 时出现以下错误:

Msg 242, Level 16, State 3, Line 1 The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.

运行从T-SQLreturns数据中提取的SP完全相同的代码,没有错误。我确定问题出在带有 DATEADD 函数的 WHERE 子句的一部分遇到了一个无法转换为日期的值,但我无法弄清楚为什么它在 SP 和提取的 T-[= 中运行不同25=].

我在 运行 之前使用 SET SHOWPLAN_ALL ON 检查了计划,发现了一些变化。也就是说,在远程查询运算符中,工作查询中的估计行数要低得多(~200K 对 1500 万)

CREATE Procedure [dbo].[SampleSP]
AS
    SELECT top 50 tbl1.rowID as rowID, 
            year(datestr) as [year],
            month(datestr) as [month],
            count(*) AS CountRow
    FROM   [LinkedSer].[RemoteDB].[dbo].[tbl1] tbl1
        inner join [dbo].[LocalTbl] tbl2 on tbl1.rowID = tbl2.rowID
    WHERE  tbl1.row_type = 'tbl1A' 
    and (TRY_CAST(tbl1.datestr AS date) IS NOT NULL 
        and tbl1.datestr > DATEADD(yy, -10, getdate()))
    group BY tbl1.rowID, year(tbl1.datestr), month(tbl1.datestr)

谓词的求值顺序是plan-dependent。因此,您需要从代码中删除 potentially-invalid 比较。

并简化为:

 and TRY_CAST(tbl1.datestr AS date) > DATEADD(yy, -10, getdate())

应该可以解决问题。