I have a problem.
CREATE TABLE accounts(
id INTEGER,
name VARCHAR2(100)
)
/
CREATE OR REPLACE FUNCTION account_balance(account_id_in IN accounts.id%TYPE)
RETURN NUMBER
IS
BEGIN
RETURN 0;
END;
/
Error:
Error starting at line : 1 in command -
CREATE OR REPLACE FUNCTION account_balance(account_id_in IN accounts.id%TYPE)
RETURN NUMBER
IS
BEGIN
RETURN 0;
END;
Error report -
ORA-01031: insufficient privileges
01031. 00000 - "insufficient privileges"
*Cause: An attempt was made to perform a database operation without
the necessary privileges.
*Action: Ask your database administrator or designated security
administrator to grant you the necessary privileges
Please help me resolve above error, thank you!
As pointed out in the comments, you are missing the required permissions to create the function from whatever user account you are currently using.
Let's assume your less privileged login is called some_user. To fix your problem, login as your more privileged account, and apply the following GRANT statement:
grant create procedure to some_user;
Documentation: GRANT
CREATE PROCEDURE: Create stored procedures, functions, and packages in the grantee's schema.
Login as
sys as sysdba
then execute the following command after changing username to your username
GRANT CREATE PROCEDURE TO username;
Do like this
sqlplus /nolog
connect sys/"123456a#"#xe as sysdba
SQl> alter session set "_ORACLE_SCRIPT"=true;
SQL>grant create table to donhuvy;
Related
I try to create user and grant for them some privileges. I try to create without using procedure:
CREATE USER User1 IDENTIFIED BY password;
It works fine.
But for example, i have thousands of users. So I created a procedure to do it:
CREATE OR REPLACE PROCEDURE CreateUser AS
BEGIN
FOR u IN ( SELECT id FROM User )
LOOP
EXECUTE IMMEDIATE 'CREATE USER User_'||d.id || ' IDENTIFIED BY password';
EXECUTE IMMEDIATE 'GRANT SELECT ON UserInfo_'||d.id||' TO User_'||d.id;
END LOOP;
END
But it throws an error:
ORA-01031: insufficient privileges
How can I handle this problem? Thanks for helping in advance
You need to make sure the user running the procedure has the privileges to create users.
Assuming the user that will run the procedure is MyUser, you need to run :
GRANT CREATE USER to MyUser;
if your SQL is directly (i.e not in a procedure ) but not working from a procedure/function it means that you have the Grants through a role. For a statement to work in a procedure or a function we need direct Grants and not through the role.
You can check that you have the Create user by a role by doing the following and trying your SQL, if it fails it means you have access through a role.
SET role none;
CREATE USER User1 IDENTIFIED BY password;
I have created a procedure as shown below. This procedure is present in schema1 and trying to modify the password of another schema/user let's say schema2.
To achieve this the user schema1 must have altered user privilege but I cannot provide the alter user privilege to schema1 due to some restrictions on the application level.
I tried to query using ALTER SESSION in the procedure but it is not working.
Can someone help me with the solution?
code:
Procedure p_demo(p_schema in varchar, p_pswd in varchar2)
is
begin
execute immediate 'alter session set current_schema ='||p_schema;
execute immediate 'alter user '||p_schema||' identified by '||p_pswd;
end;
Changing the current_schema has no impact on permissions or what user is currently logged in. It merely changes how object name resolution works. If you query an object foo when current_schema is set to schema1, Oracle looks in the schema1 schema rather than in the current user's schema. It does nothing to give you access to the schema1.foo table.
I'm not quite sure that I understand the goal. If you are trying to ensure that only the schema2 user can change the schema2 user's password, you can define the procedure to use invoker's rights rather than definer's rights.
create or replace procedure change_my_password( p_username in varchar2,
p_password in varchar2 )
authid current_user
is
begin
execute immediate 'alter user '||p_username||' identified by '||p_password;
end;
/
If the goal is to have the procedure owned by schema1 and to give users other than the schema2 user permission to change schema2's password (i.e. to allow an application user or a helpdesk user to reset the user's password), schema1 would likely need to have the alter user permission. Otherwise, it's probably not doable.
If you're really desperate, you could potentially use the undocumented (and I emphasize undocumented here, subject to change at any time, may have weird side effects, may tend to make Oracle Support unhappy) dbms_sys_sql package. That's the package that APEX uses internally to run code as other users. I don't imagine that a sane DBA would consider giving an application user execute access on that package rather than the much (much, much) safer alter user permission but if you're trying to work around some corporate policy and you're not much concerned about actual security...
There are 3 users involved in this example:
scott, who is trying to change someone else's password (that's your schema1)
mike, whose password should be changed (your schema2)
mydba, who is granted DBA role in my database (if you don't have such an user, SYS would do, but - you'd rather have your own "DBA" user, don't mess up with SYS if you don't have to)
Connected as scott, I can't modify mike's password:
SQL> alter user mike identified by lion;
alter user mike identified by lion
*
ERROR at line 1:
ORA-01031: insufficient privileges
I'm going to connect as mydba and create a stored procedure which looks like yours:
SQL> connect mydba/mypwd#c11gt
Connected.
SQL> create or replace procedure p_demo (p_schema in varchar2, p_pswd in varchar2) is
2 begin
3 execute immediate 'alter user ' || p_schema || ' identified by ' || p_pswd;
4 end;
5 /
Procedure created.
SQL> exec p_demo('mike', 'lion');
PL/SQL procedure successfully completed.
OK; it works. I'll grant execute privilege on it to scott:
SQL> grant execute on p_demo to scott;
Grant succeeded.
Back to scott; see what he can do now:
SQL> connect scott/tiger#c11gt
Connected.
SQL> exec mydba.p_demo('mike', 'friday');
PL/SQL procedure successfully completed.
Do mike's credentials work?
SQL> connect mike/friday#c11gt
Connected.
SQL>
Yes, everything's fine.
So: you don't have to grant alter user to schema1; let it use procedure owned by a privileged user who can change someone else's password.
Cant we do as shown below: Tried doing this but it didn't work.
What i am trying to do is basically give alter user privileges to one role and assign that role to my oracle procedure.
Create role role_name;
GRANT ALTER USER TO role_name
grant all on role_name to procedure
I have a stored procedure for deleting partitions. Before starting, I have to delete a constraint.
I installed the stored procedure on system user. When I test the procedure I have this error: 'ORA-01031: insufficient privileges'.
This is a piece of code that I wrote:
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE USER_NAME.TABLE_NAME DISABLE CONSTRAINT CONSTRAINT_NAME';
EXCEPTION
WHEN OTHERS THEN
O_sCodError := 'NO_OK';
O_sDesError := 'Error at DISABLE CONSTRAINT_NAME: ' || SQLERRM || ';';
RETURN;
END;
Well, as I execute the stored procedure as system, I do not understand the reason for I have that error. And I think I eventually think the same error when I try to delete a partition.
Works for me on 11g XE:
SQL> show user
USER is "SCOTT"
SQL>
SQL> create table test
2 (id number constraint pk_test primary key,
3 name varchar2(20)
4 );
Table created.
SQL> connect system
Enter password:
Connected.
SQL> begin
2 execute immediate 'alter table scott.test disable constraint pk_test';
3 return;
4 end;
5 /
PL/SQL procedure successfully completed.
SQL>
Please, follow that example and execute it in your database. Post the result (by editing the question, not as a comment).
First, you should never install custom code in an Oracle default schema like SYSTEM. Put your code in a dedicated application schema. Since it contains dynamic SQL (execute immediate) you might want to consider making it an "invoker's rights" procedure, then granting execute privileges on it to the user that will execute it.
That said, in Oracle 11g whoever's privileges are used to run the PL/SQL block must have direct permissions on the underlying table, not inherited permissions through a role like DBA. If the procedure has "definer's rights" then the schema that owns the procedure must have direct privileges on the table. If "invoker's rights" then the user executing the procedure must have the privileges.
See this link for additional details:
Execute immediate within Oracle Procedure
You must grant SYSTEM account direct privilege (not with a role) to run ALTER TABLE on the target table because roles are not enabled in stored procedures by default: https://asktom.oracle.com/Misc/RolesAndProcedures.html.
Try:
grant alter any table to system;
or
grant alter table on user_name.table_name to system;
In Ora11g I used to grant all privileges to a user as follows.
create user xx identified by psw;
grant create session, grant any privilege to xx;
grant all privileges to xx;
But in Ora 12c when I execute grant privileges, I'm getting the below ERROR.
Error starting at line : 2 in command - grant create session, grant
any privilege to xx Error report - ORA-00604: error occurred at
recursive SQL level 1 ORA-20997: "GRANT ANY PRIVILEGE" grants not
allowed ORA-06512: at "RDSADMIN.RDSADMIN", line 79 ORA-06512: at line
2
00604. 00000 - "error occurred at recursive SQL level %s"
*Cause: An error occurred while processing a recursive SQL statement
(a statement applying to internal dictionary tables).
*Action: If the situation described in the next error on the stack
can be corrected, do so; otherwise contact Oracle Support.
I have tried the answer suggested in 1 and it does not seems work.
1. Regarding Users in Oracle 12c
It is getting the below ERROR.
GRANT All PRIVILEGE TO name Error report - ORA-00922: missing or
invalid option
00922. 00000 - "missing or invalid option"
*Cause:
*Action
Your help on "grant all privileges to a user in ora12c this is much appreciated.
Thanks!
Yes. I was able to grant privileges with a namespace.
Create user xx identified by psw account unlock;
grant connect to xx;
grant create session, create table, create sequence, create trigger to
xx;
alter user xx quota 5M on USERS;
commit;
if you need to give unlimited quota, you use this.
ALTER USER xx quota unlimited on USERS;
commit;
create or replace function gen.sample_func(owner varchar2) return varchar2
as
data_t varchar2(10);
cursor cur is select data_type from SYS.DBA_TAB_COLUMNS;
begin
open cur;
dbms_output.put_line('Done');
close cur;
return data_t;
end sample_func;
On compiling the above function i get the following error
Warning: compiled but with compilation errors
Errors for FUNCTION sample_func
LINE/COL
--------------------------------------------------------------------------------
ERROR
--------------------------------------------------------------------------------
4/8
PLS-00201: identifier 'DBA_TAB_COLUMNS' must be declared
4/8
PL/SQL: Item ignored
7/15
PLS-00320: the declaration of the type of this expression is incomplete or malfo
rmed
7/8
PL/SQL: Statement ignored
I'm not getting this error when i execute the select statement alone in the cursor.
Please help me to resolve this issue.
Your user needs to be granted SELECT ON DBA_TAB_COLUMNS.
Note that granting through a role will not work - it needs to be a direct grant to the user for you to create a function/procedure.
In a definer's rights stored procedure such as the one you are creating, only privileges that are granted directly to the owner of the procedure are considered when resolving object names. Privileges granted through roles are not considered. I would wager that the owner of your procedure has been granted access to the DBA_TAB_COLUMNS view via a role rather than via a direct grant. You would need to ask the DBA to grant access to DBA_TAB_COLUMNS directly to the user that owns your procedure.
You can quickly test whether this is actually the problem you're experiencing. In SQL*Plus, enter the command
SQL> set role none;
and then run your SELECT statement. If you get the same permissions error, then the rpoblem is that you have the grant via a role. Disabling roles means that your interactive session is running with the same privileges that your stored procedure would run with.