Dba Code
Dba Code
This tip comes from Mohammad Anwar, Oracle Developer, Tuskerdirect Ltd, in London, United Kingdom.
This tip achieves the same output as the Tip for Week of August 23, 2004. In that tip, the author uses
ROWNUM and inline views, whereas I use the analytic function RANK() to do the job.
Original Statement:
select case when rank() over (partition by dept order by empno) = 1 then
dept else null end as dept,
rank() over (partition by dept order by empno) as sno,
empno,
name
from emp;
/
Output:
This function provides the number of times a pattern occurs in a string (VARCHAR2).
Function created.
*Note: Use CREATE to make sure you are not overwriting an existing function.
Try it out:
SQL> select num_chars('miSSissipPi','i') from dual
2 /
NUM_CHARS('MISSISSIPPI','I')
----------------------------
4
SQL> c/'i'/'ssi'
1* select num_chars('miSSissipPi','ssi') from dual
SQL> /
NUM_CHARS('MISSISSIPPI','SSI')
------------------------------
2
SQL> c/ssi'/ppi'
1* select num_chars('miSSissipPi','ppi') from dual
SQL> /
NUM_CHARS('MISSISSIPPI','PPI')
------------------------------
1
SQL> c/'ppi/'p
1* select num_chars('miSSissippi','p') from dual
SQL> /
NUM_CHARS('MISSISSIPPI','P')
----------------------------
2
SQL> c/p'/s'
1* select num_chars('miSSissippi','s') from dual
SQL> /
NUM_CHARS('MISSISSIPPI','S')
----------------------------
4
This tip comes from Ilya Petrenko, Senior Oracle DBA, Open Distributed Solutions, Inc., in Jamison,
Pennsylvania.
This script uses two Oracle functions—TRANSLATE and Length—to identify if data includes numeric or non-
numeric characters.
ROW_SEQ# STRING#
---------- --------
100 0123
100 911
ROW_SEQ# STRING#
---------- ------------------------------------
1 T0011TABLE
2 TEST22TABLE
3 TMP_DATA3TABLE
5 TRANS5TABLE
6 TRANS216TABLE
7 TRIV7TRIGGER
100 87
Tip of the Week
Tip for Week of November 22, 2004
This tip comes from Nikhil Dave, Sr. Software Enginner, Hexaware Technologies Ltd., in Navi Mumbai,
India.
This tip shows the tablespace owner and usage for all within a database.
Generate Factorials
This tip comes from Kailasanathan Subbaraman, Senior Technical Architect, Hexaware Technologies, in
East Brunswick, New Jersey.
The following code snippet uses Oracle analytic functions to generate factorials. This snippet generates a
factorial for each row number up to 20.
select rownum,
exp(sum(ln(rownum)) over (order by rownum)) Factorial
from user_objects
where rownum < 21;
This tip comes from Jony Safi, Database Administrator, Videotron Ltee, in Montreal, Canada.
This query lists information needed by a DBA to trace the use of the TEMP tablespace.
This tip comes from Jony Safi, Database Administrator, Videotron Ltee, in Montreal, Canada.
This query lists information needed by a DBA to trace the use of the TEMP tablespace.
This tip comes from Amit Zhankar, DBA, Tata Share Registry Limited, in Mumbai, India.
This tip selects a column from a table, weeds out the numeric characters, and returns the alphabetical
characters.
select
name ,
translate('.1234567890',name,'$')
from
Vtable
where
length(translate('1234567890','$'||name,'$')) = 10
/
This tip comes from Casimir Saternos, Systems Engineer, Trifecta Technologies Inc, in Allentown,
Pennsylvania.
As PL/SQL a code base for an application grows over time, the number of dependencies that exist can grow
and become difficult to manage. This can be especially difficult for the DBA being called upon to support a
legacy system that has had numerous independent developers contributing code. The following query can
be used to identify the objects that a given object is dependent upon:
FROM
FROM SYS.public_dependency s
from user_objects
where object_name=UPPER('&OBJECT_NAME')
)tree,
user_objects u
WHERE
tree.object_id = u.object_id
ORDER BY lvl
When prompted, enter the OBJECT_NAME of the object whose dependencies you want to identify.
The OBJECT_NAME can be a PACKAGE, PACKAGE BODY, or PROCEDURE. The OBJECT_NAME is the
name of the object at the root of the tree.
This tip provides an alternate way to get the name of the file, segment, or resource that's causing a wait,
with times.
Suppose you need the object_name, ..., from dba_extents for an event. Traditionaly you can look at block_id
(P1) and file_id (P2) from v$session_wait as follows:
SEGMENT_NAME PARTITION_NAME
------------------------ --------------
LOGSTDBY$APPLY_PROGRESS P0
Elapsed: 00:00:27.19
select
o.name as OBJECT_NAME,
o.subname as OBJECT_SUBNAME,
so.object_type as OBJECT_TYPE
from
sys.obj$ o,
sys.sys_objects so,
sys.seg$ s
where
s.file# = so.header_file
OBJECT_NAME OBJECT_SUBNAME
OBJECT_TYPE
------------------------------ ------------------------------
------------------
LOGSTDBY$APPLY_PROGRESS P0 TABLE
PARTITION
Elapsed: 00:00:00.13
This tip comes from Jaromir Nemec , consultant at DBN, in Vienna, Austria.
The general rule for performing an explain plan is that you can perform the explain plan only if you have
sufficient privileges to execute the statement. It means with only read rights you cannot explain, for example,
an INSERT statement or any other DML statement.
But there is a simple workaround, if your DBA--as a user that has sufficient privilegs--creates the following
procedure:
SQL> @test_explan
SQL> exec utl_explan.explan(-
> 'select * -
> from dual'-
> )
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------
--------
--------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
-------------------------------------------------------------!
-------
| 0 | SELECT STATEMENT | | | | |
| 1 | TABLE ACCESS FULL | DUAL | | | |
--------------------------------------------------------------------
9 rows selected.
You may now, because of definers rights of the procedure, perform explain plan on a statement that you
can't execute.
Don't forget that this is a workaround. Import the database statistics to your environment where you have full
rights and test and tune there.
This tip comes from Satyanarayana Josyula, Sr. Oracle DBA at Nexus Energy Software, in Reston, Virginia.
You can reset the serial numbers after each group break using a single query--without using any utilities.
This technique uses the ROWNUM returned by Oracle and resets the serial number at the beginning of
each group. Also this query shows how to suppress the repeating group values in the result set.
Table test
EMPNO NUMBER(3)
DEPT NUMBER(3)
NAME VARCHAR2(15)
WHERE a.deptno=b.deptno
This tip comes from Ajay Garg, a developer at Accenture Services Pvt. Ltd., in Bangalore, India.
UNDEF Owner
ACCEPT Owner PROMPT 'Enter Owner :'
UNDEF Table_Name
ACCEPT Table_Name PROMPT 'Enter Table Name :'
PROMPT
PROMPT Comments for Table &Table_Name.
SELECT COMMENTS
FROM ALL_TAB_COMMENTS
WHERE TABLE_NAME = UPPER('&Table_Name.')
AND Owner = UPPER('&Owner.') ;
SET HEADING ON
PROMPT
PROMPT Column Details for Table &Table_Name.
SELECT
ROWNUM "Sr No", T.COLUMN_NAME , T.Data_Type , T.DATA_LENGTH,
DECODE(T.Nullable, 'N' , 'NOT NULL' , 'Y', ' ') NULLABLE ,
T.Data_Default , C.Comments
FROM
ALL_TAB_COLS T , All_Col_Comments C
WHERE
T.OWNER = C.OWNER
AND T.TABLE_NAME = C.TABLE_NAME
AND T.COLUMN_NAME = C.COLUMN_NAME
AND T.TABLE_NAME = UPPER('&Table_Name.')
AND T.Owner = UPPER('&Owner.') ;
PROMPT
PROMPT PRIMARY KEY for Table &Table_Name.
select COLUMN_NAME
FROM ALL_CONS_COLUMNS
WHERE TABLE_NAME = UPPER('&Table_Name.')
AND Owner = UPPER('&Owner.')
AND CONSTRAINT_NAME = ( SELECT CONSTRAINT_NAME
FROM ALL_CONSTRAINTS
WHERE TABLE_NAME = UPPER('&Table_Name.')
AND CONS! TRAINT_T YPE = 'P'
AND Owner = UPPER('&Owner.')
)
ORDER BY POSITION
/
PROMPT
PROMPT INDEXES for Table &Table_Name.
CLEAR BREAKS
PROMPT
PROMPT FOREIGN KEYS for Table &Table_Name.
PROMPT
PROMPT CONSTRAINTS for Table &Table_Name.
PROMPT
PROMPT ROWCOUNT for Table &Table_Name.
SET FEEDBACK ON
PROMPT
PROMPT Tables That REFER to Table &Table_Name.
CLEAR BREAKS
PROMPT
PROMPT PARTITIONED COLUMNS for Table &Table_Name.
PROMPT
PROMPT PARTITIONS for Table &Table_Name.
PROMPT
PROMPT TRIGGERS for Table &Table_Name.
SELECT Trigger_Name
FROM All_Triggers
WHERE TABLE_NAME = UPPER('&Table_Name.')
AND Owner = UPPER('&Owner.') ;
PROMPT
PROMPT DEPENDANTS for Table &Table_Name.
CLEAR BREAKS
This tip comes from Eli Leiba, an Applications DBA at Israel Electric Co., in Haifa, Israel.
String tokenizing is an important string parsing function in both C and Java programming languages.
sbuf := '@0@11@222@3333@44444@555555@6666666@77777777@888888888';
sepr := '@';
istart := 1;
tokenizer (istart ,sepr,sbuf,sres,pos);
if (pos <> 0) then
dbms_output.put_line (sres);
end if;
while (pos <> 0)
loop
istart := pos;
tokenizer (istart ,sepr,sbuf,sres,pos );
dbms_output.put_line (sres);
end loop;
END sp_test_tokenizer;
/
This tip comes from Sanjay Ray, an Oracle Applications technical consultant in London, UK.
Note: This tip was written for use with Oracle8i. This code tip demonstrates a technique to track changes occurring in the unde
application, or runs a process,and the audit table will record the full details of how the tables were affected.
The information will include:
1) Table name and Unique ID(s) and values to identify the record
2) The event (INSERT, UPDATE, DELETE)
3) In case of UPDATE, the list of column names whose values have changed along with the old and new values
4) In case of INSERT or DELETE, column names and values from the record Inserted or Deleted
5) A Sequence number indicating the order in which the events occurred.
This procedure may be helpful in reverse engineering of code, or to get a better understanding of how an pplication process w
The process involves the following steps:
1) Creation of an audit table and a sequence number generator to supply the ID of the audit table
2) Generation of creation scripts for triggers on the tables likely to be modified by the Application Process (Also see Note #4 at
3) Creation of Triggers by running the spool file produced from Step 2
4) Run the Application Process or complete a transaction
5) Query the audit table to view the changes at the database level
Script:
--------
(This script assumes that TEST_TABLE1 and TEST_TABLE2 have already been created)
for i in 1..vt.count
loop
v_keys.delete;
--If no Unique Index exists, use the first column in the table
if v_keys.count = 0 then
select column_name into v_keys(1)
from all_tab_columns
where table_name=vt(i)
and column_id=1;
end if;
--For UPDATE, compare! each column and log details if any column values
--have changed. Compare only scallar values. Comment out other data types.
pr('if v_event in ('||kq||'U'||kq||') then');
pr('null;');
for c1 in (select column_name, data_type from all_tab_columns
where table_name = vt(i)
order by column_id )
loop
if c1.data_type in ('NUMBER', 'DATE', 'LONG', 'CHAR', 'VARCHAR2')
then
v_comm:=null;
else
v_comm:='--';
end if;
pr(v_comm||'if :old.'||c1.column_name||' is null and :new.'||c1.column_name||'
pr(v_comm||'or :new.'||c1.column_name||' is null and :old.'||c1.column_name||'
pr(v_comm||'or :old.'||c1.column_name||' <> :new.'||c1.column_name||' ');
pr(v_comm||'then');
pr(v_comm||'v_colval:=v_colval||'||kq||c1.column_name||'('||kq||'||:old.'||c1.
kq||';');!
--For INSERT, log the :new values of the first k_cols_disp columns
pr('if v_event in ('||kq||'I'||kq||') then');
pr('null;');
for c1 in (select column_name, data_type from all_tab_columns
where table_name = vt(i)
and column_id <= k_cols_disp
order by column_id )
loop
if c1.data_type in ('NUMBER', 'DATE', 'LONG', 'CHAR', 'VARCHAR2')
then
v_comm:=null;
else
v_comm:='--';
end if;
pr(v_comm||'v_colval:=v_colval||'||kq||c1.column_name||'='||kq||'||:new.'||c1.
end loop;
pr('end if;');
pr('end;');
pr('/');
pr('sho err;');
end loop;
end;
/
spo off
Testing:
--------------
Or you can generate the table name! s at runtime based on some criteria, e.g. for a particular schema.
5) The script does not check the ownership of the tables. So unique table name is assumed in the code. (Thus if you are dealin
6) Trigger name is generated by prefixing the table name with 'XX_' and adding '_T' at the end. Thus the trigger name for the t
necessary, change the k_prefix and k_suffix values in the master script.
7) The delimiter value is determined by k_dm variable which is set to an asterix '*' in the master script.
8) Format of a date value will be determined by database settings, which quite often exclude the time component. However co
to be reported to have been changed during an update, the displayed values (in column_val) bein! g the sa me (Seq#=10)
9) Code assumes you have the appropriate privileges to create the necessary objects. Sequence, Audit table and Triggers are
10) Ensure no trigger is created on the audit table xx_test_log!
This tip comes from Jayant Kulkarni, Senior Oracle DBA/Tech Lead, at Rapidigm, Inc., in Houston, TX.
NOTE: The following tip applies to Oracle9i Database. Oracle Database 10g provides new GUI and
command line analysis and manageability tools, including the SQL Access Advisor and SQL Tuning advisor,
that Oracle Database 10g DBAs should investigate as primary tools for managing optimizer stats analysis
and tuning operations.
Analyze The Analyzed: Are all my tables, indexes and their sub-objects analyzed?
One of the key pieces of information needed in performance tuning under a Cost Based Optimizer (CBO) is
to identify whether stats are run on all the tables, indexes, and their sub-objects (partitions and sub-
partitions).
If stats are not being run, the very first step is to run stats on the objects in question and provide the
optimizer all the information that is needed to choose and execute the most optimal execution plan.
However, getting this information in one single shot is pretty difficult and often a DBA has to query
DBA_TABLES, DBA_TAB_PARTITIONS, DBA_TAB_SUBPARTITIONS, DBA_INDEXES,
DBA_IND_PARTITIONS and DBA_IND_SUBPARTITIONS dictionary views to extract this information.
The following query attempts to consolidate this information in a report format and add warnings at
appropriate places so that the DBA can know in a glance what objects/sub-objects have stats missing on
them.
break on report
...
...
...
... some more rows
IRS |OD_XRATES | 0| 0| | 1| 0| 0|
IRS |WM_AR_INVOICE_ACTIVITY | 36| 0| | 2| 72| ! 0|
IRS |WM_CAF_FLAG_MV01 | 0| 0| | 2| 0| 0|
IRS |WM_CUST_COD_PLN_MV01 | 0| 0| | 1| 0| 0|
IRS |WM_CUST_DREF_MV01 | 0| 0| | | | |
IRS |WM_CUST_RELS | 8| 0| | | | |
IRS |WM_CUST_STATUS_CODE | 0| 0| | 4| 0| 0|
IRS |WM_DELINQUENT_ACCOUNTS_MV01 | 0| 0| | | | |
IRS |WM_MAS_CUST_LOC | 0| 0| | 1| 0| 0|
| |------|------------| |------|------|------------|
sum | | 820| 42| | 272| 1658| 248|
This tip comes from Galina Petrenko, Sr. IT Specialist, TPAS, in Voorhees, NJ.
We can convert and format alphabetical phone numbers using the TRANSLATE function.
Example:
----------------
def Phone=1-800-VERIZON
select TRANSLATE(UPPER('&Phone')
,'ABCDEFGHIJKLMNOPQRSTUVWXYZ)(-'
,'22233344455566677778889999'
) Phone
from dual;
PHONE
-------------
1-800-8374966
Now, note the size difference between the alphabetical and numeric phone numbers:
--
-- Check Size in a Database
-- get rid of formatting - could also be done via format masks
--
def PHONE="1(800)-CALLATT"
select
VSIZE('&PHONE') VSIZE_WORD,
VSIZE(
to_number( TRANSLATE( UPPER('&PHONE')
,'ABCDEFGHIJKLMNOPQRSTUVWXYZ)(-','222333444555666777! 78889999'
))
) VSIZE_NUMBER
from dual;
VSIZE_WORD VSIZE_NUMBER
---------- ------------
14 7
Now, if we create a function-based index on the alphabetical phone number column in our table, the
response will be faster since size of the data is smaller (almost half the size):
select ......
from ......
where ConvertPhone#(ABC_PHONE)=ConvertPhone#('1-866-CALLABC')
This tip comes from Sudhindra Chillarige, Software Engineer, Global Computer Enterprises, Inc., in Reston,
Virginia.
Everyone has a favorite script to find the active SQL statements. Here is one of mine.
It builds the information using an anonymous PL/SQL block. It reads the information of active sessions from
gv$session_wait and gv$session. (They have been made generic to support RAC instances, too.)
dbms_output.put_line('**************************************************
**************');
for y in (select sql_text
from gv$sqltext
where address = x.sql_address
and hash_value = x.sql_hash_value
and inst_id = x.inst_id
order by piece)
loop
dbms_output.put_line(y.sql_text);
end loop;
end;
end loop;
dbms_output.put_line('************** End re! port for sessions
waiting with current SQL ****************');
dbms_output.put_line(' ');
end;
/
This tip comes from Ajwat Ul-Hasan, Database Administrator/System Analyst, The
Carphonewarehouse in London, United Kingdom.
In Oracle9i, this script can restrict users logging into the database. In one table you provide
information about which users are allowed to log into the database. You can modify this script to allow
or block a user with respect to application, ip address, username, osuser, terminal, etc. It is a very
easy and efficient way of implementing security in database.
In the valid_user table you have to insert information about valid users, otherwise no user can log in to
the database. You can generate information about user connection by using information in user_audit
table.
This tip comes from Sudhindra Chillarige, Software Engineer, Global Computer Enterprises, Inc., in Reston,
Virginia.
Everyone has a favorite script to find the active SQL statements. Here is one of mine.
It builds the information using an anonymous PL/SQL block. It reads the information of active sessions from
gv$session_wait and gv$session. (They have been made generic to support RAC instances, too.)
And it pulls the information on the current SQL from gv$sqltext.
dbms_output.put_line('**************************************************
**************');
for y in (select sql_text
from gv$sqltext
where address = x.sql_address
and hash_value = x.sql_hash_value
and inst_id = x.inst_id
order by piece)
loop
dbms_output.put_line(y.sql_text);
end loop;
end;
end loop;
dbms_output.put_line('************** End re! port for sessions
waiting with current SQL ****************');
dbms_output.put_line(' ');
end;
/
This tip comes from Vishnu Bhavaraju, Oracle Lead DBA, Tata Consultancy Services, in Cincinnati, Ohio.
In Oracle8i, DBAs want to know how fast the tablespaces in their databases are growing so that they can
plan for additional disk space. At the time of database/tablespace creation, DBAs use their best estimates to
allocate optimal size to the tablespaces, but often need to resize the tablespaces frequently. Keeping
historical information also helps to predict the growth more accurately. The following set of scripts does that.
CronJob:
00 07 * * * /opt/oracle/tools/scripts/TSStats pfin >>
/tmp/TSStats_pfin.log
#!/bin/ksh
ExitHere()
{
if [ ! $STATUS = "0" ] ; then
cat ${Output} | mailx -s "TS Statistics Job: $ORACLE_SID :
FAILED" $MAIL_TO
else
cat ${Output} | mailx -s "TS Statistics Job: $ORACLE_SID :
SUCCESS" $MAIL_TO
fi
}
ProgName=`basename ${0}`
LogFile="${ProgName}"
SqlFile="/technology/opt/oracle/tools/sql/${ProgName}"
MAIL_TO="vishnu.murthy@ge.com"
Output="/technology/tmp/${LogFile}.${LOGNAME}"
if [ ! -z ${1} ] ; then
ORACLE_SID=${1}
export ORACLE_SID
if [ ! -z $ORACLE_HOME ] ; th en
PATH=$PATH:$ORACLE_HOME/bin
export PATH
if [ -e ${SqlFile}.sql ] ; then
else
echo "${SqlFile}.sql doesnot exist" >> ${Output}
STATUS=1
ExitHere
fi
else
echo "No entry found in oratab for ${ORACLE_SID} " >>
${Output}
STATUS=1
ExitHere
fi
else
echo "Oracle sid is not supplied..." >> ${Output}
echo "usage: ${ProgName} " >> ${Output}
STATUS=1
ExitHere
fi
BEGIN
DELETE FROM DBMONITOR.TSREPORT
WHERE REPORT_DATE < SYSDATE - 90;
COMMIT;
DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT || ' ROWS ARE INSERTED INTO
DBMONITOR.TSREPORT TABLE');
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('FATAL ERROR:Failed to Collect TableSpace
Stats');
RAISE;
END;
/
exit;
It prompts for the report start date and report end date
which need to be entered in 'DD-MON-YY' format only; otherwise, the script will
terminate immediately. If the user chooses not to enter the dates, the script
will use the minimum and maximum report_date from dbmonitor.tsreport as start
and end dates.
Author : Vishnu
History: 16-Sep-03 Vishnu Created
spool log
undef start_date
Prompt the user to enter the start and end dates for the
period of report to be generated.
If the user doesn't enter any dates, choose
default values as least and highest dates from the tsreport table.
select
decode('&&start_date',null,min(report_date),min(to_date(upper('&&start_d
ate'),'DD-MON-YY')))
Date_Start from dbmonitor.tsreport;
select
decode('&&end_date',null,max(report_date),max(to_date(upper('&&end_date'
),'DD-MON-YY')))
Date_End from dbmonitor.tsreport;
btitle on
ttitle on
set linesize 200
spool off
btitle on
ttitle on
spool '&instance_name'_Growth_Report.htm
set markup html on
spool off
clear breaks;
clear computes;!
btitle off
ttitle off
undef start_date
undef end_date
set feedback on
set verify on
This tip comes from Yakov Shlafman, DBA, Open Distributed Solutions, Inc. in Jamison,
Pennsylvania.
This script shows how to extract unique "valid" accounts from a group of duplicates using Oracle's
analytical function ROW_NUMBER().
According to the specification, the Customer_Id column should have only one Account_id.
In cases where a single customer has more than one account, we need to flag the "valid" account so
the migration process knows which account to load into the new system. The "valid" account is the
"oldest" account in a particular group and can be determined by getting the MIN(Account_id) of that
group.
There is one additional condition that complicates the task — in each group of duplicates the "oldest"
account with an open account bill plan gets priority over the "oldest" account without a plan.
After intermediate steps of identifying duplicated accounts and among them the accounts with account
bill plan, we have the table— table account_duplicates_flagged. We are going to use this table with a
sample population.
Step 1:
Step 2:
3. Customer has multiple accounts and does not have an account bill plan.
commit;
Step 3: Populate table Accounts_To_Migrate_Driver with unique data &151; customers with only one
selected Account_id.
select *
from Accounts_To_Migrate_Driver
order by CUSTOMERENTITYID;
ACCOUNTID CUSTOMERENTITYID
--------- ----------------
5 1
52 2
7 3
10 4
316 5
3 8
6 rows selected.
Step 4: Populate table Accounts_To_Delete_Driver with all duplicates to delete.
select *
from Accounts_To_Delete_Driver
order by CUSTOMERENTITYID, ACCOUNTID;
ACCOUNTID CUSTOMERENTITYID
--------- ----------------
128 2
551 2
558 2
77 3
444 3
771 3
6 4
9 4
11 4
12 4
109 4
315 5
12 rows selected.
You should be able to run this script on Oracle8i and later releases.
Here's a function to calculate the number of seconds elapsed in a given period of time.
create or replace function how_many_seconds (
p_startdate date,
p_enddate date,
p_starttime varchar2,
p_endtime varchar2
)
return number
is
--
mv_sysdate varchar(8) := to_char(sysdate, 'rrrrmmdd');
mn_return_value number;
mn_seconds_per_day number;
mn_total_days number;
mn_seconds_in_start_day number;
mn_seconds_in_end_day number;
--
begin
--
mn_seconds_per_day := to_char(to_date(mv_sysdate || p_endtime,
'rrrrmmddhh24mi'), 'sssss') -
to_char(to_date(mv_sysdate || p_starttime, 'rrrrmmddhh24mi'),
'sssss');
mn_total_days := (trunc(p_enddate) - trunc(p_startdate)) - 1;
mn_seconds_in_start_day := to_char(to_date(mv_sysdate ||
p_endtime, 'rrrrmmddhh24mi'), 'sssss') -
to_char(p_startdate, 'sssss');
mn_seconds_in_end_day := to_char(p_enddate, 'sssss') -
to_char(to_date(mv_sysdate || p_starttime, 'rrrrmmddhh24mi'),
'sssss');
--
if mn_total_days < 0 then
mn_total_days := 0;
mn_seconds_in_start_day := 0;
end if;
--
if mn_seconds_in_start_day < 0 then
mn_seconds_in_start_day := 0;
end if;
--
if mn_seconds_in_end_day < 0 then
mn_seconds_in_end_day := 0;
end if;
--
mn_return_value := mn_seconds_in_start_day + (mn_total_days *
mn_seconds_per_day) + mn_seconds_in_end_day;
--
return mn_return_value;
--
end;
/
select how_many_seconds(to_date('200404281900',
'rrrrmmddhh24mi'),
to_date('200404291000', 'rrrrmmddhh24mi'), '0900', '1500')
"Seconds"
from dual!
/
!
Seconds
----------
3600
This tip comes from Mir Mirhashimaali, Oracle Systems Manager, Rice University in Houston, Texas.
Here's a function to calculate the number of seconds elapsed in a given period of time.
create or replace function how_many_seconds (
p_startdate date,
p_enddate date,
p_starttime varchar2,
p_endtime varchar2
)
return number
is
--
mv_sysdate varchar(8) := to_char(sysdate, 'rrrrmmdd');
mn_return_value number;
mn_seconds_per_day number;
mn_total_days number;
mn_seconds_in_start_day number;
mn_seconds_in_end_day number;
--
begin
--
mn_seconds_per_day := to_char(to_date(mv_sysdate || p_endtime,
'rrrrmmddhh24mi'), 'sssss') -
to_char(to_date(mv_sysdate || p_starttime, 'rrrrmmddhh24mi'),
'sssss');
mn_total_days := (trunc(p_enddate) - trunc(p_startdate)) - 1;
mn_seconds_in_start_day := to_char(to_date(mv_sysdate ||
p_endtime, 'rrrrmmddhh24mi'), 'sssss') -
to_char(p_startdate, 'sssss');
mn_seconds_in_end_day := to_char(p_enddate, 'sssss') -
to_char(to_date(mv_sysdate || p_starttime, 'rrrrmmddhh24mi'),
'sssss');
--
if mn_total_days < 0 then
mn_total_days := 0;
mn_seconds_in_start_day := 0;
end if;
--
if mn_seconds_in_start_day < 0 then
mn_seconds_in_start_day := 0;
end if;
--
if mn_seconds_in_end_day < 0 then
mn_seconds_in_end_day := 0;
end if;
--
mn_return_value := mn_seconds_in_start_day + (mn_total_days *
mn_seconds_per_day) + mn_seconds_in_end_day;
--
return mn_return_value;
--
end;
/
select how_many_seconds(to_date('200404281900',
'rrrrmmddhh24mi'),
to_date('200404291000', 'rrrrmmddhh24mi'), '0900', '1500')
"Seconds"
from dual!
/
!
Seconds
----------
3600
This tip comes from Galina Petrenko, Sr. IT Specialist, TPAS Systems Development in Voorhees, New
Jersey.
To generate comma or pipe delimited output for tools such as Excel, Access, and so on while spooling from
SQL*Plus, use settings from SQL*Plus such as:
SET COLSEP ,
or
SET COLSEP |
Example:
Output:
set colsep |
select
object_name,
object_type,
status,
created
from all_objects
where owner='PUBLIC'
and rownum < 10 /* 9 rows for Sample Output */
;
Output:
select
object_name,
status,
created
from all_objects
where owner='PUBLIC'
and rownum < 10 /* 9 rows for Sample Output */
;
Output:
This tip comes from Robert Ware, DBA, TEK Systems in St. Louis, Missouri.
The following lists the top 10 segments by V$SEGSTAT statistic name (since the instance was started). I
usually employ this method to help determine which segments are responsible for most of the Logical I/O or
Buffer Busy Waits on my system. Once I have this information, then I will search for SQL statements to tune
in either my statspack report or by querying V$SQL.
set feed off pagesize 42 linesize 132 veri off echo off pause off
from v$segstat
order by statistic_name)
prompt
select statname
from v$segstat
! END )
set head on
DO.object_name,
DO.object_type,
SS.value,
SS.statistic_name,
where RN <= 10
prompt
ttitle off
set feed on
This tip comes from Navroz Kapadia, DBA, Economics & Business Cluster in Toronto, Ontario, Canada.
This script will generate a SQL*Loader control file for any specified table, which can then be customized as
per individual needs. Ensure it is run by a user with SELECT_CATALOG_ROLE. Parameter 1 is the owner
of the table. Parameter 2 is the tablename.
set embedded on
set lines 80
spool c:\your_path_name\&&2..ctl
select
'load data
replace
trailing nullcols'
(case when a.column_id < max(b.column_id) then ',' else ')' END)
order by a.column_id
spool off
set verify on
set heading on
set pages 64
set lines 80
set feedback 6
undefine 1
undefine 2
Suppose you run a relatively long PL/SQL procedure that processes several rows, and you want to track its
progress. The following procedure lets you see the total number of rows and the current row being
processed, using client_info in the V$SESSION view.
AS
begin
select count(*)
into L_TOTAL
from all_objects;
begin
L_CNT := L_CNT + 1;
end;
end loop;
DBMS_APPLICATION_INFO.SET_CLIENT_INFO ( 'Done');
end PROC_MYPROGRESS;
Execute the above procedure in a SQL session and query the V$SESSION table with the following SQL.
from v$session
This can be easily modified to specific procedures/jobs to track that particular session.
This tip comes from Marco Gilbert, DBA, MRQ in Ste-Foy, Quebec, Canada.
When you are working with UNDO (instead of ROLLBACK) there are two important things to consider: 1.)
the size of the UNDO tablespace, and 2.) the UNDO_RETENTION parameter.
1) You can choose to allocate a specific size for the UNDO tablespace and then set the
UNDO_RETENTION parameter to an optimal value according to the UNDO size and the database activity. If
your disk space is limited and you do not want to allocate more space than necessary to the UNDO
tablespace, this is the way to proceed. The following query will help you to optimize the UNDO_RETENTION
parameter :
from v$datafile a,
v$tablespace b, dba_tablespaces c
v$parameter f,
from v$undostat) g
2) If you are not limited by disk space, then it would be better to choose the UNDO_RETENTION time that is
best for you (for FLASHBACK, etc.). Allocate the appropriate size to the UNDO tablespace according to the
database activity:
v! $tablespace b,
dba_tablespaces c
v$parameter e,
v$parameter f,
from v$undostat) g
;
The previous query may return a "NEEDED UNDO SIZE" that is less than the "ACTUAL UNDO SIZE". If this
is the case, you may be wasting space. You can choose to resize your UNDO tablespace to a lesser value
or increase your UNDO_RETENTION parameter to use the additional space.
WARNING: Because these queries use the V$UNDOSTAT statistics, run the queries only after the
database has been running with UNDO for a significant and representative time.
This tip comes from Devanshi Parikh, Sr. DBA, Ernst and Young LLP in Lyndhurst, New Jersey.
System generated (redundant) check constraints can really drain the performance of a database. But
sometimes, such as when using third party tools with Oracle, it becomes impossible to avoid them. I have
developed a script, which is actually a UNIX Korn shell script, that retrives information from the Oracle
dictionary tables, and then formats the output to generate SQL statements that can be executed in the
database. Also, the script puts you in more control since, because you decide which and how many tables
you are interested in.
To run the script, first create a text file with one column, and one or more entries in the form tablename(
Uppercase ). The file can include any number of table names. The script accepts this text file's name as
the input argument. Each table listed in the input file is read and passed to Oracle Database to retrive the
relevent information.
Note that I have used hard coded the schema name and password in the script, which you can edit.
For each table three files in the format _.tmp, _.txt and _.sql are generated by the script in the working
directory. The .tmp and .txt files are intermidiate files while the .sql files contain the actual drop constraint
statements. The script leaves out the originally created check constraints; it generates statements for the
constraints that are genuine duplicates.
The script assumes that each column originally did not have more than 2 distinct SEARCH_CONDITION
values. (This is true in most cases, because the columns end up having a NOT NULL and a LENGTH
condition in the SEARCH_CONDITION.) In this kind of a scenerio, if data migrations occur between
databases, with the CONSTRAINTS=N clause missing, you end up with lots of duplicate check constraints.
#!/us! r/bin/ksh
# search.sh
#
INFILE=$1
infile=`cat ${INFILE}`
do
rm ${TAB_NAME}_${ORACLE_SID}.txt
rm ${TAB_NAME}_${ORACLE_SID}.tmp
rm ${TAB_NAME}_${ORACLE_SID}.sql
spool ${TAB_NAME}_${ORACLE_SID}.tmp
select a.constraint_name,b.column_name,search_condition
order by b.column_name,last_change;
spool off
exit
rows`
column_name='aa'
constraint_name='aa'
do
if [ ${column_name_next} = ${column_name} ]
then
${constraint_name_n
fi
column_name=${column_name_next}
constraint_name=${constraint_name_next}
done
done
exit
Tip of the Week
Tip for Week of March 8, 2004
Use chr(9) for fewer spaces and chr(160) for more spaces.
Example:
prompt
begin
dbms_output.put_line('This is 1st message Line and next line is
blank.');
dbms_output.put_line(chr(0));
dbms_output.put_line(chr(0));
end;
prompt
------------------------------------------------------------------------
----------------------------------------
Output:
This tip comes from Ramesh Periyasamy, Programmer/Analyst, in Iselin, New Jersey.
This function will split an input string separated by commas into a string enclosed with single quotes. This is
helful in applying conditions in dynamic SQL.
dyn_string1 Function:
t varchar2(2):=',';
t1 varchar2(2):='''';
t2 varchar2(32767);
t_check number(10);
a varchar2(32767);
begin
a:=ab;
t_check:=instr(a,',');
if t_check!=0 then
t2:=t1||t||t1;
a:=replace(a,',',t2);
a:='('||''''||a||''''||')';
-- dbms_output.put_line(a);
else
a:=a;
a:='('||''''||a||''''||')';
end if;
return a;
END ;
Example:
select dyn_string1('2334,3!
45,5656,6767,7878,78989,8989,8989,9090,9090,90,90,9090,90,090,,9090,909)
from dual
Output:
DYN_STRING1('2334,345,5656,6767,7878,78989,8989,8989,9090,9090,90,90,909
0,90,090,9090,909)
------------------------------------------------------------------------
------------------
('2334','345','5656','6767','7878','78989','8989','8989','9090','9090','
90','90','9090','90','090','','9090','909')
AS
B date;
C date;
actcode VARCHAR2(32767);
sql_stmt varchar2(32767);
Begin
a:=dyn_string1(actcode);
b:=fr_date;
c:=to_date;
sql_stmt:='INSERT INTO Table2 select A1.NYCWAY_CASE_NUMBER
FROM table1 a
end;
We get a lot of tips on managing date and time date. Here's part two of a collection of some date/time
tips.
We get a lot of tips on managing date and time data. Here's part one of a collection of some date/time
tips.
Use this simple SQL script--lay.sql--to generate the layout for the spooled file. Run the script before spooling
the table to get the layout.
Layout contains :
------------------
Column Name,
Data Type,
Length of Column,
Start Position of Column,
End Position of Column,
SQL*LOADER script,
R/L of Rec is "End Position" in Last Line
Paste the following script into c:\lay.sql, and run this script at the SQL prompt.
SQL>spool c:\emp.lay
SQL>@c:\lay.sql
Note the R/L (End Pos in Last Line) from emp.lay. Now you are ready to 'spool set' the following and change
the line size with R/L:
Using LogMiner
This tip comes from Frank Pantaleo, Database Technologist, in Rochester, NY.
This tip is about using LogMiner to replicate data between a production instance and a remote instance. The
biggest advantage is this technique does not require any changes to the production instance if you are just
capturing inserts. If you want to capture updates/deletes there are issues in Oracle8i. Oracle8i does not
capture key information in logs as it does in Oracle9i. I have a work around for this, but it does not work very
well for high volume tables.
This body of work that follows was born out of a desire to replicate data out of production. Of course we
needed to do this while minimizing the effect to production. The best way to do this was to leverage API’s
that Oracle made available in Oracle8i. Some or all of this logic provided becomes unnecessary in Oracle9i
with the advent of Oracle Streams. (Although I would contend that this provides a better level of control. I
made a pitch to a technical community that I am involved in. The pitch was based on a article from George
Jucan at http://www.opendatasys.com . The article was called "Using Oracle LogMiner as a Data Replication
Utility". The article explains the way a program or set of programs could make use of this api. Our business
had already leveraged information available in the LogMiner to track activity in an application. )
There are some C applications are involved in this as well. I am only supplying the PL/SQL and C Oracle
external functions as I feel this is enough to get started. Some of these file and directory procdures were
created to reproduce functions that are now available in Oracle9i.
Dir_proc: C Oracle external application to get a list of all files in a unix directory
File_proc: C Oracle external application to determine the existence of a UNIX file
File_del_proc: C oracle external application to delete a file in /tmp
Get_ora_tab: Function that drives the diy$oratab view
Logminer_stats: Procedure that returns counts of local logmnr_contents store
Load_logminer: The workhorse of the application. Identifies, Extracts, and deletes archive log into local store
For Oracle8i LogMiner, I have another program that creates a known state. Oracle8i LogMiner captures the
rowid for update and deletes, but Oracle9i LogMiner captures additional information on deletes and updates,
including whether the table being captured has a primary/unique key.
For Oracle8i LogMiner, I have another program that creates a known state:
The initial table state is captured from the source instance, including the rowid of each row from the source
table, and I capture this in a column called drowid. The drowid is used to apply the update or delete to the
destination table data. Once a state is captured, I can then move on to the logic supplied here and extract
changes from a set of archive logs.
So the process is:
1. Enable archive logging in source instace.
2. Create a known state--this is only necessary in Oracle8i and then only if you need to worry about
update/deletes.
3. Copy all archive logs from source to the machine where the destination instance lives; this process is
ongoing afterward.
4. Change the init.ora of the destination instance to have log_archive_dest point to the archive logs that
have been captured from the source instance.
5. At regular intervals:
a. run the load_logminer proc provided
b. apply the dml in logmnr_contents to the destination instance
c. update checkpoint_change# in lmstate_checkpoint as each dml is applied
d. commit after the scn changes in logmnr_contents table
-------------------------- pl/sql source --------------------
First I create a schema with dba rights (lmdba):
Ora_Tab( Ora_Tab.Last ) :=
Oratab_Row_Type( rtrim(v_file_name));
Exception
When NO_DATA_FOUND Then
b_Read := FALSE;
End;
End Loop;
Utl_File.FClose( f_Handle );
end if;
file_del_proc(tmp_file);
Return Ora_Tab;
End;
/
Create Or Replace View DIY$ORATAB
As Select * From Table( Cast( GET_ORATAB() As Oratab_Type ) );
/
CREATE OR REPLACE PROCEDURE "LOGMINER_STATS" (insert_count out
integer,delete_count out integer, update_count out integer,total_count
out integer) is
EMPTY_LOGMNR_CONTENTS exception;
PRAGMA EXCEPTION_INIT(EMPTY_LOGMNR_CONTENTS, -1306);
cursor the_csr is Select count(*) the_count,operation
from LOGMNR_contents,lmsubscribe b
where seg_owner = b.owner
and seg_name = b.table_name
and operation in ('INSERT','DELETE','UPDATE')
group by operation;
begin
insert_count :=0;
update_count :=0;
delete_count :=0;
total_count :=0;
for the_rec in the_csr loop
if the_rec.operation = 'INSERT' then
insert_count := the_rec.the_count;
elsif the_rec.operation = 'DELETE' then
delete_count := the_rec.the_count;
elsif the_rec.operation = 'UPDATE' then
updat
This tip comes from Sanjay Ray, Oracle Applications Technical Consultant in Sydney, Austrailia.
This is an extension to the code tip that I supplied on 21 December 2003, "Comparing Contents of Two
Tables with Identical Structure." The following script highlights the columns that are different in the two
tables, so there is no need to compare each column individually. The columns values may optionally be
displayed as well.</SPAN< p> This script generates a spool file that can be run from a SQL*Plus session to
list the differences between 2 tables with identical structure.
This can be useful if you need to compare two similar tables across different schemas (or different
databases, in which case you will need to create a local view using a database link), or to compare a table
with itself at different points in time, such as before and after an update through an application to track how a
table is affected. It reports whether a record is present in one but not in the other table, or if the same key is
present in both tables but non-key columns have different values.
undefine TABLE1
undefine TABLE2
define g_table1 = '&&TABLE1'
define g_table2 = '&&TABLE2'
set verify off
set feedback off
set serveroutput on size 1000000
set linesize 132
set trimspool on
spo temp_file.sql
declare
v_owntab1 varchar2(255) := '&&g_table1';
v_owntab2 varchar2(255) := '&&g_table2';
v_own1 varchar2(255);
v_own2 varchar2(255);
v_tab1 varchar2(255);
v_tab2 varchar2(255);
v_dot1 number := 0;
v_dot2 number := 0;
type t_cols is table of varchar2(255) index by binary_integer;
v_cols1 t_cols;
v_cols2 t_cols;
v_keys t_cols;
v_out1 varchar2(255);
v_out2 varchar2(255);
kq CONSTANT varchar2(1) := '''';
v_ind number := 0;
v_str varchar2(2000):=null;
v_ind_found boolean := FALSE;
v_ind_colno number := 0;
v_is_key boolean := FALSE;
v_nonkey number := 0;
procedure print_cols (p_cols in t_cols) is
begin
for i in 1..p_cols.count
loop
dbms_output.put_line(','||p_cols(i)); end loop;
end print_cols;
begin
v_dot1 := instr(v_owntab1, '.');
v_dot2 := instr(v_owntab2, '.');
select column_name
bulk collect into v_cols1
from all_tab_columns
where table_name = v_tab1
and owner = nvl(v_own1, user)
order by column_id;
select column_name
bulk collect into v_cols2
from all_tab_columns
where table_name = v_tab2
and owner = nvl(v_own2, user)
order by column_id;
--Outer select
dbms_output.put_line('select * from ( ');
--Main select (key attributes)
dbms_output.put_line('select ');
for c1 in (
select b.column_name
from all_indexes a, all_ind_columns b
where a.owner=b.index_owner
and a.index_name=b.index_name
and a.uniqueness = 'UNIQUE'
and a.table_owner = nvl(v_own1, user)
and a.table_name = v_tab1
order by b.index_name, b.column_position
)
loop
v_ind_found := TRUE;
v_keys(nvl(v_keys.count, 0)+1):=c1.column_name;
dbms_output.put_line('nvl(a.'||c1.column_name||', b.'||
c1.column_name||') '||c1.column_name||',');
end loop;
/*
--To display column list with values, uncomment Section 2
--Start of Section 2 : Column List with values
if v_nonkey = 1 then
dbms_output.put_line('decode(a.'||v_cols1(i)||',b.'||v_cols1(i)||',
null,'||kq||v_cols1(i)
||'=('
||kq||'||a.'||v_cols1(i)||'||'||kq||','
||kq||'||b.'||v_cols1(i)||'||'||kq||')'||kq
||')');
else
dbms_output.put_line('||'||kq||','||kq||'||'||'decode(a.'||
v_cols1(i)||',b.'||v_cols1(i)||', null,'||kq||v_cols1(i)
||'=('
||kq||'||a.'||v_cols1(i)||'||'||kq||','
||kq||'||b.'||v_cols1(i)||'||'||kq||')'||kq
||')');
end if;
--End of Section 2 : Column List with values
*/
end if;
end loop;
dbms_output.put_line('COL_LIST');
--from clause
dbms_output.put_line('from '||nvl(v_own1, user)||'.'||v_tab1||' a
');
dbms_output.put_line('full outer join '||nvl(v_own2, user)||'.'||
v_tab2||' b ');
dbms_output.put_line('on (');
--Where condition
for i in 1..v_keys.count
loop
if i = 1 then
dbms_output.put_line('a.'||v_keys(i)||'=b.'||v_keys(i));
else
dbms_output.put_line('and a.'||v_keys(i)||'=b.'||v_keys(i));
end if;
end loop;
dbms_output.put_line(')');
dbms_output.put_line(';');
end;
/
spo off
set feedback on
Testing:
This tip comes from Pasupuleti Sailaja, in Hyderabad, Andhra Pradesh, India.
declare
rs integer;
cur integer;
rp integer;
trs integer;
n integer;
un varchar2(30);
begin
dbms_output.put_line(rpad('Table Name',40)||' Number of Rows
Created Date');
dbms_output.put_line(rpad('-',73,'-'));
cur:= dbms_sql.open_cursor;
for t in (select object_name, created from user_objects
where object_type='TABLE') loop
dbms_sql.parse(cur,'select count(*) from ' || t.object_name,
dbms_sql.v7);
dbms_sql.define_column(cur, 1, rs);
rp:= dbms_sql.execute(cur);
n:=dbms_sql.fetch_rows(cur);
dbms_sql.column_value(cur, 1, rs);
dbms_output.put_line(rpad(t.object_name,48,'.')||
rpad(rs,15,'.')||t.created);
end loop;
dbms_sql.close_cursor(cur);
select count(*) into n from tab where tabtype='TABLE';
select user into un from dual;
dbms_output.put_line(rpad('-',73,'-'));
dbms_output.put_line(un||' User contain '||n||' Table(s)');
end;
/
------------------------------------------------------------------------
-
ACCTS...........................................5..............29-
JUN-03
ACCT_ADDRS......................................5..............29-
JUN-03
BONUS...........................................0..............09-
AUG-00
CHESS_SAVE......................................0..............29-
JUN-03
CHESS_SAVE_BOARDSTATE...........................0..............29-
JUN-03
CHESS_SAVE_CAPTURED.............................0..............29-
JUN-03
CHESS_SAVE_PLAYER...............................0..............29-
JUN-03
CITIES..........................................205............29-
JUN-03
COMPANY_SUMMARY.................................3..............29-
JUN-03
CUSTOMER........................................9..............09-
AUG-00
CUSTOMERS.......................................14.............29-
JUN-03
DEMOKIT_CLASSES.................................9..............29-
JUN-03
DEMOKIT_DEMOS...................................23.............29-
JUN-03
DEMOKIT_DEMO_SCRIPTS............................14.............29-
JUN-03
DEMOKIT_INSTALLED_SCRIPTS.......................5..............29-
JUN-03
DEMOKIT_SCRIPTS.................................10.............29-
JUN-03
DEPT............................................4..............09-
AUG-00
DUMMY...........................................1..............09-
AUG-00
DUPEMP..........................................7168...........12-
AUG-00
EMP.............................................14.............09-
AUG-00
FFI$FUNCTION....................................2..............29-
JUN-03
FFI$FUNCTIONARGS................................10.............29-
JUN-03
FFI$LIBRARY.....................................1..............29-
JUN-03
FFI$TYPEDEF.....................................14.............29-
JUN-03
FUNDS...........................................5..............29-
JUN-03
FUND_CONTRIB....................................16.............29-
JUN-03
FUND_XACT.......................................45.............29-
JUN-03
F_EMPCOMP.......................................2..............29-
JUN-03
F_XACT_TYPE.....................................7..............29-
JUN-03
GAME_SEMAPHORE..................................0..............29-
JUN-03
INDCAT..........................................11.............29-
JUN-03
INVINFO.........................................5..............29-
JUN-03
INVREQUEST......................................12.............29-
JUN-03
ITEM............................................0..............09-
AUG-00
MENU_CAT........................................7..............29-
JUN-03
MENU_ITM........................................35.............29-
JUN-03
MODE_BUTTON.....................................9..............29-
JUN-03
ORD.............................................21.............09-
AUG-00
ORDER_HISTORY...................................5..............29-
JUN-03
ORDPICT.........................................21.............29-
JUN-03
PORTFOLIO.......................................39.............29-
JUN-03
PRICE...........................................17.............09-
AUG-00
PRODUCT.........................................10.............09-
AUG-00
RCL_CLASSIFICATIONS.............................6..............29-
JUN-03
RCL_COMPONENTS..................................7..............29-
JUN-03
RCL_COMPONENT_DEPENDANCIES......................6..............29-
JUN-03
RCL_FRAGMENTS...................................31.............29-
JUN-03
RCL_INSTRUCTIONS................................57.............29-
JUN-03
RCL_INSTRUCTIONS_TEXT...........................520............29-
JUN-03
RCL_MODULES.....................................31.............29-
JUN-03
SALES_REVENUE...................................16.............29-
JUN-03
SALGRADE........................................5..............09-
AUG-00
STOCKS..........................................328............29-
JUN-03
STOCK_HISTORY...................................11.............29-
JUN-03
TABLE_CONFIG....................................11.............29-
JUN-03
USA.............................................50.............29-
JUN-03
------------------------------------------------------------------------
-
SCOTT User contain 56 Table(s)
This tip comes from Pasupuleti Sailaja, in Hyderabad, Andhra Pradesh, India.
declare
rs integer;
cur integer;
rp integer;
trs integer;
n integer;
un varchar2(30);
begin
dbms_output.put_line(rpad('Table Name',40)||' Number of Rows
Created Date');
dbms_output.put_line(rpad('-',73,'-'));
cur:= dbms_sql.open_cursor;
for t in (select object_name, created from user_objects
where object_type='TABLE') loop
dbms_sql.parse(cur,'select count(*) from ' || t.object_name,
dbms_sql.v7);
dbms_sql.define_column(cur, 1, rs);
rp:= dbms_sql.execute(cur);
n:=dbms_sql.fetch_rows(cur);
dbms_sql.column_value(cur, 1, rs);
dbms_output.put_line(rpad(t.object_name,48,'.')||
rpad(rs,15,'.')||t.created);
end loop;
dbms_sql.close_cursor(cur);
select count(*) into n from tab where tabtype='TABLE';
select user into un from dual;
dbms_output.put_line(rpad('-',73,'-'));
dbms_output.put_line(un||' User contain '||n||' Table(s)');
end;
/
------------------------------------------------------------------------
-
ACCTS...........................................5..............29-
JUN-03
ACCT_ADDRS......................................5..............29-
JUN-03
BONUS...........................................0..............09-
AUG-00
CHESS_SAVE......................................0..............29-
JUN-03
CHESS_SAVE_BOARDSTATE...........................0..............29-
JUN-03
CHESS_SAVE_CAPTURED.............................0..............29-
JUN-03
CHESS_SAVE_PLAYER...............................0..............29-
JUN-03
CITIES..........................................205............29-
JUN-03
COMPANY_SUMMARY.................................3..............29-
JUN-03
CUSTOMER........................................9..............09-
AUG-00
CUSTOMERS.......................................14.............29-
JUN-03
DEMOKIT_CLASSES.................................9..............29-
JUN-03
DEMOKIT_DEMOS...................................23.............29-
JUN-03
DEMOKIT_DEMO_SCRIPTS............................14.............29-
JUN-03
DEMOKIT_INSTALLED_SCRIPTS.......................5..............29-
JUN-03
DEMOKIT_SCRIPTS.................................10.............29-
JUN-03
DEPT............................................4..............09-
AUG-00
DUMMY...........................................1..............09-
AUG-00
DUPEMP..........................................7168...........12-
AUG-00
EMP.............................................14.............09-
AUG-00
FFI$FUNCTION....................................2..............29-
JUN-03
FFI$FUNCTIONARGS................................10.............29-
JUN-03
FFI$LIBRARY.....................................1..............29-
JUN-03
FFI$TYPEDEF.....................................14.............29-
JUN-03
FUNDS...........................................5..............29-
JUN-03
FUND_CONTRIB....................................16.............29-
JUN-03
FUND_XACT.......................................45.............29-
JUN-03
F_EMPCOMP.......................................2..............29-
JUN-03
F_XACT_TYPE.....................................7..............29-
JUN-03
GAME_SEMAPHORE..................................0..............29-
JUN-03
INDCAT..........................................11.............29-
JUN-03
INVINFO.........................................5..............29-
JUN-03
INVREQUEST......................................12.............29-
JUN-03
ITEM............................................0..............09-
AUG-00
MENU_CAT........................................7..............29-
JUN-03
MENU_ITM........................................35.............29-
JUN-03
MODE_BUTTON.....................................9..............29-
JUN-03
ORD.............................................21.............09-
AUG-00
ORDER_HISTORY...................................5..............29-
JUN-03
ORDPICT.........................................21.............29-
JUN-03
PORTFOLIO.......................................39.............29-
JUN-03
PRICE...........................................17.............09-
AUG-00
PRODUCT.........................................10.............09-
AUG-00
RCL_CLASSIFICATIONS.............................6..............29-
JUN-03
RCL_COMPONENTS..................................7..............29-
JUN-03
RCL_COMPONENT_DEPENDANCIES......................6..............29-
JUN-03
RCL_FRAGMENTS...................................31.............29-
JUN-03
RCL_INSTRUCTIONS................................57.............29-
JUN-03
RCL_INSTRUCTIONS_TEXT...........................520............29-
JUN-03
RCL_MODULES.....................................31.............29-
JUN-03
SALES_REVENUE...................................16.............29-
JUN-03
SALGRADE........................................5..............09-
AUG-00
STOCKS..........................................328............29-
JUN-03
STOCK_HISTORY...................................11.............29-
JUN-03
TABLE_CONFIG....................................11.............29-
JUN-03
USA.............................................50.............29-
JUN-03
------------------------------------------------------------------------
-
SCOTT User contain 56 Table(s)
In a previous tip, Fast Reset Sequences, I showed how to reset a sequence to MinValue with few calls to the
data dictionary (SQL and PL/SQL implementations). The following script below is another approach to
achiev the same result with even fewer calls. This technique is very useful for environments with the heavy
use of sequences.
Script:
-------
-- Return Old(Current) Values Back such as Min_Value anc Cache Size (if
exists) alter sequence &SeqOwner..&SeqName increment by
&Seq_Increment_By MinValue &Seq_MinValue &Seq_Cache;
Example:
--------
set ver off
DEFINE SeqOwner=SBC
DEFINE SeqName=Seq1
NEXTVAL
----------
55
VALUE1 VALUE2
---------- ----------
-79 -24
NEXTVAL
----------
-19
SQL> -- Return Old(Current) Values Back such as Min_Value anc Cache Size