SSMS - SQL 2017 我正在从视图中选择记录 - 3个场景,并且查询失败,其中一个有错误。
SELECT top 94 *
FROM [myDB].[dbo].[test1]
结果:(94行受影响)
SELECT top 95 *
FROM [myDB].[dbo].[test1]
结果:
Msg 241,Level 16,State 1,Line 2 从字符串转换日期和/或时间时转换失败。
SELECT *
FROM [myDB].[dbo].[test1]
结果:(受影响的24934行)
这让我很困惑。 SELECT如何在第二个场景中给出错误而在第三个场景中没有错误。
答案 0 :(得分:2)
有些情况会发生这种情况。通常,此类转换错误位于select
表达式或where
表达式中,其类型不兼容。
你的结果是:
我最好的猜测是你看到了查询计划的变化。当您选择95行时,查询计划正在处理数据并查找错误。有错误的行将在稍后过滤掉,但错误已经发生。
当您选择所有行时,查询计划会更改,并且不再出现错误,因为过滤发生在转换错误之前。
例如,请考虑以下问题:
select . . .
from t1 join
t2
on t1.x = t2.x
where t1.col1 = 5 and
cast(t2.col2 as date) = cast(getdate() as date); -- this generates the error
这可以通过两种方式进行评估。使用t1
作为驱动表,对所有行执行“5”的过滤器。但是只会过滤t2
中匹配的行。所以,不会发生错误。
或者,可以过滤t2
并将过滤器应用于所有行。错误!我们永远不会进一步了解错误行会被过滤掉。
执行计划的选择可以基于返回的行数。或者,成本可能完全相同,SQL Server任意选择其中一个。