If I'm creating a table in user A.
How user B can query that table if I didn't gave it any privs?
In that code, I'm creating table general.privs_test from DBA user named "DBA_MAINT".
After that, I'm switching to another user and try to query the table.
There is no exception, even there is no grant on that table.
SQL> select user from dual;
USER
------------------------------
DBA_MAINT
SQL> create table general.privs_test(id number);
Table created.
SQL> conn dp99712a
Enter password:
Connected.
SQL> select user from dual;
USER
------------------------------
DP99712A
SQL> select * from general.privs_test;
no rows selected
SQL> desc all_tab_privs;
Name Null? Type
----------------------------------------- -------- ----------------------------
GRANTOR NOT NULL VARCHAR2(30)
GRANTEE NOT NULL VARCHAR2(30)
TABLE_SCHEMA NOT NULL VARCHAR2(30)
TABLE_NAME NOT NULL VARCHAR2(30)
PRIVILEGE NOT NULL VARCHAR2(40)
GRANTABLE VARCHAR2(3)
HIERARCHY VARCHAR2(3)
SQL> select grantee,table_schema,table_name,privilege, grantable from all_tab_pr
ivs where table_name = 'PRIVS_TEST';
no rows selected
My version is ORacle 11g.
As the table is freshly created without any privileges, the user dp99712a must have a system privilege that lets see him/her all tables. This privilege is called SELECT ANY TABLE and is granted normally to the role DBA.
To find out if this is the case, connect as user dp99712a and query:
SELECT * FROM session_privs WHERE PRIVILEGE = 'SELECT ANY TABLE';
To find out all the users and roles that have this privilege, you can use:
SELECT DISTINCT grantee
FROM dba_sys_privs
WHERE PRIVILEGE LIKE 'SELECT ANY TABLE%' ORDER BY 1;
Related
I have to give right to a database user wherein the user can add/edit comments on any column of a table .
I wrote this command , but it is giving error missing or invalid privilege , please help with the correct query , I don't have to give right on all tables to the user that is why didn't use this command
GRANT COMMENT ON ANY TABLE TO DILIP .
GRANT COMMENT ON COLUMN STN_CODE.STATION_LIST TO DILIP
As far as I can tell, you can't do that.
owner can comment anything they want on their own tables/columns
other users require comment any table privilege
If you don't want to grant that privilege, then create a stored procedure which will be used by those users. Something like this: I'll add comment only to loc column in the dept table.
SQL> create or replace procedure p_comm (par_comment in varchar2) is
2 begin
3 execute immediate 'comment on column dept.loc is ' || dbms_assert.enquote_literal(par_comment);
4 end;
5 /
Procedure created.
Let's test it: column loc doesn't have any comments:
SQL> select * from user_col_comments where table_name = 'DEPT';
TABLE_NAME COLUMN_NAM COMMENTS
--------------- ---------- ----------------------------------------
DEPT DEPTNO
DEPT DNAME
DEPT LOC
SQL> exec p_comm('department location');
PL/SQL procedure successfully completed.
Any comments now?
SQL> select * from user_col_comments where table_name = 'DEPT';
TABLE_NAME COLUMN_NAM COMMENTS
--------------- ---------- ----------------------------------------
DEPT DEPTNO
DEPT DNAME
DEPT LOC department location
SQL>
Looks OK.
I use the query CTAS to create a new table, however, when CTAS has finished, other users canĀ“t select the new table, but they had access to the old, Is it a way to pass all the users and groups to the new table? because the old table will be deleted.
"A way" is to grant (at least) select privileges to all those users.
If you used a role and granted select privilege to that role, and then granted role to those users, things would be quite simpler - just grant select privilege on the new table to the same role, and everyone will "see" it.
Otherwise, you can write query to create those grant statements for you.
For example, in Scott's schema there's the EMP table. I've previously granted privileges on it to other users in my database, and now I'm going to create a "new" CTAS table and grant privileges to the same set of users.
SQL> create table my_new_table as select * from emp;
Table created.
SQL> select 'grant select on my_new_table to ' || grantee ||';' run_me
2 from all_tab_privs_made
3 where owner = 'SCOTT'
4 and table_name = 'EMP';
RUN_ME
---------------------------------------------------------------
grant select on my_new_table to SYS;
grant select on my_new_table to SUPERUSER;
grant select on my_new_table to MY_ROLE;
grant select on my_new_table to MIKE;
Now simply copy/paste the above bunch of grant statements:
SQL> grant select on my_new_table to SYS;
Grant succeeded.
SQL> grant select on my_new_table to SUPERUSER;
Grant succeeded.
SQL> grant select on my_new_table to MY_ROLE;
Grant succeeded.
SQL> grant select on my_new_table to MIKE;
Grant succeeded.
SQL>
If there's zillion of users, PL/SQL option would be simpler as it would do everything for you (i.e. no copy/pasting):
SQL> begin
2 for cur_r in (select grantee
3 from all_tab_privs_made
4 where owner = 'SCOTT'
5 and table_name = 'EMP'
6 )
7 loop
8 execute immediate 'grant select on my_new_table to ' || cur_r.grantee;
9 end loop;
10 end;
11 /
PL/SQL procedure successfully completed.
SQL>
If you create a table using CTAS from an existing one, the new one is a new segment, therefore it lacks of privileges. You need to recover the permissions granted to the old table and granting to the new one. For that you can use several alternatives ( dbms_metadata, dynamic sql ).
For the purposes , I'd do it like this
SQL> CREATE TABLE T2 AS SELECT * FROM T1 ;
SQL> begin
dbms_metadata.set_transform_param (dbms_metadata.session_transform,
'SQLTERMINATOR', true);
dbms_metadata.set_transform_param (dbms_metadata.session_transform, 'PRETTY',
true);
end;
/
select replace(dbms_metadata.get_dependent_ddl('OBJECT_GRANT', 'T1', 'OWNER_OF_T1' ),'T1','T2') AS ddl
from dual;
The first part is for creating in a nice format the list of necessary grants. The second part retrieves all the privileges granted to T1 and generates the list of grants statements for running to the T2 table. Then you only need to run the list of grants
As I said, there are several alternatives to do this.
Regards
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
Seeking help from experts to resolve the following error:
CREATE TABLE "ABC"
(----
----
"STATUSES" "INTLIST" ,
----
"CHAIN_DETAILS" "CHAIN_CFG_LIST" ,
-----
)
NESTED TABLE "STATUSES" STORE AS "OP_STATUSES_NT"
RETURN AS VALUE
NESTED TABLE "CHAIN_DETAILS" STORE AS "op_chains"
RETURN AS VALUE;
Gives error message:
ORA-02320: Error creating nested table column storage table STATUSES
ORA-01950: no permissions for tablespace
My guess is the user has no quota on the default tablespace. You can find your default tablespace by querying user_users, or dba_users if checking a different user, and the quota from user_ts_quotas or dba_ts_quotas. A value of -1 means unlimited. Join these to see your quota for the default tablespace:
select u.username
, u.default_tablespace
, tq.max_bytes
from user_users u
left join user_ts_quotas tq
on tq.tablespace_name = u.default_tablespace;
This will be a problem for any table, but if deferred_segment_creation is set to true (the default) then the error will only appear when you attempt to add a row to the table, as this is the first request for storage.
Now that I check, it seems a nested table requires storage immediately, which could explain why you get the error for a nested table column.
Example using test user 'demo':
sqlplus / as sysdba
SQL*Plus: Release 12.2.0.1.0 Production on Fri May 11 10:41:51 2018
Copyright (c) 1982, 2016, Oracle. All rights reserved.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
SQL> create user demo identified by demo;
User created.
SQL> grant create session, create table, create type to demo;
Grant succeeded.
Connect as demo:
SQL> conn demo/demo
Connected.
SQL> col username format a15
SQL> col default_tablespace format a20
SQL> select u.username
2 , u.default_tablespace
3 , tq.max_bytes
4 from user_users u
5 left join user_ts_quotas tq
6 on tq.tablespace_name = u.default_tablespace;
USERNAME DEFAULT_TABLESPACE MAX_BYTES
--------------- -------------------- ----------
DEMO USERS
My default tablespace is USERS and I have no quota on it, but I can create a table:
SQL> create table demotable(id integer);
Table created.
I only have a problem when I need some actual storage:
SQL> insert into demotable values (1);
insert into demotable values (1)
*
ERROR at line 1:
ORA-01950: no privileges on tablespace 'USERS'
Now try with a nested table:
SQL> create or replace type demo_tt as table of number(1);
2 /
Type created.
SQL> create table abc
2 ( id integer
3 , statuses demo_tt )
4 nested table statuses store as op_statuses_nt return as value;
create table abc
*
ERROR at line 1:
ORA-02320: failure in creating storage table for nested table column STATUSES
ORA-01950: no privileges on tablespace 'USERS'
My user demo needs a quota on tablespace USERS (normally you grant unlimited or nothing, but just for fun let's allocate 1MB...)
SQL> conn / as sysdba
Connected.
SQL> alter user demo quota 1M on users;
User altered.
SQL> conn demo/demo
Connected.
SQL> select u.username
2 , u.default_tablespace
3 , tq.max_bytes
4 from user_users u
5 left join user_ts_quotas tq
6 on tq.tablespace_name = u.default_tablespace;
USERNAME DEFAULT_TABLESPACE MAX_BYTES
--------------- -------------------- ----------
DEMO USERS 1048576
Retry the table creation:
SQL> create table abc
2 ( id integer
3 , statuses demo_tt )
4 nested table statuses store as op_statuses_nt return as value;
Table created.
SQL> insert into abc (id, statuses) values (1, demo_tt(1,2,3));
1 row created.
I've created some TABLES in 1 DB with the user name DEVICE.
Querying the tables I see that they belong to the user DEVICE
SELECT owner, table_name FROM dba_tables
Then I created a user named CAR, I logged in the DB with that user and create some tables, I've tried to query the other tables with
SELECT * FROM DEVICE.table_name;
with the result
00942. 00000 - "table or view does not exist"
and logged with the user CAR and don't see the user DEVICE in others users from SQL Developer
This error comes up because CAR doesn't have privileges to query the DEVICE's table.
You need to grant access to this table to CAR.
1- login as DEVICE
2- Issue the following grant:
GRANT SELECT ON TABLE_NAME TO CAR;
If you want to do it for all the tables of the DEVICE user, create a script like that:
select 'GRANT SELECT ON ' || table_name || ' TO CAR;' FROM USER_TABLES;
My advice would be to create a ROLE if you do that:
CREATE ROLE DEVICE_READ_ROLE;
select 'GRANT SELECT ON ' || table_name || ' TO DEVICE_READ_ROLE;' FROM USER_TABLES;
GRANT DEVICE_READ_ROLE TO CAR;
Note that if you create new tables in the DEVICE schema you will need to grant select on the new table to the ROLE for CAR to have access to it.
Here the script to generate grant select on all the tables.
select 'grant select on Admin.' || object_name || ' to User;'
from user_objects
where object_type in('TABLE');
Then you have to create a script to run these grant statements at once or you can use PL/SQL as well. Type the following in the SQL prompt.
SQL> spool grant_statements.sql
SQL> set pagesize 0
SQL> set feedback off
SQL> set linesize 300
SQL> set trimout on
SQL> set trimspool on
SQL> select 'grant select on Admin.' || object_name || ' to User;' from user_objects where object_type in('TABLE','SYNONYM')
/
SQL> spool off
And you have got the script file you can run it.
OR
You can run the following PL/SQL block (Run as admin user).
BEGIN
FOR s IN (SELECT *
FROM user_objects where object_type in('TABLE','SYNONYM'))
LOOP
EXECUTE IMMEDIATE 'grant select on admin.' || s.object_name || ' to user';
END LOOP;
END;
you need to grant access to user CAR for the tables created by DEVICE . login using DEVICE user and grant access to the tables CAR should be able to access using sql like below
GRANT SELECT , UPDATE , INSERT ON TABLE_NAME TO CAR;
Is it normal for an oracle view to loose all its grants when modifying the source SQL?
I am using SQL Developer if that has anything to do with it.
First of all, you don't have "grants" - "grant" is an operation. You have "roles" and "privileges".
Second, views have neither roles nor privileges themselves - schemas do have. Basically, a self-descriptive command is: grant select on view_1 to schema_1.
Third, schemas do not lose their privileges if you create or replace your view. Here's a quick sample:
11:03:07 #> conn system/sys#oars_sandbox
Connected.
11:03:15 SYSTEM#oars_sandbox> create user test1 identified by test1;
User created.
11:03:39 SYSTEM#oars_sandbox> create user test2 identified by test2;
User created.
11:03:48 SYSTEM#oars_sandbox> create view test1.view1 as select * from dual;
View created.
11:04:03 SYSTEM#oars_sandbox> grant select on test1.view1 to test2;
Grant succeeded.
11:04:15 SYSTEM#oars_sandbox> select grantee, owner, table_name, privilege, grantor from dba_tab_privs where grantee = 'TEST2';
GRANTEE OWNER TABLE_NAME PRIVILEGE GRANTOR
------------------------------ ------------------------------ ------------------------------ ---------------------------------------- ------------------------------
TEST2 TEST1 VIEW1 SELECT TEST1
11:05:13 SYSTEM#oars_sandbox> create or replace view test1.view1 as select * from dual;
View created.
11:05:24 SYSTEM#oars_sandbox> select grantee, owner, table_name, privilege, grantor from dba_tab_privs where grantee = 'TEST2';
GRANTEE OWNER TABLE_NAME PRIVILEGE GRANTOR
------------------------------ ------------------------------ ------------------------------ ---------------------------------------- ------------------------------
TEST2 TEST1 VIEW1 SELECT TEST1
However, it is quite possible that SQL developer invokes drop view first instead of create or replace. In this case, your privileges are automatically removed.
11:05:26 SYSTEM#oars_sandbox> drop view test1.view1;
View dropped.
11:10:21 SYSTEM#oars_sandbox> select grantee, owner, table_name, privilege, grantor from dba_tab_privs where grantee = 'TEST2';
no rows selected
11:10:24 SYSTEM#oars_sandbox> create or replace view test1.view1 as select * from dual;
View created.
11:10:26 SYSTEM#oars_sandbox> select grantee, owner, table_name, privilege, grantor from dba_tab_privs where grantee = 'TEST2';
no rows selected