Мы только что перевели нашу БД с 9i на 10G
(Да .. лучше поздно, чем никогда и Нет - переход на 11g в настоящее время не вариант: -))
Подробности моей базы данных Oracle 10G: -
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.
Я искал другие вопросы SO, связанные с rownum, но не смог найти ничего похожего.
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
См. Строки, отмеченные между *** в самом внутреннем подзапросе.
Если я прокомментирую эту строку из моего запроса, запрос будет работать нормально.
И PEM.ENDORSEMENT_STATUS = 'POST'
Если я прокомментирую эту строку из моего запроса, а все остальное останется неизменным по сравнению с оригиналом, запрос также будет работать нормально
заказ по 1 ASC
Более ранние точки, относящиеся к 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
, затем результаты извлекаются, как и ожидалось.
ПЛАН для этого запроса без заказа ниже
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)
Обратите внимание, что единственное реальное различие между этими двумя планами состоит в том, что тот, который не работает, имеет следующие два дополнительных шага после шага 3, так как эти шаги отсутствуют в запросе без заказа по - что работает нормально.
Как и ожидалось, шаг 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)