Oracle, кажется, имеет алгоритм, который включает в себя удаление пробелов и использование заглавных букв. Однако полученный в результате псевдоним столбца, который он создает для проекции, похоже, не подчиняется обычным правилам для идентификаторов, которым мы с вами подчиняемся. По этой причине я не думаю, что вам будет полезно попытаться продублировать внутренний алгоритм Oracle для всего, что вы пытаетесь выполнить sh - потому что даже если вы сделаете это идеально, вы не сможете гарантированно получится идентификатор, который вы можете использовать.
Возьмите этот пример:
SELECT * FROM
(
SELECT OWNER, COUNT(distinct object_name || 'This is a really long string in my expression, don''t you think? Actually, it''s really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, ridiculously long!')
FROM DBA_OBJECTS
WHERE ROWNUM <= 100
GROUP BY OWNER )
ORDER BY 2 DESC;
... для читателей, которые не удосужились прокрутить правильно, выражение начинается с COUNT(distinct object_name...
действительно, очень долго.
Давайте запустим это и посмотрим, что Oracle использует для проекции внутреннего запроса.
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| OWNER | COUNT(DISTINCTOBJECT_NAME||'THISISAREALLYLONGSTRINGINMYEXPRESSION,DON''TYOUTHINK?ACTUALLY,IT''SREALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| SYS | 100 |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Мы будем использовать DBMS_XPLAN
для просмотра информация о проекции.
SELECT *
FROM TABLE (DBMS_XPLAN.display_cursor (null, null,
'ADVANCED LAST'));
Информация о проекции столбца (идентифицируется по идентификатору операции):
1 - (#keys=1) INTERNAL_FUNCTION("from$_subquery$_001"."COUNT(DISTINCTOBJECT_NAME||'THISISAREALLYLONGS
TRINGINMYEXPRESSION,DON''TYOUTHINK?ACTUALLY,IT''SREALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY
,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALL
Y,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REAL
LY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REA
LLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,RE
ALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,REALLY,R
IDICULOUSLYLONG!')")[22], "from$_subquery$_001"."OWNER"[VARCHAR2,128]
Это внутренний идентификатор из 688 символов. Удачи в использовании этого!
Еще одно доказательство того, что Oracle действительно использует все 688 символов для проекции ...
Я взял приведенный выше пример запроса и продублировал действительно, (действительно!) длинное выражение. Затем я вставил FETCH FIRST 1 ROW ONLY
. Как хорошо известно в Oracle 12 c, из-за того, как Oracle обрабатывает предложение FETCH
, оно не будет работать, если в запросе есть повторяющиеся псевдонимы столбцов.
SELECT OWNER,
COUNT(distinct object_name || 'This is a really long string in my expression, don''t you think? Actually, it''s really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, ridiculously long!'),
COUNT(distinct object_name || 'This is a really long string in my expression, don''t you think? Actually, it''s really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, really, ridiculously long!') FROM DBA_OBJECTS WHERE ROWNUM <= 100 GROUP BY OWNER FETCH FIRST 1 ROW ONLY;
ORA-00918: column ambiguously defined
00918. 00000 - "column ambiguously defined"
*Cause:
*Action:
Теперь повторите, но замените самый последний символ в выражении (измените "!" На "?"), И вы увидите, что он работает нормально.
Снова псевдоним столбца Oracle, генерируемый через внутренний недокументированный лог c, не подчиняется стандартным правилам для идентификаторов. Это, в моей книге, делает их непригодными для использования, даже если вы изменили логику c для их определения.