在一个较大的项目中,我正在将数十个查询从Microsoft Office Access数据库(MDB)迁移到Oracle。
虽然我能够理解几乎所有可以在Access中编写的疯狂构造,但我在单个构建中失败了。
(简化)查询是:
SELECT *
FROM SomeTable
WHERE
Left(SomeField,3)=IIf(SomeParameter="GYM",Mid(SomeField,2,1)<>'0')
AND
Left(SomeField,3)=IIf(SomeParameter="GYM",Left(SomeField,3)<>'110')
此处,SomeField
是表格中的一列,SomeParameter
是查询的输入。
我不明白的是WHERE
部分:
else
声明中缺少IIF
部分?<>
操作的结果(即布尔值)进行比较?由于它在Access中成功运行,因此查询 有效。我甚至无法生成一些将通过比较的测试数据。
有关如何解释比较的任何提示?
答案 0 :(得分:2)
正如我在评论中所说,我分享了原始提问者对这个表达的困惑:
WHERE Left(SomeField,3)=IIf(SomeParameter="GYM",Mid(SomeField,2,1)<>'0')
让我们打开那个:
如果SomeParameter =“GYM”返回:
Mid(SomeField,2,1)<>'0'
这是在SomeField中对字符串“0”测试第二个字符,因此这意味着设计设计不合理的字段,因为该字段中的第二个字符具有独立含义。对于第二个字符不是0的所有值,这将返回true。
无论它返回什么(在False情况下为True或Null),它将与此字符串进行比较:
Left(SomeField,3)
如果SomeField的前三个字符碰巧是“是”那么它可能会产生真正的比较,因为在Access / Jet / ACE中,Yes和True和-1都是等价的,并且字符串表示可以隐式裹挟。
因此,这可能会返回如下所示的行:
SomeParameter SomeField
GYM Yes sir, that's my baby
然而,它确实没有多大意义,因为SomeField的测试是循环的。也就是说,你要比较一个实例中字段的前3个字符,其中真正的比较只能在前三个字符为“是”时发生,但你又将前三个字符与测试进行比较对于同一字段中的第二个字符是否&lt;&gt; 0.在前三个字符为“是”的所有情况下,第二个字符肯定不是“0”,所以你真的只需要测试前三个字符的值。
我投票支持原始开发者的无能。
答案 1 :(得分:1)
来自http://www.techonthenet.com/access/functions/advanced/iif.php
iif ( condition, value_if_true, value_if_false )
所以它就像是C ++ / C#等中的三元运算符。看起来他们不关心值是否为假。
另外,我想知道他们是不是搞砸了逻辑:)
修改强> 我相信如果没有指定错误条件,它会返回Null。
在这种情况下,看起来他们将字段设置为true(当条件&lt;&gt;为真时)或null,当它为false时。
对我来说似乎是一个奇怪的设计
答案 2 :(得分:1)
如果SomeParameter<>"GYM"
,第一个iif将返回Null,否则它将返回True
或False
,具体取决于表达式Mid(SomeField,2,1)<>'0'
的布尔值。
第二个iif的逻辑相同。
让我猜一下......这是金融业的疑问吗? ; - )