我在继承的应用程序中遇到了一个查询,如下所示:
Select *
From foo
where
1 <> 1
当我解析它时,它应该什么都不返回(1 <> 1
应该评估为假,对)。但是(至少在我的 Oracle 机器上)它会返回一个完整的foo
. 当我在 MSAccess/Jet 和 MSSQL 中尝试同样的事情时,我得到了我期望的行为。为什么 Oracle 会有所不同(以及为什么最初的开发人员想要这样做)?
注意:我已经看到一些关于使用“where 1 = 1”的 +s 和 -s 的迷信,它会导致全表扫描;但我认为这不是原始开发人员的意图。
小更新:
在这种情况下foo
是一个视图。当我在一张实际的桌子上尝试同样的事情时,我得到了我所期望的(没有行)。
更新 2:
我已经在兔子洞中进一步跟踪代码,并确定他所做的只是试图获取字段/列名。我仍然不知道为什么它会返回完整的记录集。但仅限于意见。
从字面上看,他在字符串中构建查询并将其传递给另一个函数以原样执行。
'VB6
strSQL = "SELECT * FROM " & strTableName & " WHERE 1 <> 1"
在这种情况下,strTableName 包含视图的名称。
更新 3:
作为参考,这是我遇到问题的视图之一(我更改了字段/表/模式名称)
CREATE OR REPLACE FORCE VIEW scott.foo (field1,
field2,
field4,
field5,
field12,
field8,
field6,
field7,
field16,
field11,
field13,
field14,
field15,
field17
)
AS
SELECT bar.field1,
bar.field2,
DECODE
(yadda.field9, NULL, 'N',
DECODE (yadda.field3, NULL, 'Y', 'N')
) AS field4,
bar.field5,
snafu.field6,
DECODE
(snafu.field6,
NULL,
bar.field8,
bar.field8
- snafu.field6
) AS field7,
DECODE
(yadda.field10,
NULL,
bar.field12,
yadda.field10
) AS field11,
DECODE
(SIGN ( yadda.field10 - bar.field12),
NULL, 'N', 1, 'N', 0, 'N', -1, 'Y'
) AS field13,
bar.field14,
ADD_MONTHS
(DECODE (yadda.field10, NULL, bar.field12, yadda.field10
),
bar.field14 * 12
) AS field15,
FROM clbuttic,
bar,
yadda,
snafu
WHERE clbuttic.asset_type = bar.asset_type
AND bar.field16 = yadda.field9(+)
AND bar.field1 = snafu.field1(+)
AND (bar.field17 IS NULL)
;
附加Order By 1
(或 foo 上的选择中的某些列名)似乎说服 Oracle 将空集还给我。这是一个长期解决方案,但不是短期解决方案(更改代码和重新部署是主要的 PITA)。我希望数据库端有一个鲜为人知的设置,或者视图中有问题,这是导致这种奇怪行为的原因。