SQL - 为什么这个选择的排序很重要?

时间:2018-05-24 09:53:10

标签: sql select

我运行以下代码并收到以下错误;

  

将varchar值'1.5'转换为数据类型int

时转换失败
O(n * m)

在此示例中,SMR = 5且SMA = 1.5,并且这两个值都已声明为Numerics。但是,通过切换子句的顺序,错误停止发生,存储过程继续进行(见下文)

BEGIN -- first update to check Interface held SMR and Interface held SMA
update interface set INTERR = 'U7'
from interface i
where 
i.conttype = 'SMR' 
and isnumeric(i.contrate)=1 
and cast(i.contrate as decimal(12,2)) < 5 
and caseno = @caseno
and exists (
    select 1 
    from interface i2 
    where i2.caseno = @caseno 
    and i2.conttype = 'SMA' 
    and i2.intmembno = i.intmembno 
    and i2.effdte = i.effdte 
    and i2.contrate > cast(0 as decimal(12,2)) 
    and isnumeric(i2.contrate)=1
)

你能帮我理解为什么订购很重要吗?通常情况下,据我所知,它不会也不应该。

谢谢! 保罗

1 个答案:

答案 0 :(得分:2)

WHERE条件不会以任何特定顺序执行。使用子查询和CTE时甚至都是如此 - 优化器重新排列处理并且有充分的理由。

而且,使用隐式转换是危险的 - 正如您所发现的那样。因此,使用显式转换并执行:

where i.conttype = 'SMR' and
      try_cast(i.contrate as decimal(12,2)) < 5 and
      caseno = @caseno and
      exists (select 1 
              from interface i2 
              where i2.caseno = @caseno and
                    i2.conttype = 'SMA' and
                    i2.intmembno = i.intmembno and
                    i2.effdte = i.effdte and
                    try_cast(i2.contrate as decimal(12,2)) > 0
             )

注意:

  • 您无需查看isnumeric()
  • 无需为0投射常量,例如case
  • 您可以在2012年之前的SQL Server版本中使用private statsform _statsform = null; public exportform(statsform caller) { _statsform = caller; } 执行类似的操作。