Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Vladimir.

Asked: May 02, 2004 - 6:34 pm UTC

Last updated: May 03, 2004 - 7:45 pm UTC

Version: 9.2.0

Viewed 1000+ times

You Asked

Hi Tom,

After three years of occasional trying, I finally get to ask you a direct question. I've asked this a couple of times in the form of a comment to relevant topics on this site, but never got an answer.

Here I copy my last post on the subject. I hope I'll get an answer this time.
Quote from
</code> http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:412605596308#15359853000993 <code>

"Why Oracle don't use CLOB but use LONG in its dictionary tables?

Tom, your first answer to it ("Legacy reasons") doesn't tell us why the *new* data dictionary columns are of type LONG. I mean, there cannot be any backward compatibility concerns for "user_ind_expressions.column_expression", for example -- LOBs were present and recommended at the time when function-based indexes
came around.
I have a grudge with that particular view, since it prevents me from using a simple read-only script to tell me if a column is indexed -- and it is a rare occasion when I am allowed to create a stored PL/SQL function in a production database, where every change is strictly controlled (as it should be)."

Regards,
Flado

and Tom said...



but you can run any ad-hoc plsql block you want (and perhaps, this function could be added to your "utility package" so it is always there)

I don't see how this affects your ability to see if a column is indexed -- since if a function on the column is indexed, the column isn't indexed (the function f(x) is). Besides, you'd have to totally parse the string (a simple like doesn't cut it) -- meaning you'd need code anyhow.

But -- i do agree, it would be nice to have them as lobs.

for enhancement requests like this -- I'll have to refer you to support, I cannot change the implementation.

Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

ad-hoc PL/SQL doesn't do it

Vladimir Andreev, May 03, 2004 - 2:04 pm UTC

Hi Tom,
Thanks for your answer. It seems I have trouble explaining my problems with this. Another try:
I have some SQL statements that check for things like redundant indexes, indexes that include a unique key but are not declared unique, and such. Each of these is a single SQL statement... I'd like to keep it that way and still cover all cases. I can't use an ad-hoc PL/SQL function, as they are not allowed in SQL. IOW, this doesn't work:
19:06:48 sys@flado>declare
19:07:05 2 function Get_Lob return varchar2 is
19:07:05 3 begin return 'example'; end;
19:07:05 4 begin
19:07:05 5 for i in (select Get_Lob d from dual) loop
19:07:05 6 dbms_output.put_line(i.d);
19:07:05 7 end loop;
19:07:05 8 end;
19:07:05 9 /
for i in (select Get_Lob d from dual) loop
*
ERROR at line 5:
ORA-06550: line 5, column 19:
PLS-00231: function 'GET_LOB' may not be used in SQL

Second, I don't want to take the function-based indexes in account, exactly for the reasons you gave: an index on f(x) is not the same as an index on x. However, a descending index on X is (for the above mentioned purposes) the same as an ascending index on X:

sys@flado>create table t(x int, y int);

Table created.

sys@flado>create index t_asc on t(x);

Index created.

sys@flado>create index t_desc on t(x desc);

Index created.

sys@flado>col column_name for a13
sys@flado>col index_name for a7
sys@flado>select index_name,column_position,column_name,descend from dba_ind_columns
2 where table_name='T';

INDEX_N COLUMN_POSITION COLUMN_NAME DESC
------- --------------- ------------- ----
T_ASC 1 X ASC
T_DESC 1 SYS_NC00003$ DESC

2 rows selected.

For all intents and purposes, these two indexes are identical -- with Oracle, one can range-scan B*Tree indexes in any direction, so one of these two is redundant. But how do you tell that these two indexes in fact index the same column? Or more generally, how do I find out that there is in fact an index on t(x)?
Here the dba_ind_expressions view comes into play:

sys@flado>set long 10
sys@flado>select index_name,column_position,column_expression
2 from dba_ind_expressions
3 where table_name='T';

INDEX_N COLUMN_POSITION COLUMN_EXP
------- --------------- ----------
T_DESC 1 "X"

1 row selected.

So, theoretically, I could do a (inline) view that would provide the same information as dba_ind_columns, only replacing the descending column names (SYS_NC00003$ and the like) with the real names -- and parsing this "function" is not at all hard. Then I could adjust my SQLs to cover all cases...
Only in theory, since I cannot get the column expression out of the dictionary *and* pass it to the SQL engine without the help of a *stored* function (packaged or not). Let's see... maybe Oracle provides such a (simple, really) function in one of its many supplied packages?
Nope.
And that's where I'm stuck. I'm quite sure there isn't any solution to this, but I was sure that solutions to other problems didn't exist until I found them on your site :-)
If you can pull a solution to this problem out of your hat (or sleeve?), I would be extremely impressed - not to mention grateful.

Regards,
Flado

Tom Kyte
May 03, 2004 - 7:45 pm UTC

but in general


t(x desc,y,z)
t(x,y desc,z)


are not "the same" at all -- seems like might be looking for a "so rare, it won't happen" case.

without a user defined function, you will not be "whereing" on a long.

My comment about anonymous blocks was -- you can write code to do this, but not sql.

varchar2's are limited to 4000 bytes in sql.

clobs are different beasts from longs (it is not "simple, really", it is actualy quite "large" and hard)

(on a *production* system, I wouldn't let you look for duplicate indexes in the first place. that is something for TEST or DEV, not production)

sorry, no magic on this one.



More to Explore

CLOB/BLOB/etc

Complete documentation on Securefiles and Large Objects here