17

次のクエリを実行すると、一致するレコードが 11 あるにもかかわらず、書き込まれたとおりに返されるレコードはありません。ただし、6 行目と 9 行目の括弧を削除すると、11 件すべ​​てのレコードが期待どおりに返されます。

1  select obj_id, obj_title, UI_DISPLAYNAME
2  from PITS_OBJECT 
3  LEFT OUTER JOIN ui_displayname_view ON obj_create_ui_id = UI_ID  
4  where
5  /* w/ parens, no results, w/o parens, expected results */
6  (
7     Upper( UI_DISPLAYNAME ) LIKE Upper( '%smith%' )  
8     OR Upper( OBJ_TITLE ) LIKE Upper( '%smith%' ) 
9  )
10 /* end w/ parents, no results.... */
11 AND OBJ_ID IN (select obj_id from PITS_OBJECT where 
12     (UPPER( OBJ_TITLE ) LIKE UPPER( '%smith%' )) 
13     AND obj_id in( select sa_obj_id as obj_id from security_access 
14         where sa_type_id = 494 
15         and sa_usrgrp_id = 35
16         and sa_usrgrp_type_id = 230 
17         union 
18         select sa_obj_id from security_access 
19         where sa_type_id = 494 
20         and sa_usrgrp_type_id = 231 
21         and sa_usrgrp_id in ( select ug_gi_id from user_group where ug_ui_id = 35)) )

なぜこれが問題になるのでしょうか?ORステートメントは、どちらか一方が真でなければならないことを意味しませんか? ここで何が欠けていますか?

4

5 に答える 5

19

3 つの言葉: 操作の順序。数学で学んだように、括弧を使用して強制しない限り、特定の演算子が他の演算子よりも優先されます (乗算は加算よりも優先されるなど)。この場合、ANDは よりも優先されORます。

独自の括弧を追加しないと、WHERE句は次のように評価されます。

Upper( UI_DISPLAYNAME ) LIKE Upper( '%smith%' )
OR 
(Upper( OBJ_TITLE ) LIKE Upper( '%smith%' ) 
    AND OBJ_ID IN (select obj_id from PITS_OBJECT where 
    ...)

しかし、これらの括弧を手動で追加すると、ORが最初に評価されるように強制されます。

(Upper( UI_DISPLAYNAME ) LIKE Upper( '%smith%' )
    OR Upper( OBJ_TITLE ) LIKE Upper( '%smith%' ))
AND OBJ_ID IN (select obj_id from PITS_OBJECT where 
...

編集:なぜあなたがより多くのデータを取り戻しているのかについてのあなたの質問に直接答える必要があります. その理由は、括弧がないと、7 行目が true であることが判明した場合に、エンジンがチェックを省略してしまうからです。Upper( UI_DISPLAYNAME ) LIKE Upper( '%smith%' )つまり、他の基準に関係なく、 のすべてのレコードが含まれます。

これらの括弧を追加すると、ロジックが変わります。レコード where が含まれUpper( UI_DISPLAYNAME ) LIKE Upper( '%smith%' ) OR Upper( OBJ_TITLE ) LIKE Upper( '%smith%' )、レコード ALSO が 12 行目から始まる内部選択を満たしていることが確認されます。これらの余分なレコードは、その内部選択の基準を満たしていないため表示されません。

于 2011-11-17T18:44:56.110 に答える
16

where句は現在、次のようになっています。

(A || B) && C && D

括弧なしでは、次のようになります。

A || B && C && D

これはに相当します

A || (B && (C && D))
于 2011-11-17T18:47:14.090 に答える
2

これはANDandOR演算子の優先順位に関係しています。AND優先度が高くなります。 http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/conditions001.htm#i1034834

于 2011-11-17T18:44:07.377 に答える
0

これが基本的な操作順序です。括弧は、他のすべてがテストされる前にすべてがテストされることを意味します。括弧内の項目を評価した後に返される値は、残りの項目を評価するために使用されます。AND は OR よりも優先されるため、括弧によって SQL は最初に OR を評価します。

于 2011-11-17T18:45:11.727 に答える
0

where ステートメントを変更して Upper( OBJ_TITLE ) LIKE Upper( '%smith%' )、次の AND に関係なく、true であるレコードを常に返すようにしたためです。

于 2011-11-17T18:42:47.530 に答える