Oracle seems to have an algorithm that involves removing spaces and capitalizing things. However, the resulting column alias that it comes up with for a projection does not seem to obey the regular rules for identifiers that you and I are subject to. For that reason, I do not think it is going to be valuable for you to try to duplicate Oracle's internal algorithm for whatever you are trying to accomplish -- because even if you do that perfectly, you are not guaranteed to end up with an identifier you can use.
Take this example:
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;
... for readers who didn't bother scrolling right, the expression starting with COUNT(distinct object_name...
is really, really long.
Let's run that and see what Oracle is using for the projection of the inner query.
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 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 |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
We'll use DBMS_XPLAN
to look at the projection information.
SELECT *
FROM TABLE (DBMS_XPLAN.display_cursor (null, null,
'ADVANCED LAST'));
Column Projection Information (identified by operation id):
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]
That's a 688 character identifier is using internally. Good luck making use of that one!
More proof that Oracle is really using all 688 characters internally for the projection ...
I've taken the example query above and duplicated the really, (really!) long expression. Then, I stuck a FETCH FIRST 1 ROW ONLY
. As is well known in Oracle 12c, because of the way Oracle processes the FETCH
clause, it won't work if there are duplicate column aliases in the query.
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:
Now, repeat but change the very last character in the expression (change "!" to "?") and you will see it runs fine.
Again, the column alias Oracle generates through its internal, undocumented logic does not obey the standard rules for identifiers. That, in my book, makes them unusable, even if you reverse engineered the logic for determining them.