Проблема подзапроса в Oracle 10g
Следующий запрос работает в Oracle 10.2.0.1.0 в Windows, но не работает в Oracle 10.2.0.2.0 в Linux.
Отчет об ошибке: Ошибка SQL: ORA-00904: "T"."AUDIT_USECS": неверный идентификатор 00904. 00000 - "%s: неверный идентификатор"
Это работает после того, как я удаляю подзапрос. Я обнаружил, что если использовать поля T в подзапросе, то возникает ошибка. Это говорит о том, что подзапрос не может получить доступ к полям основного запроса?
В чем проблема? Как я могу заставить его работать на Oracle на Linux? Спасибо!
CREATE TABLE AUDITHISTORY(
CASENUM numeric(20, 0) NOT NULL,
AUDIT_DATE date NOT NULL,
USER_NAME varchar(255) NULL,
AUDIT_USECS numeric(6, 0) NOT NULL,
TYPE_ID INT NOT NULL )
Запрос:
SELECT T.CASENUM,
T.USER_NAME,
T.AUDIT_DATE AS STARTED,
(SELECT *
FROM (SELECT S.AUDIT_DATE
FROM AUDITHISTORY S
WHERE S.CASENUM=T.CASENUM AND TYPE_ID=2
AND S.USER_NAME=T.USER_NAME
AND (S.AUDIT_DATE > T.AUDIT_DATE OR (S.AUDIT_DATE = T.AUDIT_DATE AND S.AUDIT_USECS > T.AUDIT_USECS))
ORDER BY S.AUDIT_DATE ASC,S.AUDIT_USECS ASC
) WHERE rownum <= 1) AS ENDED
FROM AUDITHISTORY T WHERE TYPE_ID=1
БАННЕР
Oracle Database 10g Enterprise Edition, выпуск 10.2.0.1.0 - Prod PL/SQL, выпуск 10.2.0.1.0 - Производство
CORE 10.2.0.1.0 Производство
TNS для 32-битной Windows: версия 10.2.0.1.0 - производство
NLSRTL Версия 10.2.0.1.0 - Производство
БАННЕР
Oracle Database 10g Enterprise Edition, выпуск 10.2.0.2.0 - Prod PL/SQL, выпуск 10.2.0.2.0 - Производство
CORE 10.2.0.2.0 Производство
TNS для Linux: версия 10.2.0.2.0 - производство
NLSRTL Версия 10.2.0.2.0 - Производство
2 ответа
Это ошибка!!! Проверьте эту ссылку http://forums.oracle.com/forums/thread.jspa?messageID=4023215?
или http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1853075500346799932
Это ошибка только в Соединении с Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Следующий скрипт работает:
SQL> select * from AUDITHISTORY;
CASENUM AUDIT_DAT USER_NAME AUDIT_USECS TYPE_ID
10 12-MAR-10 USER 100 1
10 14-MAR-10 USER 100 2
10 16-MAR-10 USER 100 2
SQL> SELECT T.CASENUM,
2 T.USER_NAME,
3 T.AUDIT_DATE AS STARTED,
4 (
5 SELECT max(S.AUDIT_DATE) keep (dense_rank first order by S.AUDIT_DATE ASC,S.AUDIT_USECS ASC)
6 from AUDITHISTORY S
7 WHERE S.CASENUM=T.CASENUM AND TYPE_ID=2
8 AND S.USER_NAME=T.USER_NAME
9 AND (
10 S.AUDIT_DATE > T.AUDIT_DATE OR (
11 S.AUDIT_DATE = T.AUDIT_DATE
12 AND S.AUDIT_USECS > T.AUDIT_USECS
13 )
14 )
15 ) as ended
16 FROM AUDITHISTORY T WHERE TYPE_ID=1;
CASENUM USER_NAME НАЧАЛО ЗАВЕРШЕНО
10 USER 12-MAR-10 14-MAR-10
Для получения дополнительной информации: http://forums.oracle.com/forums/thread.jspa?messageID=4160559
Я считаю удивительным, что это работает где угодно. Вы используете псевдоним T во встроенном представлении, но он определен только во внешнем выборе.
ОБНОВЛЕНИЕ после просмотра всей информации, указанной в комментариях и других ответах:
- Тот факт, что он действительно работает в одной / некоторой версии, был ошибкой в этой версии, по словам Тома Кайта, который является достаточно надежным источником информации такого рода: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1853075500346799932
- Здесь работают две вещи:
- При использовании подвыбора в качестве встроенного представления вы не можете ссылаться на что-либо из внешнего выбора. См. Последний пункт в этом документе: http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14200/queries007.htm
- В других случаях использования подвыборов (в предложении select или в предложении where) вы можете ссылаться на вещи из внешнего выбора, но только из непосредственно включающего выбора. (Лично я считаю, что это глупое ограничение, но я думаю, что никто из комитетов ANSI SQL не заботится о моем мнении)
Предполагая, что все это правильно, это утверждение может работать:
SELECT T.CASENUM,
T.USER_NAME,
T.AUDIT_DATE AS STARTED,
(SELECT *
FROM (SELECT S.AUDIT_DATE
FROM AUDITHISTORY S
WHERE S.CASENUM=T.CASENUM AND TYPE_ID=2
AND S.USER_NAME=T.USER_NAME
ORDER BY S.AUDIT_DATE ASC,S.AUDIT_USECS ASC
) R WHERE (S.AUDIT_DATE > T.AUDIT_DATE OR (S.AUDIT_DATE = T.AUDIT_DATE AND S.AUDIT_USECS > T.AUDIT_USECS))
AND rownum <= 1) AS ENDED
FROM AUDITHISTORY T WHERE TYPE_ID=1