grant SELECT access to v$session to other users - oracle

I want to grant SELECT access to v$session to other users in an Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
but when I run this query:
SELECT owner, object_type FROM dba_objects WHERE object_name = 'V$SESSION';
I got this error:
00942. 00000 - "table or view does not exist"

Oracle v$ views are named V_$VIEWNAME and they have synonyms in format V$VIEWNAME and you can’t give privilege on a synonym. If you want to give permission to a V$ view you must give it like below
SQL> grant select on v_$session to hr;

We also needed a regular user without access to v$session to cleanup sessions. A function will execute with the privileges of the owning schema, so if you create a function as the user having access to V$SESSION you can execute it from the user not having the required privilege.
For example, IFH_OWNER has access to v$session, user id854812 doesn't:
As id854812:
select count(*) from v$session
ORA-00942: table or view does not exist
As IFH_OWNER:
select count(*) from v$session
56
create or replace function getSessionCount return int
as
vCnt int;
begin
select count(*) into vCnt from v$session;
return( vCnt);
end;
select getSessionCount from dual;
56
grant execute on getSessionCount to id854812;
As id854812:
select ifh_owner.getSessionCount from dual;
56

Related

How to get the created / last DDL time for an Oracle synonym?

SQL Developer shows the creation and last DDL time for a public synonym in a table:
CREATED 15-AUG-09
LAST_DDL_TIME 15-AUG-09
OWNER PUBLIC
SYNONYM_NAME ISEMPTY
TABLE_OWNER MDSYS
TABLE_NAME OGC_ISEMPTY
DB_LINK (null)
How can I get the same information via a SQL query?
select * from all_synonyms where synonym_name = 'ISEMPTY'
does not get the created/last ddl dates.
More generally, is there a good way to see the queries that sql developer uses to display the data it displays (when you do not have access to a profiler)?
Thanks
You need the ALL_OBJECTS system view:
select *
from all_objects
where owner = 'OWNER_NAME'
and object_name = 'ISEMPTY'
and object_type = 'SYNONYM'

oracle table_privileges values

Does anybody know the values that are given in the table_privileges? I already found out what "A" means. But I did not find out for what the "S" stands for. I think this isnt documented. It has something to do with update privileges on particular columns.
The thing you are missing is that we can grant UPDATE on a subset of a table's columns.
First of all, let's just grant SELECT on a table. The value of UPDATE_PRIV is 'N', for None:
SQL> grant select on t23 to mr_x;
Grant succeeded.
SQL> select select_priv, update_priv
2 from table_privileges
3 where table_name = 'T23'
4 /
S U
- -
Y N
SQL>
Now, if I grant UPDATE on a single column the value of UPDATE_PRIV is 'S', presumably for Some:
SQL> grant update (col2) on t23 to mr_x
2 /
Grant succeeded.
SQL> select select_priv, update_priv
2 from table_privileges
3 where table_name = 'T23'
4 /
S U
- -
Y S
SQL>
Finally, I grant UPDATE on the whole table the value of UPDATE_PRIV is 'A', for All:
SQL> grant update on t23 to mr_x
2 /
Grant succeeded.
SQL> select select_priv, update_priv
2 from table_privileges
3 where table_name = 'T23'
4 /
S U
- -
Y A
SQL>
I'm sorry but having noticed an answer that #JustinCave gave to this very question back in 2005 I have to post it.
From the SQL Reference documentation on table_privileges
http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96536/ch2486.htm#1318903
"TABLE_PRIVILEGES contains information on grants on objects for which
the user is the grantor, grantee, or owner, or PUBLIC is the grantee.
This view is included for compatibility with Oracle version 6. Oracle
Corporation recommends that you do not use this view."
Given that Oracle recommends you not use this view, I would strongly
suggest that you use the DBA_TAB_PRIVS view instead. The information
there should be a bit easier to decipher.

Efficient way to obtain DDL from entire Oracle DB

