継承したアプリケーションで、次のようなクエリに遭遇しました。
Select *
From foo
where
1 <> 1
私がそれを解析すると、何も返されない1 <> 1
はずです( false と評価されるはずです)。ただし、(少なくとも私の Oracle ボックスでは) 内のすべての完全なリストが返されfoo
ます。MSAccess/Jet と MSSQL で同じことを試すと、期待どおりの動作が得られます。Oracle ではなぜ違うのでしょうか (また、元の開発者がこれをやりたいと思ったのはなぜですか)?
注: "where 1 = 1" を使用する際の + と - についての迷信を見たことがありますが、それによってテーブル全体がスキャンされます。しかし、これは元の開発者が意図していたものではないと思います。
小さな更新:
この場合foo
はビューです。実際のテーブルで同じことを試してみると、期待どおりの結果が得られます (行はありません)。
更新 2:
ウサギの穴のさらに下のコードをたどり、フィールド/列名を取得しようとしているだけだと判断しました。完全なレコードセットを返す理由については、まだ途方に暮れています。ただし、ビューのみ。
文字通り、彼はクエリを文字列で作成し、それを別の関数に渡して変更せずに実行しています。
'VB6
strSQL = "SELECT * FROM " & strTableName & " WHERE 1 <> 1"
この場合、strTableName にはビューの名前が含まれます。
更新 3:
参考までに、これは私が問題を抱えているビューの 1 つです (フィールド/テーブル/スキーマ名を変更しました)。
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のselectの列名)は、Oracleに空のセットを返すように説得するようです。これは長期的な解決策ですが、短期的な解決策ではありません (コードの変更と再デプロイは主要な PITA です)。DB 側にほとんど知られていない設定があるか、この奇妙な動作の原因であるビューに何か問題があることを願っています。