SQL -VB - 即使if为真,它还会评估else吗?

时间:2011-08-12 12:57:37

标签: sql sql-server-2005 reporting-services

我正在尝试阻止#error显示在我正在创建的报告中

当我将2个数字分开并且其中一个为零时会发生这种情况

所以我尝试使用if / switch语句在进行除法之前检查2号中的任何一个是否为0:

    =IIf(Fields!Field1.Value = 0 
            or Fields!Field2.Value = 0 
            or Not(IsNumeric(Fields!Field1.Value)) 
            or Not(IsNumeric(Fields!Field2.Value)), 
        0, 
        (Fields!Field1.Value/Fields!Field2.Value)*100
    )


    =Switch(
            Fields!Field1.Value = 0 or Fields!Fields.Value = 0, 0,
            IsNumeric(Fields!Field1.Value) or IsNumeric(Fields!Fields.Value), (Fields!Field1.Value/Fields!Fields.Value)*100
    )

这两个仍然抛出错误。即使if语句为真,似乎仍然会评估else条件

如果我将代码更改为仅为if和else打印X或Y,那么它可以工作 - 所以if语句中没有错误

这对我来说太可笑了

请告诉我我做错了什么?当if为真时,我无法相信语言会评估其他

修改

所以似乎评估了else条件。那么你如何绕过零误差的潜在鸿沟呢?

以下是答案: http://www.sqlservercentral.com/Forums/Topic442497-150-1.aspx#bm1115960

另一种选择(特别是如果你有一个包含许多表达式的报告可能会导致零除的情况,那就是使用自定义代码功能。

在“报告属性”的“代码”选项卡/窗口中,输入以下内容:

Public Function DivideBy(ByVal Exp1, ByVal Exp2)
If Exp2 = 0 Then
DivideBy = 0
Else : DivideBy = Exp1 / Exp2
End If
End Function

然后插入表达式 = code.DivideBy(场!ToBeDivided.Value,场!DividingBy.Value) 进入任何有可能被零问题分割的细胞。

5 个答案:

答案 0 :(得分:7)

是的,IIf函数的真假部分都得到了评估:

http://en.wikipedia.org/wiki/IIf#Side_Effects

  

副作用
  IIf的另一个问题是因为它是一个图书馆   function:与C派生的条件运算符不同,都是truepart和   无论实际是哪一个,都将评估falsepart   回。请考虑以下示例:

value = 10 
result = IIf(value = 10, TrueFunction, FalseFunction)
     

虽然TrueFunction是要调用的函数,但是IIf会   导致TrueFunction和FalseFunction都被执行。

     

还要考虑这个:

a = 10 
b = 0 
result = IIf(b <> 0, a / b, 0) 
     

而程序员   打算通过执行除零来避免引发错误,   只要b为零,就会发生错误。这是因为   代码段中的代码将被理解为

a = 10 b = 0
_temp1 = a / b ' Error if b = 0
_temp2 = 0
_temp3 = b <> 0 result = IIf(_temp3, _temp1 , _temp2) 
     

这个问题       IIf()调用没有条件运算符那么有用。要解决   这个问题,微软开发人员曾考虑过将IIf转换为   内在的功能;如果发生这种情况,编译器就会发生   能够通过替换来执行类型推断和短路   使用内联代码进行函数调用。

答案 1 :(得分:6)

Iif()Switch()都是函数调用,因此将评估传递给它们的所有参数。他们没有短路的能力。

答案 2 :(得分:3)

IIF是一个函数,在评估函数本身之前,会对函数的所有参数进行求值。

要防止出现此问题,您需要使用完整的If/Else语句。

另外相关的是,如果您习惯于对布尔表达式进行短路评估(例如C语言中的&&),则需要在VB中使用AndAlsoOrElse .NET。

答案 3 :(得分:0)

对于VB中的IIF语句,我认为无论初始条件如何,都会对所有内容进行评估。这是必须在IIF声明中解决的问题。

在第二个声明中,第一个IIF声明中的Fields!Field**2**.Value变为Fields!Field**s**.Value。由于.Value Fields!Fields如果{{1}}什么都不是

,那么该语句中的错误可能会失败

答案 4 :(得分:0)

我试图在RS 2005中重现此错误,但我不能!我采用了以下数据集:

select 5 as field1, 0 as field2
union
select 10 as field1, 5 as field2
union
select null as field1, 5 as field2
union 
select 3 as field1, null as field2
union 
select null as field1, null as field2
union 
select 0 as field1, null as field2
union
 select null as field1,  0 as field2
union
 select 11 as field1, 10 as field2
union
 select PI() as field1, 0 as field2
union
select PI() as field1, PI() as field2

并使用你的表达式,Jon Egerton在交换机中进行了修正。然后我做了一个纯粹的未经检查的师。

你的表达都有效,即使我除以0,我得到“无限”或“南”,但不是#Error。

如果用1/0替换除法,会发生什么。你得到#Error还是得到Infinity?

Report Preview