繁体   English   中英

为什么在筛选查询中使用筛选视图时无法转换?

[英]Why does a filtered view fail to convert when used in a filtered query?

这是方案的一个示例:

CREATE TABLE dbo.TestConversionTable
(
    Value VARCHAR(MAX)
)

INSERT INTO dbo.TestConversionTable VALUES ('1')
INSERT INTO dbo.TestConversionTable VALUES ('foo')

CREATE VIEW dbo.TestConversion 
AS
    SELECT CONVERT(BIGINT,Value) Value
    FROM dbo.TestConversionTable
    WHERE Value <> 'foo'
GO

SELECT * FROM dbo.TestConversion --this works
SELECT * FROM dbo.TestConversion WHERE Value = 1 --Error converting data type varchar to bigint.
SELECT * FROM dbo.TestConversion WHERE Value = '1' --Same thing, this doesn't work either.

我希望这两种方案都能正常工作,因为视图已经过滤掉了不良数据。 更奇怪的是第二个查询也不起作用。 我只能对它们两者都获取一个估计的执行计划(因为我实际上无法毫无错误地运行查询),并且它们是相同的。 根据估计的计划,将在应用WHERE Value = 1之前首先过滤不良数据。

编辑:为了测试查询计划,我将CONVERT更改为TRY_CONVERT。 计划的结果仍然相同,并且看起来转换之前发生了过滤器:

在此处输入图片说明

我希望这两种方案都能正常工作,因为视图已经过滤掉了不良数据

您正在使用视图,并且视图仅存储定义。.在运行时,您的查询都将被扩展,并且此比较肯定会失败

 SELECT CONVERT(BIGINT,Value) Value

您可能还认为,where子句应该过滤掉错误的数据,但这可能会或可能不会发生。.Paul White在此进行了解释: 尽管没有包含0的列,但TSQL除以零

SQL是一种声明性语言; 您编写了一个查询,该查询从逻辑上描述了您想要的结果,但这取决于优化程序来生成物理计划。 该物理计划可能与查询的书面形式关系不大,因为优化器不会简单地对查询文本形式派生的“步骤”进行重新排序,而是可以应用300多种不同的转换来找到有效的执行策略。

提出了一个连接项 ,但是您对连接项的评论中有不同的意见

还可以从连接项中看到下面的示例,该示例与您的类似,并且它还依赖于过滤出不良数据

 create table albert(a int NOT NULL,
                        b varchar(23) NOT NULL)
   create table stina (a int NOT NULL)  
  go
   insert albert (a, b) 
       values  (1, '99'), 
              (2, 'Gurka'),
              (3, '89')
   insert stina (a) values(1), (3), (9), (12)
   go
   SELECT a.a, a.b + 100   
   FROM   albert a
   JOIN   stina s ON s.a = a.a

上面的查询失败,并出现以下错误

尽管此行永远不会出现在输出中,但此查询失败,并显示“将varchar值'Gurka'转换为数据类型int时转换失败。”

进行编辑并低于要点

编辑:为了测试查询计划,我将CONVERT更改为TRY_CONVERT。 计划的结果仍然相同,并且看起来转换之前发生了过滤器:

您提供的计划是估计的,而不是实际的。请查看此答案以了解它们的不同之处: 估计执行计划与实际执行计划之间的差异

还可以查看马丁史密斯的答案,以获取更多示例

https://stackoverflow.com/a/7192951/2975396

暂无
暂无

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

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