Find out how is table partitioned - oracle

Is there any way to find out, whether is table partitioned by Hash, Range or List in Oracle?
I could not find such info in metadata tables.
Thanks for help.

You haven't searched metadata tables enough.
Connected to Oracle Database 12c Enterprise Edition Release 12.2.0.1.0
Connected as xxx#yyy
SQL> select owner, table_name, partitioning_type, subpartitioning_type
SQL> from all_part_tables
SQL> where owner = 'SYS'
SQL> and rownum <= 10
SQL> ;
OWNER TABLE_NAME PARTITIONING_TYPE SUBPARTITIONING_TYPE
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ----------------- --------------------
SYS AQ$_SUBSCRIBER_LWM HASH NONE
SYS WRH$_FILESTATXS RANGE NONE
SYS WRH$_SQLSTAT RANGE NONE
SYS WRH$_SYSTEM_EVENT RANGE NONE
SYS WRH$_WAITSTAT RANGE NONE
SYS WRH$_LATCH RANGE NONE
SYS WRH$_LATCH_CHILDREN RANGE NONE
SYS WRH$_LATCH_PARENT RANGE NONE
SYS WRH$_LATCH_MISSES_SUMMARY RANGE NONE
SYS WRH$_EVENT_HISTOGRAM RANGE NONE
10 rows selected
SQL>
You should be better off with using the user_part_tables instead of all_part_tables, and then please omit the owner = 'SYS' predicate from the where clause.

Related

Number column in Oracle table storing 'hidden' decimal places

First ever question here, because searching for these terms is way too vague. I don't know how the data got in to the table (I think just by "insert into tomtest(test) values (280.1);" but can't be sure) but this example seems odd. Why does the straight select show 1 decimal place, but the to_char select shows 14 decimal places?
SQL> set linesize 100
SQL> select banner from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
PL/SQL Release 12.2.0.1.0 - Production
CORE 12.2.0.1.0 Production
TNS for Linux: Version 12.2.0.1.0 - Production
NLSRTL Version 12.2.0.1.0 - Production
SQL> describe tomtest
Name Null? Type
----------------------------------------------------- -------- ------------------------------------
TEST NUMBER
SQL> select * from tomtest;
TEST
----------
280.1
SQL> select * from tomtest where test = 280.1;
no rows selected
SQL> select to_char(test) from tomtest;
TO_CHAR(TEST)
----------------------------------------
280.10000000000002
SQL> SELECT data_type, data_length, data_precision, data_scale FROM USER_TAB_COLS WHERE TABLE_NAME = 'TOMTEST' AND COLUMN_NAME = 'TEST';
DATA_TYPE DATA_LENGTH DATA_PRECISION DATA_SCALE
NUMBER 22
The reason is the default numberformat in sql plus.
in the database you have the value 280.10000000000002 and not 280.1
here is an example
SQL> select 128.000000000000000000006 as test from dual;
test
-------------------------
128
SQL> select 128.200000000000000000006 as test from dual;
test
-------------------------
128,2
you can change the number format and check again
SQL> SET NUMF 999999999.99999999999999999999999999999999
SQL> select 128.200000000000000000006 as test from dual;
test
-------------------------------------------
128.20000000000000000000600000000000
SQL>
Update:
This phenomenon can be explained by the fact that your data type is only defined as a number, without precise specification of precision.
This means that you can save a decimal number, but do not give an exact specification of the decimal places.
Here is an example that shows the differences.
CREATE TABLE test_num(
n1 NUMBER,
n2 NUMBER(23,15));
INSERT INTO test_num VALUES(208.20000000000006,208.20000000000006);
SELECT t.*FROM test_num t;
Resut in PLSQL/Developer:
N N2
--- ---
208,2 208,200000000000030
in plsql Developer you can display numbers as char. If you want to that activate a checkbox in the preferences: Tools -> Preferences -> SQL Window -> Number fields to_char
in your case, I would round a number value to a certain number of decimal places on insert/update or change your data type from number to number(p, s) (Where p is the precision and s is the scale.)

Find tables with specific criteria - Oracle 12c

