SQL-VB-即使if为真,它也会计算else吗?

SQL-VB-即使if为真,它也会计算else吗?,sql,sql-server-2005,reporting-services,Sql,Sql Server 2005,Reporting Services,我试图防止在我创建的报告中显示错误 当我除以两个数,其中一个是零时,就会发生这种情况 因此,在进行除法之前,我尝试使用if/switch语句检查2个数字中的任何一个是否为0: =IIf(Fields!Field1.Value = 0 or Fields!Field2.Value = 0 or Not(IsNumeric(Fields!Field1.Value)) or Not(IsNumeric(Fields!

我试图防止在我创建的报告中显示错误

当我除以两个数,其中一个是零时,就会发生这种情况

因此,在进行除法之前,我尝试使用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语句为true,else条件似乎仍然被计算

如果我将If和else的代码更改为只打印X或Y,那么它就工作了——因此If语句中没有错误

我觉得这很可笑

请告诉我我做错了什么?我不敢相信如果if为真,语言会对else进行评估

编辑

因此,似乎对else条件进行了评估。那么,如何绕过一个势能除以零的误差呢

以下是答案:

另一种选择(特别是如果您有一个包含许多表达式的报表,可能导致被零除的情况),就是使用自定义代码函数

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

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)
进入任何可能出现被零除问题的单元格。

是的,IIf函数的正确部分和错误部分都会得到评估:

副作用
IIf的另一个问题是因为它是一个库 函数:与C派生的条件运算符不同,truepart和 不管实际是哪一个零件,都将对该零件进行评估 返回。考虑下面的例子:

value = 10 
result = IIf(value = 10, TrueFunction, FalseFunction)
虽然TrueFunction是要调用的函数,但IIf将 使TrueFunction和FalseFunction同时执行

也考虑这一点:

a = 10 
b = 0 
result = IIf(b <> 0, a / b, 0) 
a=10
b=0
结果=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) 
a=10b=0
_如果b=0,则temp1=a/b'错误
_temp2=0
_temp3=b0结果=IIf(_temp3,_temp1,_temp2)
这一问题令人担忧 IIf()调用不如条件运算符有用。要解决 在这个问题上,微软开发人员曾考虑将IIf转换为 一个内在函数;如果发生这种情况,编译器将 能够通过更换 带有内联代码的函数调用


Iif()
Switch()
都是函数调用,因此传递给它们的任何参数都将被求值。它们没有短路的能力。

Iif
是一个函数,函数的所有参数在被求值之前都会被求值

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


如果您习惯于对布尔表达式的求值短路(例如C派生语言中的
&&
),则也与此相关你需要在VB.Net中使用
以及

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


在第二条语句中,第一条IIF语句中的
Fields!Field**2**.Value
已成为
Fields!Field**s**.Value
。该语句中的错误可能会因此而失败,因为
。如果
Fields!Fields
为空,则Value
将导致错误005,我不能!我获取了以下数据集:

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
用你的表达式,用乔恩·埃格顿的修正在开关上,然后我做了一个纯粹的无校验除法

你的两个表达式都有效,即使我除以0,我也得到“无穷大”或“Nan”,但不是#误差

如果你用1/0替换除法会发生什么?你得到的是#误差还是无穷大


wow-我很震惊。那么,防止被零除的最佳方法是什么呢?有没有其他方法可以用来防止被零除的错误?我不明白为什么你的
IIf()
正在产生
#错误
。您实际上只需要检查除数-
字段2.值
-无论如何。值可能是
?不,恐怕不是,这两个值显示在报告的其他位置,我可以看到其中一个是零,另一个是十进制数。而且,这两个值在这里也没有帮助-它们有助于阻止条件的后面部分求值,但这里的问题是结果的第二(else)部分正在求值。好的一点,我的意思是在正常IF语句的上下文中…:(没有-我只是手动更改了要发布在这里的字段名称以掩饰我们的公司名称-只是在soFair中做了一个输入错误。我不会说这是一个不可靠的命名约定!;-)