Currently there are about 30 tables in the Oracle 11.1 database.
Is there a way to generate all ddl with a single command? (Or a few commands?)
Edit:
Following a suggestion below, I tried:
SELECT dbms_metadata.get_ddl( 'TABLE', table_name, owner )
FROM all_tables;
And got:
ORA-31603: object "HS_PARTITION_COL_NAME" of type TABLE not found in schema "SYS"
ORA-06512: at "SYS.DBMS_SYS_ERROR", line 105
ORA-06512: at "SYS.DBMS_METADATA", line 3241
ORA-06512: at "SYS.DBMS_METADATA", line 4812
ORA-06512: at line 1
31603. 00000 - "object \"%s\" of type %s not found in schema \"%s\""
*Cause: The specified object was not found in the database.
*Action: Correct the object specification and try the call again.
It's clear that there is something extremely basic about dbms_metadata that I don't understand.
Here's what worked for me:
SELECT dbms_metadata.get_ddl('TABLE', table_name)
FROM user_tables;
You can use the DBMS_METADATA package. Something like
SELECT dbms_metadata.get_ddl( 'TABLE', table_name, owner )
FROM all_tables
WHERE <<some condition to get the 30 tables in question>>
Yes you can pretty easily using the dbms_metadata package. You can write a routine that opens a cursor on the USER_TABLES system table and gets the ddl for each table. An example for that is in the article too.
If you want to individually generate ddl for each object,
Queries are:
--GENERATE DDL FOR ALL USER OBJECTS
--1. FOR ALL TABLES
SELECT DBMS_METADATA.GET_DDL('TABLE', TABLE_NAME) FROM USER_TABLES;
--2. FOR ALL INDEXES
SELECT DBMS_METADATA.GET_DDL('INDEX', INDEX_NAME) FROM USER_INDEXES WHERE INDEX_TYPE ='NORMAL';
--3. FOR ALL VIEWS
SELECT DBMS_METADATA.GET_DDL('VIEW', VIEW_NAME) FROM USER_VIEWS;
OR
SELECT TEXT FROM USER_VIEWS
--4. FOR ALL MATERILIZED VIEWS
SELECT QUERY FROM USER_MVIEWS
--5. FOR ALL FUNCTION
SELECT DBMS_METADATA.GET_DDL('FUNCTION', OBJECT_NAME) FROM USER_PROCEDURES WHERE OBJECT_TYPE = 'FUNCTION'
GET_DDL Function doesnt support for some object_type like LOB,MATERIALIZED VIEW, TABLE PARTITION
SO, Consolidated query for generating DDL will be:
SELECT OBJECT_TYPE, OBJECT_NAME,DBMS_METADATA.GET_DDL(OBJECT_TYPE, OBJECT_NAME, OWNER) FROM ALL_OBJECTS WHERE (OWNER = 'XYZ') AND OBJECT_TYPE NOT IN('LOB','MATERIALIZED VIEW', 'TABLE PARTITION') ORDER BY OBJECT_TYPE, OBJECT_NAME;

How to query the permissions on an Oracle directory?

I have a directory in all_directories, but I need to find out what permissions are associated with it, i.e. what has been granted on it?
This should give you the roles, users and permissions granted on a directory:
SELECT *
FROM all_tab_privs
WHERE table_name = 'your_directory'; --> needs to be upper case
And yes, it IS in the all_TAB_privs view ;-) A better name for that view would be something like "ALL_OBJECT_PRIVS", since it also includes PL/SQL objects and their execute permissions as well.
You can see all the privileges for all directories wit the following
SELECT *
from all_tab_privs
where table_name in
(select directory_name
from dba_directories);
The following gives you the sql statements to grant the privileges should you need to backup what you've done or something
select 'Grant '||privilege||' on directory '||table_schema||'.'||table_name||' to '||grantee
from all_tab_privs
where table_name in (select directory_name from dba_directories);
Wasn't sure if you meant which Oracle users can read\write with the directory or the correlation of the permissions between Oracle Directory Object and the underlying Operating System Directory.
As DCookie has covered the Oracle side of the fence, the following is taken from the Oracle documentation found here.
Privileges granted for the directory
are created independently of the
permissions defined for the operating
system directory, and the two may or
may not correspond exactly. For
example, an error occurs if sample
user hr is granted READ privilege on
the directory object but the
corresponding operating system
directory does not have READ
permission defined for Oracle Database
processes.
With Oracle 11g R2 (at least with 11.2.02) there is a view named datapump_dir_objs.
SELECT * FROM datapump_dir_objs;
The view shows the NAME of the directory object, the PATH as well as READ and WRITE permissions for the currently connected user. It does not show any directory objects which the current user has no permission to read from or write to, though.
Expanding on this a bit, this script will allow you to see the privileges for any object type and name that appears in all_tab_privs.
/*
usage: #obj-privs <object-type> <object-name>
object-type can be any type of object; table, directory, index, etc.
case does not matter
object-name can be any legal name - case matters
Wild cards work for both object-type and object-name
#obj-privs dir% MYDIR
#obj-privs table INV%
#obj-privs synonym %
*/
set pagesize 100
set linesize 200 trimspool off
col grantor format a15
col grantee format a30
col table_schema format a30 head 'OWNER'
col table_name format a30 head 'OBJECT_NAME'
col privilege format a15
col v_object_name new_value v_object_name noprint
col v_object_type new_value v_object_type noprint
set feed off term off echo off pause off verify off
select upper('&1') v_object_type from dual;
select '&2' v_object_name from dual;
set feed on term on feed on
select
p.table_name
, p.table_schema
, p.privilege
, p.grantee
, p.grantor
, o.object_type
from all_tab_privs p
join all_objects o on o.owner = p.table_schema
and o.object_name = p.table_name
and p.table_name like '&v_object_name'
and o.object_type like '&v_object_type'
order by p.table_name, p.table_schema, p.grantee
/
Here is an example for directories:
SQL# #obj-privs dir% %
OBJECT_NAME OWNER PRIVILEGE GRANTEE GRANTOR OBJECT_TYPE
------------------------------ ------------------------------ --------------- ------------------------------ --------------- ---------------------------------------------------------------------
DATA_PUMP_DIR SYS WRITE EXP_FULL_DATABASE SYS DIRECTORY
DATA_PUMP_DIR SYS READ EXP_FULL_DATABASE SYS DIRECTORY
DATA_PUMP_DIR SYS WRITE IMP_FULL_DATABASE SYS DIRECTORY
DATA_PUMP_DIR SYS READ IMP_FULL_DATABASE SYS DIRECTORY
ORACLE_OCM_CONFIG_DIR SYS READ ORACLE_OCM SYS DIRECTORY
ORACLE_OCM_CONFIG_DIR SYS WRITE ORACLE_OCM SYS DIRECTORY
ORACLE_OCM_CONFIG_DIR2 SYS WRITE ORACLE_OCM SYS DIRECTORY
ORACLE_OCM_CONFIG_DIR2 SYS READ ORACLE_OCM SYS DIRECTORY
8 rows selected.
Here is another for tables with USER in the name:
SQL# #obj-privs tab% %USER%
OBJECT_NAME OWNER PRIVILEGE GRANTEE GRANTOR OBJECT_TYPE
------------------------------ ------------------------------ --------------- ------------------------------ --------------- ---------------------------------------------------------------------
BDSQL_USER_MAP SYS INSERT BDSQL_ADMIN SYS TABLE
BDSQL_USER_MAP SYS DELETE BDSQL_ADMIN SYS TABLE
BDSQL_USER_MAP SYS SELECT BDSQL_ADMIN SYS TABLE
BDSQL_USER_MAP SYS READ BDSQL_USER SYS TABLE
KU$_USER_MAPPING_VIEW_TBL SYS SELECT SELECT_CATALOG_ROLE SYS TABLE
SDO_PREFERRED_OPS_USER MDSYS UPDATE PUBLIC MDSYS TABLE
SDO_PREFERRED_OPS_USER MDSYS INSERT PUBLIC MDSYS TABLE
SDO_PREFERRED_OPS_USER MDSYS SELECT PUBLIC MDSYS TABLE
SDO_PREFERRED_OPS_USER MDSYS DELETE PUBLIC MDSYS TABLE
USER_PRIVILEGE_MAP SYS READ PUBLIC SYS TABLE
10 rows selected.

