最近、DB を 9i から 10G に移行しました (はい..遅いほうがいいです。いいえ - 11g への移行は現在オプションではありません :-))
私のOracle 10G DBの詳細は次のとおりです:-
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
その動き以来、私は非常に奇妙な問題に直面しています。9i で問題なく動作していたクエリが、10G では動作しません。
rownum に関連する他の SO の質問を検索しましたが、似たようなものを実際に見つけることができませんでした。
SQLクエリは:-
SELECT * FROM
( SELECT field1, field2 , field3, field4, field5, field6, field7, to_char(rownum) field8
FROM
( SELECT
field1,
field2,
field3,
field4,
field5,
field6,
field7,
''
FROM
.......REST OF MY COMPLEX INNER QUERY
)
)
WHERE field8 BETWEEN 21 AND 30;
基本的に、21 / 30 は、ページネーションのためにクエリに渡されるレコードのインデックスである数値であり、9i では、このクエリは期待どおりに機能し、指定されたデータ セットのみを返します。
ただし、10G では、この同じクエリはまったく機能せず、常に 0 レコードが返されます。
クエリのrownum関連部分にコメントすると:-
to_char(rownum) field8 and
WHERE field8 BETWEEN 21 AND 30;
次に、結果セット全体を取得します。それは素晴らしいことです。しかし、私の意図はrownumを使用してページネーションを行うことであるため、目的全体が無効になります。
このクエリが 10G で機能しなくなった理由を知っている人はいますか? rownum 実装の更新を調べてみましたが、実際に役立つものは何も見つかりませんでした。
編集:- デバッグを行っているときに、意味をなさないものに遭遇しました。それなしでは説明できないので、以下にクエリ全体を入れています。
SELECT * FROM
( SELECT field1, field2 , field3, field4, field5, field6, field7, to_char(rownum) field8 from
( SELECT PM.POLICY_NO field1
,PM.INSURED_CODE field2
,PM.INSURED_NAME field3
,TO_CHAR(PM.POLICY_EFFECTIVE_DATE,'DD/MM/YYYY') field4
,TO_CHAR(PM.POLICY_EXPIRATION_DATE,'DD/MM/YYYY') field5
,'' field6
,'' field7
,'' field8
FROM POLICY_MAIN PM
,POLICY_ENDORSEMENT_MAIN PEM
,MASTER_UW_LOB_CLASS MAS
WHERE PM.POLICY_NO = PEM.POLICY_NO
AND PM.POLICY_NO LIKE UPPER('%%')
AND PM.INSURED_CODE LIKE UPPER('%%')
AND PM.SOURCE_OF_BUSINESS LIKE UPPER('%%')
AND PM.POLICY_TYPE IS NULL
AND PM.POLICY_STATUS = 'POST'
AND PM.POLICY_LOB = MAS.UW_LOB_CODE
AND MAS.UW_CLASS_CODE LIKE UPPER('AUTO')
AND PEM.POLICY_ENDORSEMENT_NO =
(SELECT MAX(PEM2.POLICY_ENDORSEMENT_NO)
FROM POLICY_ENDORSEMENT_MAIN PEM2
WHERE PEM.POLICY_NO = PEM2.POLICY_NO
***AND PEM.ENDORSEMENT_STATUS = 'POST'***
)
***order by 1 ASC***
)
)
WHERE field8 BETWEEN 21 AND 40
最も内側のサブクエリの *** で囲まれた行を参照してください。
クエリからこの行にコメントを付けると、クエリは正常に機能します。
AND PEM.ENDORSEMENT_STATUS = '投稿'
クエリからこの行にコメントを付けても、他のすべてが元から変更されていない場合、クエリも正常に機能します
1ASCで注文
rownum に関連する以前のポイントは引き続き当てはまりますが、これらの行を個別にコメントすると、rownum が無関係になり、クエリ全体が正常に機能するようになります (結果が論理的に異なるという事実を除いて)。
私は混乱しています。控えめに言って!!!
編集2:
上記のクエリの実行プランを追加する
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=19 Card=1 Bytes=114)
1 0 VIEW (Cost=19 Card=1 Bytes=114)
2 1 COUNT
3 2 FILTER
4 3 VIEW (Cost=17 Card=1 Bytes=128)
5 4 SORT (ORDER BY) (Cost=17 Card=1 Bytes=130)
6 5 TABLE ACCESS (BY INDEX ROWID) OF 'POLICY_ENDORSEMENT_MAIN' (TABLE) (Cost=2 Card=1 Bytes=39)
7 6 NESTED LOOPS (Cost=16 Card=1 Bytes=130)
8 7 NESTED LOOPS (Cost=14 Card=1 Bytes=91)
9 8 TABLE ACCESS (FULL) OF 'POLICY_MAIN' (TABLE) (Cost=14 Card=1 Bytes=82)
10 8 INDEX (UNIQUE SCAN) OF 'PK_MASTER_UW_LOB_CLASS' (INDEX (UNIQUE)) (Cost=0 Card=1 Bytes=9)
11 7 INDEX (RANGE SCAN) OF 'PK_POLICY_ENDORSEMENT_MAIN' (INDEX (UNIQUE)) (Cost=1 Card=1)
12 3 SORT (AGGREGATE)
13 12 FILTER
14 13 INDEX (RANGE SCAN) OF 'PK_POLICY_ENDORSEMENT_MAIN' (INDEX (UNIQUE)) (Cost=2 Card=2 Bytes=68)
編集3:
上記とまったく同じクエリですが、
ORDER BY 1 ASC
節の場合、結果は期待どおりに取得されます。order by を使用しないこのクエリの PLAN は次のとおりです。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=18 Card=1 Bytes=114)
1 0 VIEW (Cost=18 Card=1 Bytes=114)
2 1 COUNT
3 2 FILTER
4 3 TABLE ACCESS (BY INDEX ROWID) OF 'POLICY_ENDORSEMENT_MAIN' (TABLE) (Cost=2 Card=1 Bytes=39)
5 4 NESTED LOOPS (Cost=16 Card=1 Bytes=130)
6 5 NESTED LOOPS (Cost=14 Card=1 Bytes=91)
7 6 TABLE ACCESS (FULL) OF 'POLICY_MAIN' (TABLE) (Cost=14 Card=1 Bytes=82)
8 6 INDEX (UNIQUE SCAN) OF 'PK_MASTER_UW_LOB_CLASS' (INDEX (UNIQUE)) (Cost=0 Card=1 Bytes=9)
9 5 INDEX (RANGE SCAN) OF 'PK_POLICY_ENDORSEMENT_MAIN' (INDEX (UNIQUE)) (Cost=1 Card=1)
10 3 SORT (AGGREGATE)
11 10 FILTER
12 11 INDEX (RANGE SCAN) OF 'PK_POLICY_ENDORSEMENT_MAIN' (INDEX (UNIQUE)) (Cost=2 Card=2 Bytes=68)
2 つのプランの唯一の実際の違いは、機能していないプランにはステップ 3 の後に次の 2 つの追加ステップがあることです。これらのステップは、順序付けなしではクエリに存在しないため、正常に機能しています。
予想どおり、ステップ 5 はデータの順序付けが行われるステップです。
4 3 VIEW (Cost=17 Card=1 Bytes=128)
5 4 SORT (ORDER BY) (Cost=17 Card=1 Bytes=130)
ステップ 4 は、順序付けのために追加のビューが作成されている可能性があるようです。
これがrownumロジックの動作を妨げる理由は、私がまだ把握しようとしているものです。
どんな助けでも大歓迎です!!
編集 4 - 9i 環境からの元のクエリ プラン
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 VIEW
2 1 COUNT
3 2 VIEW
4 3 SORT (ORDER BY)
5 4 FILTER
6 5 TABLE ACCESS (BY INDEX ROWID) OF 'POLICY_MAIN'
7 6 NESTED LOOPS
8 7 NESTED LOOPS
9 8 TABLE ACCESS (FULL) OF 'POLICY_ENDORSEMENT_MAIN'
10 8 INDEX (RANGE SCAN) OF 'PK_MASTER_UW_LOB_CLASS' (UNIQUE)
11 7 INDEX (RANGE SCAN) OF 'PK_POLICY_MAIN' (UNIQUE)
12 5 SORT (AGGREGATE)
13 12 FILTER
14 13 INDEX (RANGE SCAN) OF 'PK_POLICY_ENDORSEMENT_MAIN' (UNIQUE)