简体   繁体   English

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

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

Here's an example of the scenario: 这是方案的一个示例:

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.

I would expect both the scenarios to work since the view already filters out the bad data. 我希望这两种方案都能正常工作,因为视图已经过滤掉了不良数据。 What's even stranger is that the second query does not work either. 更奇怪的是第二个查询也不起作用。 I can only grab an estimated execution plan on both of them (since I can't actually run the query without error), and they are identical. 我只能对它们两者都获取一个估计的执行计划(因为我实际上无法毫无错误地运行查询),并且它们是相同的。 Based on the estimated plan, the bad data would be filtered first before the WHERE Value = 1 is applied. 根据估计的计划,将在应用WHERE Value = 1之前首先过滤不良数据。

Edit: To test the query plans, I changed the CONVERT to TRY_CONVERT instead. 编辑:为了测试查询计划,我将CONVERT更改为TRY_CONVERT。 The result of the plans are still identical, and it looks like the filter occurs before the conversion: 计划的结果仍然相同,并且看起来转换之前发生了过滤器:

在此处输入图片说明

I would expect both the scenarios to work since the view already filters out the bad data 我希望这两种方案都能正常工作,因为视图已经过滤掉了不良数据

you are using a view and view just stores definition ..At run time,your queries will be both expanded and this comparison will definitely fail 您正在使用视图,并且视图仅存储定义。.在运行时,您的查询都将被扩展,并且此比较肯定会失败

 SELECT CONVERT(BIGINT,Value) Value

you may also think,that where clause should filter out bad data,but this may or may not happen..this has been explained by Paul white here: TSQL divide by zero encountered despite no columns containing 0 您可能还认为,where子句应该过滤掉错误的数据,但这可能会或可能不会发生。.Paul White在此进行了解释: 尽管没有包含0的列,但TSQL除以零

SQL is a declarative language; SQL是一种声明性语言; you write a query that logically describes the result you want, but it is up to the optimizer to produce a physical plan. 您编写了一个查询,该查询从逻辑上描述了您想要的结果,但这取决于优化程序来生成物理计划。 This physical plan may not bear much relation to the written form of the query, because the optimizer does not simply reorder 'steps' derived from the textual form of the query, it can apply over 300 different transformations to find an efficient execution strategy. 该物理计划可能与查询的书面形式关系不大,因为优化器不会简单地对查询文本形式派生的“步骤”进行重新排序,而是可以应用300多种不同的转换来找到有效的执行策略。

There is also a connect item raised ,but there are different opinions as you see in comments on the connect item 提出了一个连接项 ,但是您对连接项的评论中有不同的意见

also see below example from connect item which is similar to yours and it is also relies on filtering out bad data 还可以从连接项中看到下面的示例,该示例与您的类似,并且它还依赖于过滤出不良数据

 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

The above query fails with below error 上面的查询失败,并出现以下错误

This query fails with "Conversion failed when converting the varchar value 'Gurka' to data type int.", despite this row would never appear in the output 尽管此行永远不会出现在输出中,但此查询失败,并显示“将varchar值'Gurka'转换为数据类型int时转换失败。”

Coming to your edit and below point 进行编辑并低于要点

Edit: To test the query plans, I changed the CONVERT to TRY_CONVERT instead. 编辑:为了测试查询计划,我将CONVERT更改为TRY_CONVERT。 The result of the plans are still identical, and it looks like the filter occurs before the conversion: 计划的结果仍然相同,并且看起来转换之前发生了过滤器:

The plans you provided are estimated ones not actual ones.see this answer on how they can be different : Differences between estimated and actual execution plans 您提供的计划是估计的,而不是实际的。请查看此答案以了解它们的不同之处: 估计执行计划与实际执行计划之间的差异

Also check out this answer by Martin Smith for more examples 还可以查看马丁史密斯的答案,以获取更多示例

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

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

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