Oracle SQL Query for listing all Schemas in a DB

I wanted to delete some unused schemas on our oracle DB.
How can I query for all schema names ?
Using sqlplus
sqlplus / as sysdba
run:
SELECT *
FROM dba_users
Should you only want the usernames do the following:
SELECT username
FROM dba_users
Most likely, you want
SELECT username
FROM dba_users
That will show you all the users in the system (and thus all the potential schemas). If your definition of "schema" allows for a schema to be empty, that's what you want. However, there can be a semantic distinction where people only want to call something a schema if it actually owns at least one object so that the hundreds of user accounts that will never own any objects are excluded. In that case
SELECT username
FROM dba_users u
WHERE EXISTS (
SELECT 1
FROM dba_objects o
WHERE o.owner = u.username )
Assuming that whoever created the schemas was sensible about assigning default tablespaces and assuming that you are not interested in schemas that Oracle has delivered, you can filter out those schemas by adding predicates on the default_tablespace, i.e.
SELECT username
FROM dba_users
WHERE default_tablespace not in ('SYSTEM','SYSAUX')
or
SELECT username
FROM dba_users u
WHERE EXISTS (
SELECT 1
FROM dba_objects o
WHERE o.owner = u.username )
AND default_tablespace not in ('SYSTEM','SYSAUX')
It is not terribly uncommon to come across a system where someone has incorrectly given a non-system user a default_tablespace of SYSTEM, though, so be certain that the assumptions hold before trying to filter out the Oracle-delivered schemas this way.
SELECT username FROM all_users ORDER BY username;
select distinct owner
from dba_segments
where owner in (select username from dba_users where default_tablespace not in ('SYSTEM','SYSAUX'));
Below sql lists all the schema in oracle that are created after installation
ORACLE_MAINTAINED='N' is the filter. This column is new in 12c.
select distinct username,ORACLE_MAINTAINED from dba_users where ORACLE_MAINTAINED='N';
How about :
SQL> select * from all_users;
it will return list of all users/schemas, their ID's and date created in DB :
USERNAME USER_ID CREATED
------------------------------ ---------- ---------
SCHEMA1 120 09-SEP-15
SCHEMA2 119 09-SEP-15
SCHEMA3 118 09-SEP-15
Either of the following SQL will return all schema in Oracle DB.
select owner FROM all_tables group by owner;
select distinct owner FROM all_tables;

Resources