SQL-VB-即使if为真,它也会计算else吗?
我试图防止在我创建的报告中显示错误 当我除以两个数,其中一个是零时,就会发生这种情况 因此,在进行除法之前,我尝试使用if/switch语句检查2个数字中的任何一个是否为0: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!
=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中做了一个输入错误。我不会说这是一个不可靠的命名约定!;-)