seazodiac
asked on
ORA-01031: insufficient privileges when try to alter index in the stored procedure.
I have grappled with this nasty "NO-NO" for quite a while, just cannot seem to get it to work. My goal is simple, try to rebuild the index in a procedure, which requires me to embed the "ALTER INDEX" inside the dynamic SQL.
Basic info here: oracle9i database, LINUX AS 2.1 (i don't think it matters though).
What I have tried:
Log in as the SCHEMA OWNER.
1. I have tested by calling "alter index <index_name> rebuild online compute statistics" in the sqlplus window , it worked fine.
2. the roles and sys privs this accout have are:
ROLE: DBA, CONNECT, RESOURCE.
SYSTEM PRIVS: create any index, alter any index, create any indextype, alter any indextype.
3. Then everytime, I execute the "exec cmdb_util.rebuild_all_inde
Don't explain to me that ROLE is disabled in the stored procedure because I have all index related system privileges directly assigned.
Anyone, please chime in.....
---------My code is below, it's pretty simple, you can test by just copying and pasting.
CREATE OR REPLACE PACKAGE cmdb_util
AS
TYPE g_ind_cursor_type IS REF CURSOR;
PROCEDURE rebuild_all_indexes;
END;
/
PROCEDURE rebuild_all_indexes
AS
l_ind_name VARCHAR2(30);
g_ind_cursor g_ind_cursor_type;
BEGIN
OPEN g_ind_cursor FOR 'select index_name FROM user_indexes where index_name NOT LIKE '||chr(39)||'SYS_%'||chr(3
FETCH g_ind_cursor INTO l_ind_name;
LOOP
EXIT WHEN g_ind_cursor%NOTFOUND;
execute immediate 'ALTER INDEX '||l_ind_name||' REBUILD ONLINE COMPUTE STATISTICS';
FETCH g_ind_cursor INTO l_ind_name;
END LOOP;
CLOSE g_ind_cursor;
END;
END cmdb_util;
/
Why not trap the exception and print out the index it is failing on and then try rebuilding that from your SQL*Plus login?
ie:
PROCEDURE
CURSOR c IS
SELECT 'alter index ' || index_name || ' rebuild online ...' s
FROM user_indexes
WHERE ...;
stm VARCHAR2(2000);
BEGIN
FOR r IN c
LOOP
stm := r.s;
execute immediate stm;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('ERRO R ...');
dbms_output.put_line(stm);
END;
Just out of interest, why are you rebuilding all indexes? One would usually query index_stats table and build on an as required basis. You're putting your hand up for needless overhead & most likely inconsistent performance.
How many times have we heard: "This is taking a long time to run now and we haven't touched it...."
Just a bit of DBA gripe heh :-)
Good luck!
K
ie:
PROCEDURE
CURSOR c IS
SELECT 'alter index ' || index_name || ' rebuild online ...' s
FROM user_indexes
WHERE ...;
stm VARCHAR2(2000);
BEGIN
FOR r IN c
LOOP
stm := r.s;
execute immediate stm;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('ERRO
dbms_output.put_line(stm);
END;
Just out of interest, why are you rebuilding all indexes? One would usually query index_stats table and build on an as required basis. You're putting your hand up for needless overhead & most likely inconsistent performance.
How many times have we heard: "This is taking a long time to run now and we haven't touched it...."
Just a bit of DBA gripe heh :-)
Good luck!
K
Which user was the procedure created using? If created under a different user to the one you are trying to run on, you will be accessing with the default definer rights access model, perhaps you would want to change this to invoker rights?
PROCEDURE rebuild_all_indexes
AUTHID CURRENT_USER
AS
PROCEDURE rebuild_all_indexes
AUTHID CURRENT_USER
AS
This might seem odd, but try
grant create any table to user;
As a side note you could simply have the procedure
PROCEDURE rebuild_all_indexes
AS
BEGIN
for C_ind in (select index_name from user_indexes
where index_name NOT LIKE 'SYS_%' ) LOOP
execute immediate 'ALTER INDEX '||C_Ind.Index_Name ||
' REBUILD ONLINE COMPUTE STATISTICS';
END LOOP;
END;
grant create any table to user;
As a side note you could simply have the procedure
PROCEDURE rebuild_all_indexes
AS
BEGIN
for C_ind in (select index_name from user_indexes
where index_name NOT LIKE 'SYS_%' ) LOOP
execute immediate 'ALTER INDEX '||C_Ind.Index_Name ||
' REBUILD ONLINE COMPUTE STATISTICS';
END LOOP;
END;
how may roles is the account in?
what's the default role for the account using for alter index?
did you use any proxy?
what's the default role for the account using for alter index?
did you use any proxy?
ASKER
Sorry, I just got into my office ...
dsacker --->try both, but neither helped :-(
Kong ---> Believed, I have turned over every stoned I could spot, when I try to trapped which index(es) I bumped over, the results: None of them let me pass through. another fact is that the user account owns the tables as well as all indexes.
grim_toaster --->read my comment to Kong, then you know definer vs. invoker does not play a role here.
Bigfam5 --->Yes, I could do that (I will try that for sanity check and see if I could get around by that way). However, I would prefer to put all my procedures in one package since I have many more of them .
Danielzt: No, I am not using proxy , I directly log into the sqlplus window. if that's what you mean.
Any other ideas?
dsacker --->try both, but neither helped :-(
Kong ---> Believed, I have turned over every stoned I could spot, when I try to trapped which index(es) I bumped over, the results: None of them let me pass through. another fact is that the user account owns the tables as well as all indexes.
grim_toaster --->read my comment to Kong, then you know definer vs. invoker does not play a role here.
Bigfam5 --->Yes, I could do that (I will try that for sanity check and see if I could get around by that way). However, I would prefer to put all my procedures in one package since I have many more of them .
Danielzt: No, I am not using proxy , I directly log into the sqlplus window. if that's what you mean.
Any other ideas?
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
The double semi-colons aren't by accident, as I'm sure you're aware. :)
Correction: ||index|| should be ||index_name||
ASKER
dsacker:
thanks for the effort. It's my bad. I should point it out in the very beginning, that I need this to be done in stored procedure.
I used this script for the past.
thanks for the effort. It's my bad. I should point it out in the very beginning, that I need this to be done in stored procedure.
I used this script for the past.
I suspected you did need it that way, as I sometimes need a stored procedure for things, too ... just wondered if it wasn't something beyond the 1031 error that perhaps would reveal itself in SQLPLUS, ie at the very table that could be the culprit or something like that. Or did it execute flawlessly in your sqlplus .sql script in the past?
ASKER
the script that alter all the indexes (the syntax are exactly the same as it appears in pl/sql) are working just fine .
Another possibility, then I'm out of ideas :)
Could the stored procedure actually put an index in use while trying to rebuild it? See some interesting comments at:
http://www.dbazine.com/weeg16.shtml
Could the stored procedure actually put an index in use while trying to rebuild it? See some interesting comments at:
http://www.dbazine.com/weeg16.shtml
seazodiac,
Did you try to assign the system privilege CREATE ANY TABLE
Did you try to assign the system privilege CREATE ANY TABLE
ASKER
Yes. i think I mention this account I used to run this rebuild index procedure is the schema owner.
Hmmm maybe I missed something but did you grant create index explicitly to the user or was it inherited from a role. Try granting create index explicitly...
Can't figure out why else it wouldn't work good luck!
Can't figure out why else it wouldn't work good luck!
Either grant explicitly the create index priv or run the procedure as invoker's rights:
procedure ...
authid current_user
IS
...
Roles are disabled in a definer rights (default) procedure
but they remain enabled in a invoker rights procedure.
procedure ...
authid current_user
IS
...
Roles are disabled in a definer rights (default) procedure
but they remain enabled in a invoker rights procedure.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Maybe you're missing the "unlimited tablespace" privilege?
Any luck? I'd be interested to hear how you went...
Yoren, "unlimited tablespace" is tagged onto the RESOURCE role.
Yoren, "unlimited tablespace" is tagged onto the RESOURCE role.
Kong - I suggested it because roles don't take effect in stored procedures.
True, but then we're going down the definer vs invoker's rights path which seazodiac doesn't agree with...
ASKER
something really strange is going on here....
I think I exhaust almost all the means, but seems going no where...
I will give one last shot tomorrow, report back....
I think I exhaust almost all the means, but seems going no where...
I will give one last shot tomorrow, report back....
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
HI All:
I finally got it over with, but I took Kong's list of sys privs , just assigned them to the user account, and it worked. I am still puzzling what exaclty the sys privs I am missing here.
I split points between you guys....
I finally got it over with, but I took Kong's list of sys privs , just assigned them to the user account, and it worked. I am still puzzling what exaclty the sys privs I am missing here.
I split points between you guys....
Most likely, the privilege you were missing was "GLOBAL QUERY REWRITE".
I have to face the problem as well and searched it solution frm the site below:
In summary:
CREATE ANY INDEX must be explicitly granted to your Oracle user, not via a role!
Site: http://forums.oracle.com/forums/thread.jsp?forum=75&thread=249256&message=727594&q=20696e73756666696369656e742070726976696c65676573#727594
In summary:
CREATE ANY INDEX must be explicitly granted to your Oracle user, not via a role!
Site: http://forums.oracle.com/forums/thread.jsp?forum=75&thread=249256&message=727594&q=20696e73756666696369656e742070726976696c65676573#727594
Interestingly enough, it's actually the CREATE TABLE priv that was missing.
Actually, it's both CREATE TABLE and UNLIMITED TABLESPACE that were missing. I just did this procedure with RESOURCE role, CREATE SESSION, UNLIMITED TABLESPACE, and CREATE TABLE system privs.
* Did you by chance have the 10032 event set? Yeah, I know ... sounds far-fetched ... but turning off the trace event sometimes helps.
* If it works from an anonymous PL block, but not from a procedure, disconnect and reconnect, then try it again. I'm sure you've done this, but am just going over a few "features" that have scratched the itch.
Just chiming in. :)