I have two schemas MONITORING and MONITORING_CONFIGURATION.
I am trying to create a table to which both schemas have access.
I am running the script as MONITORING_CONFIGURATION, but it is not completely ruled out that it runs as MONITORING. Can I simply ignore the error that i am getting on GRANT and get permissions because I created the table as MONITORING_CONFIGURATION while still achieving the goal of a table to which both schemas have access? The error is SQL-Fehler: ORA-01749: you may not GRANT/REVOKE privileges to/from yourself
01749. 00000 - "you may not GRANT/REVOKE privileges to/from yourself"
CREATE TABLE "MONITORING"."WEB_SERVICE_STATUS"
( "WEB_SERVICE_STATUS_ID" NUMBER,
"WEB_SERVICE_ID" NUMBER,
"STATUS" CHAR(1)
);
GRANT ALTER, DELETE, INDEX, INSERT, SELECT, UPDATE, REFERENCES, ON COMMIT REFRESH, QUERY REWRITE, DEBUG, FLASHBACK ON "MONITORING"."WEB_SERVICE_STATUS" TO "MONITORING_CONFIGURATION";
When I do select * from "MONITORING"."WEB_SERVICE_STATUS"; it appears I have the SELECT permission.
I would drop the table, and then rerun that exact script as MONITORING. Then you will know you have the correct grants for both users.
Does the following help - use PLSQL to add logic around what the current user is then taken the appropriate action via dynamic SQL using EXECUTE IMMEDIATE:
DECLARE
vsql VARCHAR2(1000);
BEGIN
IF user = 'MONITORING' THEN
DBMS_OUTPUT.PUT_LINE ( ' Running as ' || USER || ' - creating table' );
vsql := 'CREATE TABLE "MONITORING"."WEB_SERVICE_STATUS"
( "WEB_SERVICE_STATUS_ID" NUMBER,
"WEB_SERVICE_ID" NUMBER,
"STATUS" CHAR(1)
)';
EXECUTE IMMEDIATE vsql;
DBMS_OUTPUT.PUT_LINE ( ' Running as ' || USER || ' - issuing grant' );
vsql := ' GRANT ALTER, DELETE, INDEX, INSERT, SELECT, UPDATE, REFERENCES, ON COMMIT REFRESH, QUERY REWRITE, DEBUG, FLASHBACK ON "MONITORING"."WEB_SERVICE_STATUS" TO "MONITORING_CONFIGURATION"';
EXECUTE IMMEDIATE vsql;
ELSE
DBMS_OUTPUT.PUT_LINE ( ' Running as ' || USER || ' - no action taken' );
END IF;
END;
/
Are you trying to achieve connection between to schema- ?
CREATE PUBLIC DATABASE LINK MONITORING_CONFIGURATION
USING 'MONITORING_CONFIGURATION';
Related
I am trying to learn Oracle stored procedures and I cannot make them run properly on SQL Fiddle or DBfiddle. I don't have access to an installed Oracle database.
Here is my code from http://sqlfiddle.com/#!4/e53857/5
CREATE TABLE user_1 (password varchar(10))
/
create procedure updateUsers
( new_p in varchar2)
as
begin
SAVEPOINT before;
update user_1 set password = 'in proc';
dbms_output.put_line(SQL%RowCount);
commit;
EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Error: ' || SQLCODE || ' - ' || SQLERRM);
end;
/
and the query pane
insert into user_1 values ('initial');
select password from user_1;
update user_1 set password = 'from query';
SELECT password from user_1;
exec (updateUsers );
select password from user_1;
When I look at the last output below the update in the query pane has worked, the stored procedure hasn't changed anything, the value of password is still from query and there is no error message.
The line ending in the left pane is / and ; in the right pane.
I would appreciate any help and pointers.
If another online tool is easier to use for Oracle than SQL fiddle I'm open to suggestions.
I've found the solution!
schema pane, line ending / both panes
CREATE TABLE user_1 (password varchar(10))
/
create procedure updateUsers
( new_p in varchar2)
as
begin
SAVEPOINT before;
update user_1 set password = new_p;
dbms_output.put_line(SQL%RowCount);
commit;
EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Error: ' || SQLCODE || ' - ' || SQLERRM);
end;
/
query pane
insert into user_1 values ('initial')/
select password from user_1/
update user_1 set password = 'from query'/
SELECT password from user_1/
begin
updateUsers('new_pass') ;
end;
/
select password from user_1/
output
PASSWORD
initial
PASSWORD
from query
PASSWORD
new_pass
see also extension
http://sqlfiddle.com/#!4/b942cc/3
Could you please help me in a unique situation I am in. I am receiving "ORA-30511: invalid DDL operation in system triggers" when dropping sequences and procedures during logoff trigger.
I need to delete tables, sequences and procedures of users before logoff event happens. I am writing the table details in DB_OBJECTS table upon create using a separate trigger. Below is my logoff trigger - could you please help me where I am doing wrong. Dropping tables is working fine in the below code. Only Dropping sequences and procedures is giving me "ORA-30511: invalid DDL operation in system triggers" error.
CREATE OR REPLACE TRIGGER DELETE_BEFORE_LOGOFF
BEFORE LOGOFF ON DATABASE
DECLARE
USER_ID NUMBER := SYS_CONTEXT('USERENV', 'SESSIONID');
BEGIN
FOR O IN (SELECT USER, OBJECT_NAME, OBJECT_TYPE
FROM DB_OBJECTS WHERE SID = USER_ID
AND USERNAME = USER AND SYSDATE > CREATED_DTTM) LOOP
IF O.OBJECT_TYPE = 'TABLE' THEN
EXECUTE IMMEDIATE 'DROP TABLE ' || O.USER || '.' || O.OBJECT_NAME || ' CASCADE CONSTRAINTS';
ELSIF O.OBJECT_TYPE = 'SEQUENCE' THEN
EXECUTE IMMEDIATE 'DROP SEQUENCE ' || O.USER || '.' || O.OBJECT_NAME;
ELSIF O.OBJECT_TYPE = 'PROCEDURE' THEN
EXECUTE IMMEDIATE 'DROP PROCEDURE ' || O.USER || '.' || O.OBJECT_NAME;
END IF;
END LOOP;
EXCEPTION WHEN NO_DATA_FOUND THEN NULL;
END;
/
That's a simple one.
Error code: ORA-30511
Description: invalid DDL operation in system triggers
Cause: An attempt was made to perform an invalid DDL operation in a system trigger. Most DDL operations currently are not supported in system triggers. The only currently supported DDL operations are table operations and ALTER/COMPILE operations.
Action: Remove invalid DDL operations in system triggers.
That's why only
Dropping tables is working fine
succeeded.
Therefore, you can't do that using trigger.
You asked (in a comment) how to drop these objects, then. Manually, as far as I can tell. Though, that's quite unusual - what if someone accidentally logs off? You'd drop everything they created. If you use that schema for educational purposes (for example, every student gets their own schema), then you could create a "clean-up" script you'd run once class is over. Something like this:
SET SERVEROUTPUT ON;
DECLARE
l_user VARCHAR2 (30) := 'SCOTT';
l_str VARCHAR2 (200);
BEGIN
IF USER = l_user
THEN
FOR cur_r IN (SELECT object_name, object_type
FROM user_objects
WHERE object_name NOT IN ('EMP',
'DEPT',
'BONUS',
'SALGRADE'))
LOOP
BEGIN
l_str :=
'drop '
|| cur_r.object_type
|| ' "'
|| cur_r.object_name
|| '"';
DBMS_OUTPUT.put_line (l_str);
EXECUTE IMMEDIATE l_str;
EXCEPTION
WHEN OTHERS
THEN
NULL;
END;
END LOOP;
END IF;
END;
/
PURGE RECYCLEBIN;
It is far from being perfect; I use it to clean up my Scott schema I use to answer questions on various sites so - once it becomes a mess, I run that PL/SQL code several times (because of possible foreign key constraint).
Other option is to keep a create user script(s) (along with all grant statements) and - once class is over - drop existing user and simply recreate it.
Or, if that user contains some pre-built tables, keep export file (I mean, result of data pump export) and import it after the user is dropped.
There are various options - I don't know whether I managed to guess correctly, but now you have something to think about.
I am having a bit of an odd issue when it comes to oracle roles and my schema creation code, I will do my best to describe my problem below:
On schema create a role is created using the schema name provided.
EXECUTE IMMEDIATE 'CREATE ROLE ' || USER || 'ADMIN_R';
This role is then granted to specific users associated with that schema.
DECLARE
V_ROLE_NAME CONSTANT VARCHAR2(30) := USER || 'ADMIN_R';
CURSOR C_ADMIN_USERS IS
SELECT USERNAME FROM DBUSERS WHERE ROLE = 'ADMINISTRATION';
BEGIN
FOR REC IN C_ADMIN_USERS
LOOP
EXECUTE IMMEDIATE 'GRANT ' || V_ROLE_NAME || ' TO ' || REC.USERNAME || ' WITH ADMIN OPTION';
END LOOP;
END;
Users with this role have access to a special administration package.
EXECUTE IMMEDIATE 'GRANT EXECUTE ON P_ADMINISTRATION TO ' || USER || 'ADMIN_R';
The problem is When I drop the schema it does not drop this role (belongs to oracle), so when I recreate this schema the whole process fails because this role already exists. I also can't grant access to this role without logging into the system users which I want to avoid. The simple solution would be to just drop it, but my concern in that instance is that the DBA has been using that role to grant access to additional users and potentially additional packages, which would all be lost if we just arbitrarily drop the role to recreate it.
Any assistance would be greatly appreciated.
You could surround your role create with something like this:
SELECT COUNT(*)
INTO v_count
FROM DBA_ROLES
WHERE ROLE = USER || 'ADMIN_R';
IF v_count = 0 THEN
--grant your roles
END IF;
You can grant the same privilege as many times as you like.
you can drop the role before create
declare
i int;
begin
select count(*) into i
from dba_roles where role = USER||'ADMIN_R';
if (0 != i) then
execute immediate 'drop role '||USER||'ADMIN_R';
dbms_output.put_line('Role ' ||USER||'ADMIN_R has been dropped');
end if;
execute immediate 'create role '||USER||'ADMIN_R';
dbms_output.put_line('Role ' ||USER||'ADMIN_R has been created');
end;
1st try:
Role SCMADMIN_R has been created
2nd try:
Role SCMADMIN_R has been dropped
Role SCMADMIN_R has been created
DECLARE
BEGIN
FOR s IN ( SELECT first_name
FROM EA_marketing_table
WHERE town = 'LONDON'
)
LOOP
EXECUTE IMMEDIATE 'CREATE USER ' ||(s.first_name)|| ' IDENTIFIED BY LOL';
dbms_output.put_line (s.first_name || ' IDENTIFIED BY LOL');
END LOOP;
END;
/
I am trying to create a user and the code above lets me create a user but when I try to create a procedure it wont work.
This is the new code
CREATE OR REPLACE PROCEDURE proc_it_development AS
first_name VARCHAR2 (25);
BEGIN
FOR r IN ( SELECT first_name
FROM EA_marketing_table
WHERE town = 'lONDON ')
LOOP
EXECUTE IMMEDIATE 'CREATE USER '||(r.first_name)|| ' IDENTIFIED BY POOP ';
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN dbms_output.put_line ('r SELECT...INTO did not return any row.');
END;
/
any help please?
:)
Roles are not enabled in procedures/packages so you need to get the privilege granted to your user directly. Most likely you are connecting through a user that has been given the CREATE USER privilege via a role (eg: the DBA role?)
To see what you can do in a procedure, you can disable the active roles for your current session:
set role none
then try your first code block. If it works, it will also work in a procedure.
To create a new schema with a procedure you will need the privilege granted directly to your schema:
GRANT CREATE USER TO <your_schema>;
You should enclose the password in double-quotes, in Oracle 11 passwords are case-sensitive by default. Then you only create a user without any privilege, i.e.CREATE SESSION Privilege is missing.
I've got a lot of tables in a tablespace, nearly 100. I have to grant Select, Insert, Update privileges on all those tables to a user. Is it possible? When I write:
GRANT USE OF TABLESPACE MYTABLESPACE TO USERNAME
I get oracle error "invalid or missing privilege"
USE OF TABLESPACE is not a documented option, where did you find that?
You can do this to allow a user to create objects in a tablespace:
alter user username quota [amount] on mytablespace;
To grant select, insert, update and delete on objects you have to run a separate grant command for each table:
grant select, insert, update, delete on mytable1 to username;
....
Use the data dictionary view dba_tables (resp. all_tables, if you cannot access dba_tables):
declare
l_SQL varchar2(4000);
begin
for cur in (
select * from dba_tables where tablespace_name = 'mytablespace')
loop
l_sql := 'grant select, insert, update on ' || cur.owner || '.' || cur.table_name || ' to myuser';
--dbms_output.put_line(l_SQL || ';');
execute immediate l_SQL;
end loop;
end;
If you just want to generate a script, comment out the execute immediate and un-comment the dbms_output.