回答

收藏

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

技术问答 技术问答 124 人阅读 | 0 人回复 | 2023-09-13

我在继承的应用程序中遇到了如下查询:/ n3 ~8 f; y* Q+ i' P5 N
Select *8 c9 _4 g7 X# U+ v6 \
From foo
, p; W! J# y: a; A1 Wwhere
  b" \) W8 n7 @  ^8 O    1  1
; Z, Z4 m: P3 q' U% f正如我解析的那样,它应该不返回任何内容(1 ) N4 k+ n* d4 U- J7 K$ {
1应评估为false,正确)。但是(至少在我的Oracle机器上),它返回了中所有内容的完整列表foo。当我在MSAccess /1 ]* R! {1 {) {, p8 `
Jet和MSSQL中尝试相同的操作时,我得到了预期的行为。为什么对Oracle有所不同(为什么原始开发人员要这样做)?) C, `# U  n; H+ Q3 C
注意:我对使用“ where 1 = 1”的+ s和-s有一些迷信,它引起了全表扫描。但是我不认为这是原始开发人员的意图。
) m0 U- k' X4 s/ F  ?" N. b( s" H5 @小更新:+ r  W+ @+ ?5 ?5 C' P7 b
在这种情况下foo是一个视图。当我在实际的表上尝试相同的操作时,我得到了期望的结果(无行)。
& e! E; ^; P3 D8 F, U$ X  d更新2:9 ^: J) [4 R2 L
我一直在兔子洞后面跟踪代码,并确定他正在做的所有事情都是试图获取字段/列的名称。我仍然不知道为什么它要返回完整的记录集。但仅适用于视图。
6 N" y9 l- u' s8 J/ O4 x) D从字面上看,他是在字符串中构建查询,然后将其传递给另一个函数以不更改地执行。- n9 `; b1 |5 `1 L/ r' ^& E
'VB6
6 a) `( m7 A$ ^strSQL = "SELECT * FROM " & strTableName & " WHERE 1  1"  U2 |6 F7 _# @* ^3 H
在这种情况下,strTableName包含视图的名称。; r' E- \& T; R0 B
更新3:
' q: I: E( @% k4 c$ w2 B作为参考,这是我遇到的问题之一(我更改了字段/表/模式名称)
  Y' s6 c' T  qCREATE OR REPLACE FORCE VIEW scott.foo (field1,8 ]* Q6 u/ ~7 l+ }/ j  ]
                                        field2,7 V: \7 R7 z# _1 g7 L5 Q$ T& C
                                        field4,
' b& [% p+ k! m. Q) ]; A" f/ v                                        field5,# r. u  }! a9 p
                                        field12,
0 g( j. Z* k" M6 W/ S4 g! K                                        field8,
3 [, L7 X7 Q! q                                        field6,
1 p, \5 [( Y2 M  |6 f+ F                                        field7," l. F% V" c; A/ i
                                        field16,
* `4 C5 ^: b, Z                                        field11,( Q0 c% [. y2 n! ^7 O2 o
                                        field13,4 ]& a. `1 X+ s, C$ E
                                        field14,
5 ]* H5 E! o9 N4 a* K                                        field15,3 z! Y2 g5 ^6 X) H" y7 L
                                        field17; `2 \- [2 f( n3 A0 Z
                                       )4 Z0 S2 `! X) M
AS  U! O( J( m$ j7 |" u7 G
   SELECT   bar.field1,
5 r$ u9 i" c, W            bar.field2,/ c. |* O9 n3 h6 {3 u
            DECODE
" @) S. W; T  e% h) D! Q# {4 `! M# a               (yadda.field9, NULL, 'N',
% V% k. Y- q# O+ m                DECODE (yadda.field3, NULL, 'Y', 'N')
* |2 }) E3 G& N% |8 @& K               ) AS field4,
8 @' I5 L7 h2 }0 X            bar.field5,
& B* `, `  s2 m            snafu.field6," J9 W) h  {4 N9 y8 w  V
            DECODE% }4 o# m. x, @1 s8 P
                (snafu.field6,6 m# i# J5 b( |6 s* ?
                 NULL,0 E  \4 O0 H5 l
                bar.field8,# M" A6 U3 P6 m3 g7 W0 N
                   bar.field84 O. L2 r% p; L' V
                 - snafu.field6
- }% w% ~. @, P3 v9 w, T0 j1 N. R                ) AS field7," F0 P* [1 G- s+ M
            DECODE' U; u2 z6 z& C1 N
               (yadda.field10,/ F. _% w& r6 E1 y( ?
                NULL,
4 e* X5 n5 n# m) e  W1 W            bar.field12,7 X1 X0 f# j7 b  Y! A2 c" M7 Y. W
                yadda.field10
# s, m3 d* \* K$ p               ) AS field11,  t5 X8 R3 W8 o  I+ `) p' r3 I
            DECODE/ M- W4 N* Q+ E
               (SIGN (  yadda.field10 - bar.field12),) _; j2 P  B" u8 h0 A/ P4 V
                NULL, 'N', 1, 'N', 0, 'N', -1, 'Y'4 ]8 e9 E# X2 t7 z2 b! Y& D
               ) AS field13,