How to find tables in a schema that start with NUM_ whose data is more than 0 records.
Eg:
Consider I'm a couple of schemas
Schema1
Schema2
Schema3
Schema1 has tables:
NUM_table11 (has 0 records)
NUM_table12 (has 20 records)
DummyTable1 (has 10 records)
Schema2 has tables:
NUM_table21 (has 0 records)
NUM_table22 (has 20 records)
DummyTable2 (has 10 records)
Schema3 has tables:
NUM_table31 (has 0 records)
NUM_table32 (has 20 records)
DummyTable3 (has 10 records)
I want to get only Schema2 tables, whose name starts with NUM_ and has more than 0 records.
i.e, in this case NUM_table22
Can anyone help on achieving this?
I don't have your tables (and don't feel like creating ones either), so I'll show it on another example - looking for the EMP tables throughout my database.
Connect as a privileged user, the one that has access to DBA_TABLES (as you want to search all users, right?). One of those is SYS, if you don't have any other.
Then write a PL/SQL block which looks into the DBA_TABLES, searches for tables whose name begins with EMP. Dynamic SQL (i.e. execute immediate) counts rows in those tables and - if it is a positive number - returns that table as an output.
SQL> show user
USER is "SYS"
SQL> set serveroutput on
SQL>
SQL> declare
2 l_cnt number;
3 begin
4 for cur_r in (select owner, table_name
5 from dba_tables
6 where table_name like 'EMP%'
7 )
8 loop
9 execute immediate 'select count(*) from ' || cur_r.owner ||'.'||
10 cur_r.table_name into l_cnt;
11 if l_cnt > 0 then
12 dbms_output.put_line(cur_r.owner ||'.'|| cur_r.table_name ||' = ' || l_cnt);
13 end if;
14 end loop;
15 end;
16 /
HR.EMPLOYEES = 107
SCOTT.EMP = 14
PL/SQL procedure successfully completed.
SQL>
In my databases, there are two such tables:
one is owned by HR, its name is EMPLOYEES and contains 107 rows
another one is owned by SCOTT, its name is EMP and contains 14 rows
I believe that you shouldn't have any problems in adjusting that code to your needs.
I'm not sure why would you want to search only through schema2; in that case, it is simpler to connect as schema2 and do the same job using user_tables (or all_tables) (so you don't have to connect as a privileged user).
Or, if you want to pick the user within that code, you'd add yet another condition into the where clause (line #6):
and owner = 'SCHEMA2'
Littlefoot's answer would work but may take longer. Assuming stats has been collected the following SQL should give you want you want and much faster. If stats are not fresh then it can give wrong result.
select * from DBA_TABLES where TABLE_NAME like 'NUM_%' and NUM_ROWS > 0

Incorrect output while using dictionary tables inside Trigger

I am using ALL_TABLES/ALL_TAB_COLUMNS to get count of tables in my schema (EDW_SRC) and another schema(EDW_STG). I get correct counts when i run the query in my sql developer as shown below. But if i put the same query inside a trigger, i get wrong count for other schema(EDW_STG).
Please refer below code:
(This is just a sample code to replicate the issue, not my business requirement. I am referring ALL_TAB_COLUMNS in my actual code to get the number of columns in a particular table in different schema, for which i have Select access.)
select user from dual;
USER
-----
EDW_SRC
DROP TABLE ABC;
Table ABC dropped.
CREATE TABLE ABC(ID NUMBER);
Table ABC created.
select count(1) EDW_STG_CNT
from all_tables
where owner='EDW_STG';--Different Schema
EDW_STG_CNT
----------
101
select count(1) EDW_SRC_CNT
from all_tables
where owner='EDW_SRC';--My Schema
EDW_SRC_CNT
------------
1554
create or replace trigger trig_test_dml_abc
before insert on abc
DECLARE
V_STG_CNT number :=NULL;
V_SRC_CNT number :=NULL;
begin
DBMS_OUTPUT.PUT_LINE('***** TRIGGER OUTPUT *****');
select count(1) into V_SRC_CNT from all_tables
where owner='EDW_SRC'; --My Schema
DBMS_OUTPUT.PUT_LINE('My Schema EDW_SRC_CNT :'||V_SRC_CNT);
select count(1) into V_STG_CNT from all_tables
where owner='EDW_STG'; --Different Schema
DBMS_OUTPUT.PUT_LINE('Different Schema EDW_STG_CNT :'||V_STG_CNT);
end;
Trigger TRIG_TEST_DML_ABC compiled
INSERT INTO ABC VALUES (2);
1 row inserted.
***** TRIGGER OUTPUT *****
My Schema EDW_SRC_CNT :1554
Different Schema EDW_STG_CNT :2
The Different Schema count should be 101. Why is it coming as 2.
Oracle Version:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
Thanks
K

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.

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.

Resources