I have tables in Schema A. I created views in Schema B using the tables in schema A.
I want to grant permissions to a user to select the data from view in Schema B.
For this to work i know we have to enable the grant option on tables in Schema A to user B.
But I want to do it in a single script (This script has to be in schema B). Is there a way to do this using the user name/password of schema A.
It's not unusual to want to have a single script to deploy a change. The thing is, such a script needs to be run by a power user, because it needs to have system privileges at the ANY level. This usually means a DBA account, preferably an application account but otherwise SYSTEM or SYS.
So the script you want would look like this:
grant select on user_a.t23 to user_b
/
grant select on user_a.t42 to user_b
/
create view user_b.v_69 as
select t23.col1, t42.col2
from user_a.t42
join user_a.t23
on (t42.id = t23.id)
/
grant select on user_b.v_69 to user_c
/
A common scenario is that we have a suite of individual scripts which have been written to be run by different users but which we now need to bundle up into a single deployment. The original scripts don't contain the schema names, and there are many good reasons why we wouldn't want to hardcode them in the scripts.
One way to build that master script is to use change the CURRENT_SCHEMA syntax:
alter session set current_schema=USER_A
/
#run_grants_to_userb.sql
alter session set current_schema=USER_B
/
#create_view69.sql
#run_grants_to_userc.sql
We still need a DBA user to run the master script. One advantage of switching the current schema is that it allows us to deploy objects like database links, which through a quirk of syntax cannot have the schema name in their declaration. One gotcha is that the user doesn't change, so a script which employs the USER pseudo-column may produce unwanted results.
Simply Run the query
GRANT INSERT, SELECT, UPDATE, DELETE ON TABLE1 TO SCHEMA2;
Only by connecting as user A at some point. You can still do it in one script if you really want to:
connect userA/passwordA
grant select on my_table to userB;
connect userB/passwordB
create view my_view as select * from userA.my_table;
Of course now you have a script lying around which exposes two sets of user credentials to anyone who can read it. So something to think hard about before doing in production, for example.
If you want other users to be able to select from the view, you don't need to grant explicit permissions on userA.my_table to them; as long as the view owner can see the underlying table, other users just need to be able to see the view. Which is often kinda the point (or one of them) as you can restrict the view to only expose selected data from the underlying table to the rest of the world. I assume you have a reason for not creating the view in schema A.
I'm not sure if you're really asking about granting select to user B with admin option so that user B can then grant select on user A's table to other people. If that's possible, it doesn't sound like a good idea, and isn't necessary for the view to work.
Let user A grant select on his tables to B and include the 'grant option'.
As user A:
GRANT select ON table TO user_b WITH GRANT OPTION;
Let user B grant select on his views to user A and include the 'grant option'.
As user B:
GRANT select ON view TO user_a WITH GRANT OPTION;
As user A:
GRANT select on user_b.view TO user_c;
This allows user A to pass this grant on to other users.
Related
I have just created a new read only user (TEMPDBREAD) for our developers # our oracle Database 11.2.0.4
Now they like read access to all tables from just one schema (TEMPDBUSER)
is there an alternative to grant select any table.
They should not be able to read the other schemes. But since the table structure often changes, it is difficult to justify everything manually.
That's why select any table is awarded very quickly and easier to place
Can i deny the access to the other schemes anyway?
Any Idea how i can solve this very simple?
BR Julian
Grant Table Access manually
Grant Select ANY Table
Nope. You either give them select any table and let them read any table in the database or you give them access to each table in TempDBUser individually. In the vast, vast majority of cases, you'd want to give them access to each table in TempDBUser (presumably via a role because there will be many developer accounts that need to run queries).
It isn't clear to me why giving object-level access is problematic for you. "Table structure changes" do not require new grants since they're just changes to existing objects. If you really mean that new tables are created frequently, you'd just want to incorporate the grants into your change control and deployment process.
If you have a packaged application that creates new tables periodically (a terrible practice), you could create a DDL trigger that issued the grant every time a new table was created in TempDBUser. You'd need a DDL trigger that submitted a job via the dbms_job package that did the actual grant which is a rather convoluted architecture but it works.
spool /tmp/grant_issue.sql
select 'grant select on TEMPDBUSER.' || table_name || ' TO TEMPDBREAD;' from dba_tables where owner='TEMPDBUSER' ;
spool off;
run the spool file.
sqlplus #/tmp/grant_issue.sql
The given database contains a masterdata (MD) Schema and an application specific Schema (APP). In the APP Schema we have a view which provides the applications data from one table in the scheme joined with data from the MD Schema.
Example: Think of an address book application, which holds an address table, but cities and ZIP codes are joined from a masterdata table in another Schema which is maintained centrally.
CREATE VIEW view_adress AS
SELECT app.ID, app.Street, app.ZIP, zip.CITYNAME
FROM APP.adress app
LEFT OUTER JOIN MD.zipcodes zip
ON app.ZIP = zip.ZIP
This is very simplified. The actual view I use is a lot more complicated like that and therefore I implemented an INSTEAD OF INSERT, UPDATE Trigger to map INSERTs on the view to the correct base table in my APP Schema.
The application users (role) is granted SELECT,INSERT,UPDATE,DELETE on all tables inside this APP Schema. They are also granted SELECT on that zipcode table in the master data Schema.
When I insert on that view, I get an "ORA-01720: Grant Option Does Not Exist"... I don't know the exact cause of this error, but it can be assumed that the INSTEAD-OF Trigger never INSERTS on the ZIP Code Table, only on the address table.
I understand, that granting the application users INSERT privilege on the zipcode table would probably resolve this issue, but I am feeling uncomfortable granting INSERTs on tables to users which they never should edit in any way, because these are only lookups.
Is there another, possibly "the correct way" to solve this?
By "insufficient permissions error" do you mean this?
ORA-01720: grant option does not exist for 'MD.ZIPCODES'
*Cause: A grant was being performed on a view or a view was being replaced
and the grant option was not present for an underlying object.
*Action: Obtain the grant option on all underlying objects of the view or
revoke existing grants on the view.
If so, the solution is that you need to grant the relevant permissions to the schema owning the view - not to the roles that use the view:
grant insert on md.zipcodes to app with grant option;
It's true that you are still having to grant a permission that is logically not required, but you are not granting it to users, only the app schema.
I have a situation in our Oracle environment where I would like to be able to grant select permissions to a certain user/group on all views in a particular schema.
I realize that I could write a dynamic statement to iterate over all the views in the schema and grant permissions to them individually as shown here but I would like to be able to have this apply to all views that exist in the schema now or in the future.
I was also contemplating the possibility of writing a DDL trigger that could monitor for the creation of new views but setting permissions in a trigger isn't something I've seen done before and doesn't seem like accepted practice.
Basically, is there a VIEW analog to the GRANT EXECUTE ANY PROCEDURE?
The EXECUTE ANY PROCEDURE grant allows a user to execute any procedure in any schema in the database, not just those in a particular schema. You can grant a user the SELECT ANY TABLE privilege-- that will allow the user to query any table or view in any schema in the database not just those in a particular schema. That's the analogous privilege, it just seems unlikely that either is really what you're after.
Since views should not be created dynamically, this sort of requirement would normally be handled by simply including the appropriate GRANT statements in the scripts that create the new views which get promoted up through the environments. Dynamically granting privileges is generally frowned upon because it generally implies that you have issues with your change control process that need to be addressed.
I have, for third party applications that insist on creating new objects periodically, created a DDL trigger that grants privileges on new objects. In order to do that, you would need to submit a job that actually does the GRANT. A GRANT is a DDL statement so it issues an implicit commit and implicit commits aren't allowed in triggers, you have to have a separate job that runs moments after the object is created. This means that you end up with a number of moving pieces that generally makes your environment more complex.
I am a huge noob with Oracle right now. I was asked to import two databases into Oracle. I succeeded...sort of...I think. So these databases were exported with the user and when I imported the databases it created the user and all of the tables were attached to that user. Same thing for the second database. Lets just call the user for the first import USER1 and for the second db import USER2. USER1 has its own tables and USER2 has its own tables.
I want to create a user that can see all of those tables. so I don't have to login to one to access and manipulate its data and the other to do the same. I would like to create a USER3 that can see and manipulate USER1 and USER2's tables associated with each. I have tried a number of ways and just cannot seem to get this to work. Any help would be greatly appreciated.
Thanks
To allow USER3 to query a table owned by USER1:
GRANT SELECT ON USER1.tablename TO USER3;
You must run this for each table individually.
Other grants that you may need are INSERT, UPDATE and DELETE, e.g. to grant full control:
GRANT SELECT, INSERT, UPDATE, DELETE ON USER1.tablename TO USER3;
When you login as USER3, to query the table you normally need to specify the schema, e.g.:
SELECT * FROM USER1.tablename;
If you want to avoid having to specify the schema each time, you can use synonyms, e.g.:
(login as USER3)
CREATE SYNONYM tablename FOR USER1.tablename;
Now you can login as USER3 and run this:
SELECT * FROM tablename;
"I just don't understand why I have to do all that."
Users - or schemas - are the means Oracle uses for organising applications and enforcing governance. In a well-design application it is extremely unlikely that one schema would need to grant every privilege on all its objects to another user. Oracle recommends a policy of granting the minimum necessary set of privileges to other users. Doing this requires us to make choices and write discrete statements to grant specific privileges on particular objects.
I'm trying to create a view, and have distilled the problem down to the inability to create a view that references tables from a different schema.
For example, I can do:
select count(*) from otherschema.othertable;
and I can do:
create view foo as select count(*) as bar from oneofmytables;
But if I try:
create view foo as select count(*) as bar from otherschema.othertable;
I get an "insufficient privileges" error. What additional privileges do I need?
Do you have the grant to the other user's table directly? Or is it via a role? You will need the privilege to be granted directly in order to create an object (view, procedure, etc.) that references the other table. As a quick test, in SQL*Plus
SQL> set role none;
SQL> select count(*) from otherschema.othertable;
If that fails, then the problem is that you have been granted privileges on the table via a role.
I guess you have been given select right on otherschema.othertable via a role not via a direct grant.
If this is the case, you should connect as otheruser and then do a grant select on othertable to <your-schema>.
I believe that your DBA will need to grant you
create any view
privilege. Depending on the security restrictions at your site they may or not allow this. I typically do not