! b3 }8 K/ M* N5 I  i; h            bar.field14,
5 E3 u  B) g: B. S* W# ^            ADD_MONTHS* D2 y4 r0 S* G
               (DECODE (yadda.field10, NULL, bar.field12, yadda.field10
  [8 v  Q- e+ G" h# e2 J9 c# Q5 E                       ),- R) @! n" U8 V+ R
                bar.field14 * 120 v2 ~9 ]" u5 z
               ) AS field15,
8 g" R7 R. m% I       FROM clbuttic,
8 t3 f0 `2 S, v' x            bar,& p; a  _1 Q" Z9 G( B% n
            yadda,/ t6 `  o0 t2 Q9 j% E; `' s/ H1 ]; }
            snafu
  V8 C0 A  u, t1 [& ~      WHERE clbuttic.asset_type = bar.asset_type# _! m3 w% [; K: N( {
        AND bar.field16 = yadda.field9(+)% S  _8 o, ^1 L+ `+ i3 A; T
        AND bar.field1 = snafu.field1(+)
, v. T! ~% S7 z3 e: k9 A        AND (bar.field17 IS NULL)- B' ]7 G2 J# q" H* {
   ;
$ S" e( |' e8 Q9 [- F追加Order By
" \0 g/ M1 }0 {/ N1(或在foo上的select中的某些列名称)似乎使Oracle相信我可以将空集还给我。这是一个长期解决方案,而不是短期解决方案(更改代码并重新部署是主要的PITA)。我希望在数据库方面有一个鲜为人知的设置,或者在视图中出了一些问题,这是造成这种奇怪行为的原因。
* z( C: |. _1 P1 b* g* T. q               
2 ^, k. s# y: n' K) h" @解决方案:
5 S: v$ e; ~! Y: y; L7 b               
% r* g: @( v# h6 ^1 p5 p) R! g9 d  s; \
+ T) h) z2 y* i: G" @& C6 N) S
                在Oracle优化器的视图合并代码中,它肯定看起来像是个错误。我敢打赌,您只能通过包含外部联接的视图来获得此效果。您ORDER
# w# J1 c) ?$ i' }9 T7 K! ?. TBY可以解决它,因为它实际上会强制NO_MERGE视图。) N0 d& {& s2 y0 Y& Z' Y# m5 X9 R
但是,我不会在视图中放置一个ORDER) y" t1 }; P# r, _/ k+ z! m
BY或一个NO_MERGE提示,因为(取决于您的数据量)它可能会降低使用该视图的其他查询的性能。您应该在外部查询中添加一个no_merge提示:  w& ]& |5 @; A; n* [  h4 F
Select /*+ NO_MERGE(foo) */ *$ V* o* q0 f7 q' ~9 ?9 s6 x2 B
From foo! r3 j, z+ p- _8 x5 f; y
where
0 g& \, M7 l; f0 F# c" x$ ]    1  1+ m3 g& J: I, G6 _( B; P
您还应该在Oracle支持下提高SR,因为这绝对是一个错误。该查询永远不应该返回任何行,无论您从中选择什么内容,或者内部有多复杂。永远不能。
; r2 m" k0 x, O- ~( X0 f我无法复制它,因此它可能已在我使用的版本中修复。您正在使用的数据库版本是什么?
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则