Reputation: 3647
I'm using the below query to get the Max Range of all the Columns of all tables in a Oracle Database
select OWNER,TABLE_NAME,COLUMN_NAME,DATA_PRECISION,(POWER(10,DATA_PRECISION) -1)
from ALL_TAB_COLUMNS where OWNER = 'MASTER' and DATA_TYPE = 'NUMBER' and
DATA_PRECISION is NOT NULL order by TABLE_NAME ASC;
OWNER TABLE_NAME COLUMN_NAME DATA_PRECISION (POWER(10,DATA_PRECISION) -1)
MASTER TABLE_1 COL_1 7 9999999
MASTER TABLE_1 COL_5 7 9999999
MASTER TABLE_2 COL_3 10 9999999999
I am trying to get a 6th & 7th Column, which should be max of that column in that particular table and difference between Max Range( i.e (POWER(10,DATA_PRECISION) -1)) and actual max value in the table.
Ex:
OWNER TABLE_NAME COLUMN_NAME DATA_PRECISION (POWER(10,DATA_PRECISION) -1) MAX_VALUE DIFF
MASTER TABLE_1 COL_1 7 9999999 9994637 5362
MASTER TABLE_1 COL_5 7 9999999 9997637 2362
MASTER TABLE_2 COL_3 10 9999999999 8933999999 1066000000
How to achieve this ?
Would i be able to join tables, using TABLE_NAME ?
Bet, this would be helpful to a lot of people.
Upvotes: 3
Views: 969
Reputation: 36902
Convert DBA_TAB_COLUMNS.HIGH_VALUE to the maximum value as described in this post by Jonathan Lewis.
The maximum and minimum values are recorded when table statistics are gathered. If the default estimate percent is used, and the statistics were gathered recently, the value will be accurate.
create or replace function raw_to_num(i_raw raw)
return number
as
m_n number;
begin
dbms_stats.convert_raw_value(i_raw,m_n);
return m_n;
end;
/
select owner,table_name,column_name,data_precision
,(power(10,data_precision) -1) max_range
,raw_to_num(high_value) max_value
,(power(10,data_precision) -1) - raw_to_num(high_value) diff
from dba_tab_columns
where data_type = 'NUMBER'
and owner = user
--Add conditions for specific users and tables.
order by owner, table_name, column_name;
Upvotes: 0
Reputation: 164
The easiest way to go about this is to write a small function that you can provide a table name and column like so:
CREATE OR REPLACE FUNCTION get_max_value (p_table_name VARCHAR2, p_column VARCHAR2)
RETURN NUMBER IS
v_query VARCHAR2(1000);
v_max_value NUMBER;
BEGIN
v_query := 'SELECT MAX (' || p_column ||') FROM '
|| p_table_name ;
EXECUTE IMMEDIATE v_query
INTO v_max_value;
RETURN v_max_value;
END;
And then a slightly modified version of your query above:
SELECT owner,
table_name,
column_name,
data_precision,
(POWER(10,data_precision) -1) ,
get_max_value (owner || '.' || table_name, column_name) max_val
FROM all_tab_columns
WHERE 1 = 1
AND owner = 'MASTER'
AND data_type = 'NUMBER'
AND data_precision is NOT NULL
AND table_name NOT LIKE '%$%'
ORDER BY c.table_name ASC
Just be careful, depending on the number of your tables and the number of rows in each, execution can take a while.
Upvotes: 2