当前位置: 首页 > 面试题库 >

为什么查询中的“这里1 <> 1”会返回所有行?

翁宏茂
2023-03-14
问题内容

我在继承的应用程序中遇到了如下查询:

Select *
From foo
where
    1 <> 1

正如我解析的那样,它应该不返回任何内容(1 <> 1应评估为false,正确)。但是(至少在我的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上的select中的某些列名称)似乎使Oracle相信我可以将空集还给我。这是一个长期解决方案,而不是短期解决方案(更改代码并重新部署是主要的PITA)。我希望在数据库方面有一个鲜为人知的设置,或者在视图中出了一些问题,这是造成这种奇怪行为的原因。


问题答案:

在Oracle优化器的视图合并代码中,它肯定看起来像是个错误。我敢打赌,您只能通过包含外部联接的视图来获得此效果。您ORDER BY可以解决它,因为它实际上会强制NO_MERGE视图。

但是,我不会在视图中放置一个ORDER BY或一个NO_MERGE提示,因为(取决于您的数据量)它可能会降低使用该视图的其他查询的性能。您应该在外部查询中添加一个no_merge提示:

Select /*+ NO_MERGE(foo) */ *
From foo
where
    1 <> 1

您还应该在Oracle支持下提高SR,因为这绝对是一个错误。该查询永远不应该返回任何行,无论您从中选择什么内容,或者内部有多复杂。永远不能。

我无法复制它,因此它可能已在我使用的版本中修复。您正在使用的数据库版本是什么?



 类似资料:
  • 问题内容: 我正在经历一些正在维护的查询,并且程序员向我输入了“似乎1 = 1”的查询,这些查询似乎总是评估为true。 这有好处吗? 这个问题不是这个问题的答案。 子句: 没有编程或if语句将an和推入其中。直接查询。 如果您可以取消关闭它,我想知道是否有一个目的,以便在不需要时可以重写并删除1 = 1。 问题答案: 它是动态查询吗?有时在基于可选参数构建动态查询时很有用。

  • 问题内容: 我正在运行程序 我得到的输出是。 我不明白这条线 子女的父母的PID为1 应该是3071? 问题答案: 因为在孩子要求其父母的pid之前,父进程已完成。 进程完成后,其所有子级都将重新分配为init进程的子级,其pid为1。 尝试使用父母的代码来等待孩子执行。然后,它应该会按预期工作。

  • 问题内容: 在下面的程序中,你可以看到.5除以外的每个值都略小于四舍五入的值0.5。 版画 我正在使用Java 6 update 31。 问题答案: 摘要 在Java 6(可能更早)中,实现为。1 这是一个规范错误,恰恰是这种病理情况。2 Java 7不再强制执行此无效的实现。3 问题 0.5 + 0.499999999999999999994的双精度正好为1: 这是因为0.49999999999

  • 问题内容: 为什么此代码有时返回1E + 1,而对于其他输入(例如17)却没有以科学计数法打印输出? 问题答案: 使用bigDecimal.toPlainString(): 输出:

  • 在R中,返回FALSE和返回“numeric”,而返回TRUE和返回“integer”。为什么不返回true? 要确定x1是否包含整数值,我需要使用。有更简单的方法吗? 可以返回数组,例如有序因子。不应该返回c(“numeric”,“integer”)吗?

  • 我不知道当我在Mysql中运行查询时,会出现此错误。 #1242-子查询返回超过1行 谁能帮我解决这个问题?