转换时SQL转换失败

时间:2014-05-15 09:20:53

标签: sql sql-server sql-server-2008 view

以下情况:

列xy定义为varchar(25)。在视图(SQL Server Mgmt Studio 2008)中,我使用字母过滤了所有值( - >不像'%[AZ]%')并将其转换为int(cast(xy as int))

如果我现在尝试使用该列进行包含(例如,xy <1000),我收到转换错误。并且该邮件包含一个应该使用&#34;过滤的值,而不是&#39;%[A-Z]%&#39;&#34;。怎么了?

提前感谢您的帮助......

这是有效的(例如价值&#39; G8111&#39;): 选择unid 从CD_UNITS作为内部加入DEF_STATION,作为a.STATION = b.STATION 在哪里(b.CURENT =&#39; T&#39;)和UNID喜欢&#39;%[A-Z]%&#39;

但是当我把它放在一个视图中时,选择一个make:

从my_view中选择*,其中xy&lt; 3000

系统说&#39;转换varchar值时转换失败&#39; G8111&#39;数据类型int。&#39;但是&#39; G8111&#39;应该在上面的查询过滤掉...

1 个答案:

答案 0 :(得分:0)

优化器有时会crazy things,所以尽管“内部”过滤器 1 “应该”保护你,但优化器仍然可以将转换压低于过滤器并导致此类错误。

唯一没有记录的半文档位置是CASE expression

  

CASE语句( sic )按顺序评估其条件,并在满足条件的第一个条件下停止。在某些情况下,在CASE语句接收表达式的结果作为其输入之前,将计算表达式。

     

...

     

您应该只依赖于标量表达式WHEN条件的评估顺序(包括返回标量的非相关子查询),而不是聚合表达式

因此,目前唯一可行的方法是:

CASE WHEN xy NOT LIKE '%[^0-9]%' THEN CONVERT(int,xy) END < 1000

这也使用带有LIKE的双重否定值,以确保它仅在值仅包含数字时尝试转换。


1 这是在子查询,CTE,视图中,还是只考虑SELECTWHERE条款的logical processing order。在单个查询中,优化程序可以并且将推动转换操作通过过滤器。