<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8434915659673660624</id><updated>2011-04-21T16:36:25.652-07:00</updated><title type='text'>Oracle Guru</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://oracle10guru.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8434915659673660624/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://oracle10guru.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>ASHISH MITTAL</name><uri>http://www.blogger.com/profile/08380549011082398501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_Va-OfRMZJqU/TFUVl69pGSI/AAAAAAAAAhk/-fi5rgc18xI/S220/NEW2.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>1</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8434915659673660624.post-7656357632653783545</id><published>2008-09-09T03:24:00.001-07:00</published><updated>2008-09-09T03:24:57.347-07:00</updated><title type='text'>How to Prevent Locks</title><content type='html'>This script checks the current users Foreign Keys to make sure of the  &lt;br /&gt;following: &lt;br /&gt; &lt;br /&gt;        1) All the FK columns have indexes to prevent a possible locking &lt;br /&gt;         &lt;br /&gt;        2) Checks the ORDER OF THE INDEXED COLUMNS. To prevent the locking &lt;br /&gt;        problem the columns MUST be indexed in the same order as the FK is &lt;br /&gt;        defined. &lt;br /&gt; &lt;br /&gt;        3) If the script finds a mismatch, the script reports the correct  &lt;br /&gt;        order of columns that need to be added to prevent the locking &lt;br /&gt;        problem. &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;                            IMPORTANT, PLEASE NOTE &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;        This locking problem, due to a FK column not being indexed, is discussed &lt;br /&gt;        in the 8x/9x Concepts Manual under Data Integrity chapter. &lt;br /&gt;         &lt;br /&gt;        Starting with Oracle9i, Release 1 (9.0.1), Oracle no longer requires &lt;br /&gt;        a share lock on unindexed foreign keys when doing an update or delete on &lt;br /&gt;        the primary key. It still obtains the table-level share lock, but then &lt;br /&gt;        releases it immediately after obtaining it. If multiple primary keys are &lt;br /&gt;        update or deleted, the lock is obtained and released once for each row.&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;References &lt;br /&gt; &lt;br /&gt;&lt;Note:15476.1&gt; FAQ about Detecting and Resolving Locking Conflicts&lt;br /&gt; &lt;br /&gt;&lt;Note:33453.1&gt; REFERENTIAL INTEGRITY AND LOCKING&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Script &lt;br /&gt; &lt;br /&gt;======= &lt;br /&gt;Script: &lt;br /&gt;======= &lt;br /&gt; &lt;br /&gt;----------- cut ---------------------- cut -------------- cut -------------- &lt;br /&gt; &lt;br /&gt;SET ECHO off &lt;br /&gt;REM NAME:   TFSFKCHLK.SQL &lt;br /&gt;REM USAGE:"@path/tfsfkchk" &lt;br /&gt;REM -------------------------------------------------------------------------- &lt;br /&gt;REM REQUIREMENTS: &lt;br /&gt;REM    None -- checks only the USER_ views &lt;br /&gt;REM -------------------------------------------------------------------------- &lt;br /&gt;REM    This file checks the current users Foreign Keys to make sure of the  &lt;br /&gt;REM    following: &lt;br /&gt;REM &lt;br /&gt;REM    1) All the FK columns are have indexes to prevent a possible locking &lt;br /&gt;REM       problem that can slow down the database. &lt;br /&gt;REM &lt;br /&gt;REM    2) Checks the ORDER OF THE INDEXED COLUMNS. To prevent the locking &lt;br /&gt;REM       problem the columns MUST be index in the same order as the FK is &lt;br /&gt;REM       defined. &lt;br /&gt;REM    &lt;br /&gt;REM    3) If the script finds and miss match the script reports the correct  &lt;br /&gt;REM       order of columns that need to be added to prevent the locking &lt;br /&gt;REM       problem. &lt;br /&gt;REM &lt;br /&gt;REM  &lt;br /&gt;REM     &lt;br /&gt;REM ------------------------------------------------------------------------- &lt;br /&gt;REM Main text of script follows: &lt;br /&gt; &lt;br /&gt;drop table ck_log; &lt;br /&gt; &lt;br /&gt;create table ck_log ( &lt;br /&gt;       LineNum number, &lt;br /&gt;       LineMsg varchar2(2000)); &lt;br /&gt; &lt;br /&gt;declare &lt;br /&gt;t_CONSTRAINT_TYPE            user_constraints.CONSTRAINT_TYPE%type; &lt;br /&gt;t_CONSTRAINT_NAME            USER_CONSTRAINTS.CONSTRAINT_NAME%type; &lt;br /&gt;t_TABLE_NAME                 USER_CONSTRAINTS.TABLE_NAME%type; &lt;br /&gt;t_R_CONSTRAINT_NAME          USER_CONSTRAINTS.R_CONSTRAINT_NAME%type; &lt;br /&gt;tt_CONSTRAINT_NAME           USER_CONS_COLUMNS.CONSTRAINT_NAME%type; &lt;br /&gt;tt_TABLE_NAME                USER_CONS_COLUMNS.TABLE_NAME%type; &lt;br /&gt;tt_COLUMN_NAME               USER_CONS_COLUMNS.COLUMN_NAME%type; &lt;br /&gt;tt_POSITION                  USER_CONS_COLUMNS.POSITION%type; &lt;br /&gt;tt_Dummy                     number; &lt;br /&gt;tt_dummyChar                 varchar2(2000); &lt;br /&gt;l_Cons_Found_Flag            VarChar2(1); &lt;br /&gt;Err_TABLE_NAME               USER_CONSTRAINTS.TABLE_NAME%type; &lt;br /&gt;Err_COLUMN_NAME              USER_CONS_COLUMNS.COLUMN_NAME%type; &lt;br /&gt;Err_POSITION                 USER_CONS_COLUMNS.POSITION%type; &lt;br /&gt; &lt;br /&gt;tLineNum number; &lt;br /&gt; &lt;br /&gt;cursor UserTabs is &lt;br /&gt;       select table_name &lt;br /&gt;       from   user_tables &lt;br /&gt;       order by table_name; &lt;br /&gt; &lt;br /&gt;cursor TableCons is &lt;br /&gt;       select CONSTRAINT_TYPE, &lt;br /&gt;              CONSTRAINT_NAME, &lt;br /&gt;              R_CONSTRAINT_NAME &lt;br /&gt;       from user_constraints &lt;br /&gt;       where OWNER = USER &lt;br /&gt;       and table_name = t_Table_Name &lt;br /&gt;       and CONSTRAINT_TYPE  = 'R' &lt;br /&gt;       order by TABLE_NAME, CONSTRAINT_NAME; &lt;br /&gt; &lt;br /&gt;cursor ConColumns is &lt;br /&gt;       select CONSTRAINT_NAME, &lt;br /&gt;              TABLE_NAME, &lt;br /&gt;              COLUMN_NAME, &lt;br /&gt;              POSITION &lt;br /&gt;       from user_cons_columns &lt;br /&gt;       where OWNER = USER &lt;br /&gt;       and   CONSTRAINT_NAME = t_CONSTRAINT_NAME &lt;br /&gt;       order by POSITION; &lt;br /&gt; &lt;br /&gt;cursor IndexColumns is &lt;br /&gt;       select TABLE_NAME, &lt;br /&gt;              COLUMN_NAME, &lt;br /&gt;              POSITION &lt;br /&gt;       from user_cons_columns &lt;br /&gt;       where OWNER = USER &lt;br /&gt;       and   CONSTRAINT_NAME = t_CONSTRAINT_NAME &lt;br /&gt;       order by POSITION; &lt;br /&gt; &lt;br /&gt;DebugLevel number := 99; -- &gt;&gt; 99 = dump all info` &lt;br /&gt;DebugFlag varchar(1) := 'N'; -- Turn Debugging on &lt;br /&gt;t_Error_Found  varchar(1); &lt;br /&gt; &lt;br /&gt;begin &lt;br /&gt; &lt;br /&gt;  tLineNum := 1000; &lt;br /&gt;  open UserTabs; &lt;br /&gt;  LOOP &lt;br /&gt;    Fetch UserTabs into t_TABLE_NAME; &lt;br /&gt;    t_Error_Found := 'N'; &lt;br /&gt;    exit when UserTabs%NOTFOUND; &lt;br /&gt; &lt;br /&gt;    -- Log current table &lt;br /&gt;    tLineNum := tLineNum + 1; &lt;br /&gt;    insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;    ( tLineNum, NULL ); &lt;br /&gt; &lt;br /&gt;    tLineNum := tLineNum + 1; &lt;br /&gt;    insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;    ( tLineNum, 'Checking Table '||t_Table_Name); &lt;br /&gt; &lt;br /&gt;    l_Cons_Found_Flag := 'N'; &lt;br /&gt;    open TableCons; &lt;br /&gt;    LOOP &lt;br /&gt;      FETCH TableCons INTO t_CONSTRAINT_TYPE, &lt;br /&gt;                    t_CONSTRAINT_NAME, &lt;br /&gt;               t_R_CONSTRAINT_NAME; &lt;br /&gt;      exit when TableCons%NOTFOUND; &lt;br /&gt; &lt;br /&gt;      if ( DebugFlag = 'Y' and DebugLevel &gt;= 99 ) &lt;br /&gt;      then &lt;br /&gt;        begin &lt;br /&gt;          tLineNum := tLineNum + 1; &lt;br /&gt;          insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;          ( tLineNum, 'Found CONSTRAINT_NAME = '|| t_CONSTRAINT_NAME); &lt;br /&gt; &lt;br /&gt;          tLineNum := tLineNum + 1; &lt;br /&gt;          insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;          ( tLineNum, 'Found CONSTRAINT_TYPE = '|| t_CONSTRAINT_TYPE); &lt;br /&gt; &lt;br /&gt;          tLineNum := tLineNum + 1; &lt;br /&gt;          insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;          ( tLineNum, 'Found R_CONSTRAINT_NAME = '|| t_R_CONSTRAINT_NAME); &lt;br /&gt;          commit; &lt;br /&gt;        end; &lt;br /&gt;      end if; &lt;br /&gt; &lt;br /&gt;      open ConColumns; &lt;br /&gt;      LOOP &lt;br /&gt;        FETCH ConColumns INTO &lt;br /&gt;                          tt_CONSTRAINT_NAME, &lt;br /&gt;                          tt_TABLE_NAME, &lt;br /&gt;                          tt_COLUMN_NAME, &lt;br /&gt;                          tt_POSITION; &lt;br /&gt;        exit when ConColumns%NOTFOUND; &lt;br /&gt;        if ( DebugFlag = 'Y' and DebugLevel &gt;= 99 ) &lt;br /&gt;        then &lt;br /&gt;          begin &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, NULL ); &lt;br /&gt; &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Found CONSTRAINT_NAME = '|| tt_CONSTRAINT_NAME); &lt;br /&gt; &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Found TABLE_NAME = '|| tt_TABLE_NAME); &lt;br /&gt; &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Found COLUMN_NAME = '|| tt_COLUMN_NAME); &lt;br /&gt; &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Found POSITION = '|| tt_POSITION); &lt;br /&gt;          commit; &lt;br /&gt;          end; &lt;br /&gt;      end if; &lt;br /&gt; &lt;br /&gt;      begin &lt;br /&gt;        select 1 into tt_Dummy &lt;br /&gt;        from user_ind_columns &lt;br /&gt;        where   TABLE_NAME =  tt_TABLE_NAME &lt;br /&gt;        and     COLUMN_NAME = tt_COLUMN_NAME &lt;br /&gt;        and     COLUMN_POSITION = tt_POSITION; &lt;br /&gt; &lt;br /&gt;        if ( DebugFlag = 'Y' and DebugLevel &gt;= 99 ) &lt;br /&gt;        then &lt;br /&gt;        begin &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Row Has matching Index' ); &lt;br /&gt;        end; &lt;br /&gt;        end if; &lt;br /&gt;      exception &lt;br /&gt;      when Too_Many_Rows then &lt;br /&gt;      if ( DebugFlag = 'Y' and DebugLevel &gt;= 99 ) &lt;br /&gt;        then &lt;br /&gt;          begin &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Row Has matching Index' ); &lt;br /&gt;          end; &lt;br /&gt;        end if; &lt;br /&gt; &lt;br /&gt;      when no_data_found then &lt;br /&gt;        if ( DebugFlag = 'Y' and DebugLevel &gt;= 99 ) &lt;br /&gt;        then &lt;br /&gt;          begin &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'NO MATCH FOUND' ); &lt;br /&gt;          commit; &lt;br /&gt;          end; &lt;br /&gt;        end if; &lt;br /&gt; &lt;br /&gt;        t_Error_Found := 'Y'; &lt;br /&gt; &lt;br /&gt;        select distinct TABLE_NAME &lt;br /&gt;        into tt_dummyChar &lt;br /&gt;        from user_cons_columns &lt;br /&gt;        where OWNER = USER &lt;br /&gt;        and   CONSTRAINT_NAME = t_R_CONSTRAINT_NAME; &lt;br /&gt; &lt;br /&gt;        tLineNum := tLineNum + 1;&lt;br /&gt;        insert into ck_log ( LineNum, LineMsg ) values&lt;br /&gt;        ( tLineNum, 'Changing data in table '||tt_dummyChar&lt;br /&gt;                    ||' will lock table ' ||tt_TABLE_NAME);&lt;br /&gt; &lt;br /&gt;        commit; &lt;br /&gt;        tLineNum := tLineNum + 1; &lt;br /&gt;        insert into ck_log ( LineNum, LineMsg ) values&lt;br /&gt;        ( tLineNum,'Create an index on table '||tt_TABLE_NAME&lt;br /&gt;                   ||' with the following columns to remove lock problem');&lt;br /&gt;        &lt;br /&gt;        open IndexColumns ; &lt;br /&gt;        loop &lt;br /&gt;          Fetch IndexColumns into Err_TABLE_NAME, &lt;br /&gt;              Err_COLUMN_NAME, &lt;br /&gt;              Err_POSITION; &lt;br /&gt;          exit when IndexColumns%NotFound; &lt;br /&gt;          tLineNum := tLineNum + 1; &lt;br /&gt;          insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;          ( tLineNum,'Column = '||Err_COLUMN_NAME||' ('||Err_POSITION||')'); &lt;br /&gt;        end loop; &lt;br /&gt;        close IndexColumns; &lt;br /&gt;      end; &lt;br /&gt;    end loop; &lt;br /&gt;    commit; &lt;br /&gt;  close ConColumns; &lt;br /&gt;  end loop; &lt;br /&gt;  if ( t_Error_Found = 'N' ) &lt;br /&gt;  then &lt;br /&gt;    begin &lt;br /&gt;      tLineNum := tLineNum + 1; &lt;br /&gt;      insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;      ( tLineNum,'No foreign key errors found'); &lt;br /&gt;    end; &lt;br /&gt;  end if; &lt;br /&gt;  commit; &lt;br /&gt;  close TableCons; &lt;br /&gt;end loop; &lt;br /&gt;commit; &lt;br /&gt;end; &lt;br /&gt;/ &lt;br /&gt; &lt;br /&gt;select LineMsg&lt;br /&gt;from ck_log&lt;br /&gt;where LineMsg NOT LIKE 'Checking%' AND&lt;br /&gt;      LineMsg NOT LIKE 'No foreign key%'&lt;br /&gt;order by LineNum&lt;br /&gt;/&lt;br /&gt; &lt;br /&gt;----------- cut ---------------------- cut -------------- cut -------------- &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;========= &lt;br /&gt;Examples: &lt;br /&gt;========= &lt;br /&gt; &lt;br /&gt;LINEMSG                                                    &lt;br /&gt;  &lt;br /&gt;-------------------------------------------------------------------------- &lt;br /&gt;Changing&lt;br /&gt;data in table DEPT will lock table EMP&lt;br /&gt;Create an index on table EMP with the following columns to remove lock problem&lt;br /&gt; &lt;br /&gt;Column = DEPTNO (1)&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Changing data in table ITEM_CATEGORIES will lock table ITEMS&lt;br /&gt;Create an index on table ITEMS with the following columns to remove lock problem &lt;br /&gt; &lt;br /&gt;Column = ITEM_CAT (1) &lt;br /&gt;Column = ITEM_BUS_UNIT (2) &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Changing data in table EMP will lock table EMP &lt;br /&gt;Create an index on table EMP with the following columns to remove lock problem &lt;br /&gt; &lt;br /&gt;Column = MGR (1) &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Changing data in table ORD will lock table CUSTOMER &lt;br /&gt;Create an index on table CUSTOMER with the following columns to remove lock problem  &lt;br /&gt; &lt;br /&gt;Column = CUSTID (1)&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Disclaimer &lt;br /&gt; &lt;br /&gt;EXCEPT WHERE EXPRESSLY PROVIDED OTHERWISE, THE INFORMATION, SOFTWARE,&lt;br /&gt;PROVIDED ON AN "AS IS" AND "AS AVAILABLE" BASIS. ORACLE EXPRESSLY DISCLAIMS&lt;br /&gt;ALL WARRANTIES OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT&lt;br /&gt;LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR&lt;br /&gt;PURPOSE AND NON-INFRINGEMENT. ORACLE MAKES NO WARRANTY THAT: (A) THE RESULTS&lt;br /&gt;THAT MAY BE OBTAINED FROM THE USE OF THE SOFTWARE WILL BE ACCURATE OR&lt;br /&gt;RELIABLE; OR (B) THE INFORMATION, OR OTHER MATERIAL OBTAINED WILL MEET YOUR&lt;br /&gt;EXPECTATIONS. ANY CONTENT, MATERIALS, INFORMATION OR SOFTWARE DOWNLOADED OR&lt;br /&gt;OTHERWISE OBTAINED IS DONE AT YOUR OWN DISCRETION AND RISK. ORACLE SHALL HAVE&lt;br /&gt;NO RESPONSIBILITY FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR LOSS OF DATA THAT&lt;br /&gt;RESULTS FROM THE DOWNLOAD OF ANY CONTENT, MATERIALS, INFORMATION OR SOFTWARE.&lt;br /&gt; &lt;br /&gt;ORACLE RESERVES THE RIGHT TO MAKE CHANGES OR UPDATES TO THE SOFTWARE AT ANY&lt;br /&gt;TIME WITHOUT NOTICE.&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Limitation of Liability &lt;br /&gt; &lt;br /&gt;IN NO EVENT SHALL ORACLE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,&lt;br /&gt;SPECIAL OR CONSEQUENTIAL DAMAGES, OR DAMAGES FOR LOSS OF PROFITS, REVENUE,&lt;br /&gt;DATA OR USE, INCURRED BY YOU OR ANY THIRD PARTY, WHETHER IN AN ACTION IN&lt;br /&gt;CONTRACT OR TORT, ARISING FROM YOUR ACCESS TO, OR USE OF, THE SOFTWARE.&lt;br /&gt; &lt;br /&gt;SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OR EXCLUSION OF LIABILITY.&lt;br /&gt;ACCORDINGLY, SOME OF THE ABOVE LIMITATIONS MAY NOT APPLY TO YOU.&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Abstract &lt;br /&gt; &lt;br /&gt;SCRIPT TO CHECK FOR FOREIGN KEY LOCKING ISSUES&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Product Name, Product Version&lt;br /&gt; Rdbms:07.0.X &lt;br /&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Platform &lt;br /&gt; Platform Independent&lt;br /&gt; &lt;br /&gt;Date Created &lt;br /&gt; 07-NOV-2002&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Instructions &lt;br /&gt; &lt;br /&gt;Execution Environment:&lt;br /&gt;     &lt;SQL, SQL*Plus&gt;&lt;br /&gt; &lt;br /&gt;Access Privileges:&lt;br /&gt;     If run as owner of objects no special priveleges required&lt;br /&gt; &lt;br /&gt;Usage:&lt;br /&gt;     sqlplus &lt;user&gt;/&lt;pw&gt; @[SCRIPTFILE]&lt;br /&gt; &lt;br /&gt;Instructions:&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;PROOFREAD THIS SCRIPT BEFORE USING IT! Due to differences in the way text &lt;br /&gt;editors, e-mail packages, and operating systems handle text formatting (spaces, &lt;br /&gt;tabs, and carriage returns), this script may not be in an executable state&lt;br /&gt;when you first receive it. Check over the script to ensure that errors of&lt;br /&gt;this type are corrected.The script will produce an output file named [outputfile].&lt;br /&gt;This file can be viewed in a browser or uploaded for support analysis.&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Description &lt;br /&gt; &lt;br /&gt;This script checks the current users Foreign Keys to make sure of the  &lt;br /&gt;following: &lt;br /&gt; &lt;br /&gt;        1) All the FK columns have indexes to prevent a possible locking &lt;br /&gt;         &lt;br /&gt;        2) Checks the ORDER OF THE INDEXED COLUMNS. To prevent the locking &lt;br /&gt;        problem the columns MUST be indexed in the same order as the FK is &lt;br /&gt;        defined. &lt;br /&gt; &lt;br /&gt;        3) If the script finds a mismatch, the script reports the correct  &lt;br /&gt;        order of columns that need to be added to prevent the locking &lt;br /&gt;        problem. &lt;br /&gt; &lt;br /&gt;                        IMPORTANT, PLEASE NOTE &lt;br /&gt; &lt;br /&gt;        The potential locking issues, due to a FK column not being indexed, &lt;br /&gt;        apply to versions prior to Oracle V7.1.5.   &lt;br /&gt;        &lt;br /&gt; &lt;br /&gt;        This locking problem is discussed in the Oracle 7 Server, &lt;br /&gt;        Application Developer's Guide Page 6-10 under the section  &lt;br /&gt;        "On Index on the Foreign Key" &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;References &lt;br /&gt; &lt;br /&gt;&lt;Note:15476.1&gt; FAQ about Detecting and Resolving Locking Conflicts&lt;br /&gt; &lt;br /&gt;&lt;Note:33453.1&gt; REFERENTIAL INTEGRITY AND LOCKING&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Script &lt;br /&gt; &lt;br /&gt;======= &lt;br /&gt;Script: &lt;br /&gt;======= &lt;br /&gt; &lt;br /&gt;----------- cut ---------------------- cut -------------- cut -------------- &lt;br /&gt; &lt;br /&gt;SET ECHO off &lt;br /&gt;REM NAME:   TFSFKCHLK.SQL &lt;br /&gt;REM USAGE:"@path/tfsfkchk" &lt;br /&gt;REM -------------------------------------------------------------------------- &lt;br /&gt;REM REQUIREMENTS: &lt;br /&gt;REM    None -- checks only the USER_ views &lt;br /&gt;REM -------------------------------------------------------------------------- &lt;br /&gt;REM PURPOSE: &lt;br /&gt;REM    This file checks the current users Foreign Keys to make sure of the  &lt;br /&gt;REM    following: &lt;br /&gt;REM &lt;br /&gt;REM    1) All the FK columns are have indexes to prevent a possible locking &lt;br /&gt;REM       problem that can slow down the database. &lt;br /&gt;REM &lt;br /&gt;REM    2) Checks the ORDER OF THE INDEXED COLUMNS. To prevent the locking &lt;br /&gt;REM       problem the columns MUST be index in the same order as the FK is &lt;br /&gt;REM       defined. &lt;br /&gt;REM    &lt;br /&gt;REM    3) If the script finds and miss match the script reports the correct  &lt;br /&gt;REM       order of columns that need to be added to prevent the locking &lt;br /&gt;REM       problem. &lt;br /&gt;REM &lt;br /&gt;REM    NOTES: &lt;br /&gt;REM &lt;br /&gt;REM      - This locking problem is discussed in the  &lt;br /&gt;REM        Oracle 7 Server, Application Developer's Guide Page 6-10  &lt;br /&gt;REM        under the section "No Index on the Foreign Key" &lt;br /&gt;REM  &lt;br /&gt;REM ----------------------------------------------------------------------- &lt;br /&gt;REM EXAMPLE: &lt;br /&gt;REM    LINEMSG  &lt;br /&gt;REM    ------------------------------------------------------------------- &lt;br /&gt;REM    Changing data in table ITEMS will lock table ITEM_CATEGORIES &lt;br /&gt;REM    Create an index on the following columns to remove lock problem &lt;br /&gt;REM &lt;br /&gt;REM    Column = ITEM_CAT (1) &lt;br /&gt;REM    Column = ITEM_BUS_UNIT (2) &lt;br /&gt;REM     &lt;br /&gt;REM    Changing data in table ITEMS will lock table ITEM_CATEGORIES &lt;br /&gt;REM    Create an index on the following columns to remove lock problem &lt;br /&gt;REM  &lt;br /&gt;REM    Column = ITEM_CAT (1) &lt;br /&gt;REM    Column = ITEM_BUS_UNIT (2) &lt;br /&gt;REM ----------------------------------------------------------------------- &lt;br /&gt;REM DISCLAIMER: &lt;br /&gt;REM    This script is provided for educational purposes only. It is NOT  &lt;br /&gt;REM    supported by Oracle World Wide Technical Support. &lt;br /&gt;REM    The script has been tested and appears to work as intended. &lt;br /&gt;REM    You should always run new scripts on a test instance initially. &lt;br /&gt;REM ------------------------------------------------------------------------- &lt;br /&gt;REM Main text of script follows: &lt;br /&gt; &lt;br /&gt;drop table ck_log; &lt;br /&gt; &lt;br /&gt;create table ck_log ( &lt;br /&gt;LineNum number, &lt;br /&gt;LineMsg varchar2(2000)); &lt;br /&gt; &lt;br /&gt;declare &lt;br /&gt;t_CONSTRAINT_TYPE            user_constraints.CONSTRAINT_TYPE%type; &lt;br /&gt;t_CONSTRAINT_NAME            USER_CONSTRAINTS.CONSTRAINT_NAME%type; &lt;br /&gt;t_TABLE_NAME   USER_CONSTRAINTS.TABLE_NAME%type; &lt;br /&gt;t_R_CONSTRAINT_NAME          USER_CONSTRAINTS.R_CONSTRAINT_NAME%type; &lt;br /&gt;tt_CONSTRAINT_NAME           USER_CONS_COLUMNS.CONSTRAINT_NAME%type; &lt;br /&gt;tt_TABLE_NAME                USER_CONS_COLUMNS.TABLE_NAME%type; &lt;br /&gt;tt_COLUMN_NAME               USER_CONS_COLUMNS.COLUMN_NAME%type; &lt;br /&gt;tt_POSITION              USER_CONS_COLUMNS.POSITION%type; &lt;br /&gt;tt_Dummy                     number; &lt;br /&gt;tt_dummyChar                 varchar2(2000); &lt;br /&gt;l_Cons_Found_Flag            VarChar2(1); &lt;br /&gt;Err_TABLE_NAME                USER_CONSTRAINTS.TABLE_NAME%type; &lt;br /&gt;Err_COLUMN_NAME               USER_CONS_COLUMNS.COLUMN_NAME%type; &lt;br /&gt;Err_POSITION          USER_CONS_COLUMNS.POSITION%type; &lt;br /&gt; &lt;br /&gt;tLineNum number; &lt;br /&gt; &lt;br /&gt;cursor UserTabs is &lt;br /&gt;       select table_name &lt;br /&gt;       from   user_tables &lt;br /&gt;       -- where Table_Name = 'WORKERS_COMP_CLAIMS' &lt;br /&gt;       order by table_name; &lt;br /&gt; &lt;br /&gt;cursor TableCons is &lt;br /&gt;       select CONSTRAINT_TYPE, &lt;br /&gt;              CONSTRAINT_NAME, &lt;br /&gt;              R_CONSTRAINT_NAME &lt;br /&gt;       from user_constraints &lt;br /&gt;       where OWNER = USER &lt;br /&gt;       and table_name = t_Table_Name &lt;br /&gt;       and CONSTRAINT_TYPE  = 'R' &lt;br /&gt;       order by TABLE_NAME, CONSTRAINT_NAME; &lt;br /&gt; &lt;br /&gt;cursor ConColumns is &lt;br /&gt;       select CONSTRAINT_NAME, &lt;br /&gt;    TABLE_NAME, &lt;br /&gt;              COLUMN_NAME, &lt;br /&gt;              POSITION &lt;br /&gt;       from user_cons_columns &lt;br /&gt;       where OWNER = USER &lt;br /&gt;       and   CONSTRAINT_NAME = t_CONSTRAINT_NAME &lt;br /&gt;       order by POSITION; &lt;br /&gt; &lt;br /&gt;cursor IndexColumns is &lt;br /&gt;       select TABLE_NAME, &lt;br /&gt;              COLUMN_NAME, &lt;br /&gt;              POSITION &lt;br /&gt;       from user_cons_columns &lt;br /&gt;       where OWNER = USER &lt;br /&gt;       and   CONSTRAINT_NAME = t_CONSTRAINT_NAME &lt;br /&gt;       order by POSITION; &lt;br /&gt; &lt;br /&gt;DebugLevel number := 99; -- &gt;&gt; 99 = dump all info` &lt;br /&gt;DebugFlag varchar(1) := 'N'; -- Turn Debugging on &lt;br /&gt;t_Error_Found  varchar(1); &lt;br /&gt; &lt;br /&gt;begin &lt;br /&gt; &lt;br /&gt;  tLineNum := 1000; &lt;br /&gt;  open UserTabs; &lt;br /&gt;  LOOP &lt;br /&gt;    Fetch UserTabs into t_TABLE_NAME; &lt;br /&gt;    t_Error_Found := 'N'; &lt;br /&gt;    exit when UserTabs%NOTFOUND; &lt;br /&gt; &lt;br /&gt;    -- Log current table &lt;br /&gt;    tLineNum := tLineNum + 1; &lt;br /&gt;    insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;    ( tLineNum, NULL ); &lt;br /&gt; &lt;br /&gt;    tLineNum := tLineNum + 1; &lt;br /&gt;    insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;    ( tLineNum, 'Checking Table '||t_Table_Name); &lt;br /&gt; &lt;br /&gt;    l_Cons_Found_Flag := 'N'; &lt;br /&gt;    open TableCons; &lt;br /&gt;    LOOP &lt;br /&gt;      FETCH TableCons INTO t_CONSTRAINT_TYPE, &lt;br /&gt;                    t_CONSTRAINT_NAME, &lt;br /&gt;               t_R_CONSTRAINT_NAME; &lt;br /&gt;      exit when TableCons%NOTFOUND; &lt;br /&gt; &lt;br /&gt;      if ( DebugFlag = 'Y' and DebugLevel &gt;= 99 ) &lt;br /&gt;      then &lt;br /&gt;        begin &lt;br /&gt;          tLineNum := tLineNum + 1; &lt;br /&gt;          insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;          ( tLineNum, 'Found CONSTRAINT_NAME = '|| t_CONSTRAINT_NAME); &lt;br /&gt; &lt;br /&gt;   tLineNum := tLineNum + 1; &lt;br /&gt;          insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;          ( tLineNum, 'Found CONSTRAINT_TYPE = '|| t_CONSTRAINT_TYPE); &lt;br /&gt; &lt;br /&gt;        tLineNum := tLineNum + 1; &lt;br /&gt;          insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;          ( tLineNum, 'Found R_CONSTRAINT_NAME = '|| t_R_CONSTRAINT_NAME); &lt;br /&gt;          commit; &lt;br /&gt;        end; &lt;br /&gt;      end if; &lt;br /&gt; &lt;br /&gt;      open ConColumns; &lt;br /&gt; LOOP &lt;br /&gt;        FETCH ConColumns INTO &lt;br /&gt;                          tt_CONSTRAINT_NAME, &lt;br /&gt;                          tt_TABLE_NAME, &lt;br /&gt;                          tt_COLUMN_NAME, &lt;br /&gt;                          tt_POSITION; &lt;br /&gt;        exit when ConColumns%NOTFOUND; &lt;br /&gt;        if ( DebugFlag = 'Y' and DebugLevel &gt;= 99 ) &lt;br /&gt;        then &lt;br /&gt;          begin &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, NULL ); &lt;br /&gt; &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;   ( tLineNum, 'Found CONSTRAINT_NAME = '|| tt_CONSTRAINT_NAME); &lt;br /&gt; &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Found TABLE_NAME = '|| tt_TABLE_NAME); &lt;br /&gt; &lt;br /&gt;tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Found COLUMN_NAME = '|| tt_COLUMN_NAME); &lt;br /&gt; &lt;br /&gt;    tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Found POSITION = '|| tt_POSITION); &lt;br /&gt;          commit; &lt;br /&gt;          end; &lt;br /&gt;      end if; &lt;br /&gt; &lt;br /&gt;      begin &lt;br /&gt;        select 1 into tt_Dummy &lt;br /&gt;        from user_ind_columns &lt;br /&gt;        where   TABLE_NAME =  tt_TABLE_NAME &lt;br /&gt;  and     COLUMN_NAME = tt_COLUMN_NAME &lt;br /&gt;        and     COLUMN_POSITION = tt_POSITION; &lt;br /&gt; &lt;br /&gt;        if ( DebugFlag = 'Y' and DebugLevel &gt;= 99 ) &lt;br /&gt;        then &lt;br /&gt;  begin &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Row Has matching Index' ); &lt;br /&gt;       end; &lt;br /&gt;        end if; &lt;br /&gt;      exception &lt;br /&gt;      when Too_Many_Rows then &lt;br /&gt;  if ( DebugFlag = 'Y' and DebugLevel &gt;= 99 ) &lt;br /&gt;        then &lt;br /&gt;          begin &lt;br /&gt;       tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Row Has matching Index' ); &lt;br /&gt;          end; &lt;br /&gt;        end if; &lt;br /&gt; &lt;br /&gt;      when no_data_found then &lt;br /&gt;        if ( DebugFlag = 'Y' and DebugLevel &gt;= 99 ) &lt;br /&gt;        then &lt;br /&gt;          begin &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'NO MATCH FOUND' ); &lt;br /&gt;          commit; &lt;br /&gt;          end; &lt;br /&gt;        end if; &lt;br /&gt; &lt;br /&gt;      t_Error_Found := 'Y'; &lt;br /&gt; &lt;br /&gt;        select distinct TABLE_NAME &lt;br /&gt;        into tt_dummyChar &lt;br /&gt;        from user_cons_columns &lt;br /&gt;        where OWNER = USER &lt;br /&gt;        and   CONSTRAINT_NAME = t_R_CONSTRAINT_NAME; &lt;br /&gt; &lt;br /&gt;        tLineNum := tLineNum + 1; &lt;br /&gt;    insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;        ( tLineNum, 'Changing data in table '||tt_TABLE_NAME &lt;br /&gt;                    ||' will lock table ' ||tt_dummyChar); &lt;br /&gt; &lt;br /&gt;        commit; &lt;br /&gt;        tLineNum := tLineNum + 1; &lt;br /&gt;        insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;        ( tLineNum,'Create an index on the following columns to remove lock  &lt;br /&gt;problem'); &lt;br /&gt;        open IndexColumns ; &lt;br /&gt; loop &lt;br /&gt;          Fetch IndexColumns into Err_TABLE_NAME, &lt;br /&gt;              Err_COLUMN_NAME, &lt;br /&gt;              Err_POSITION; &lt;br /&gt;          exit when IndexColumns%NotFound; &lt;br /&gt;        tLineNum := tLineNum + 1; &lt;br /&gt;          insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;          ( tLineNum,'Column = '||Err_COLUMN_NAME||' ('||Err_POSITION||')'); &lt;br /&gt;          end loop; &lt;br /&gt;        close IndexColumns; &lt;br /&gt;      end; &lt;br /&gt;    end loop; &lt;br /&gt;    commit; &lt;br /&gt;  close ConColumns; &lt;br /&gt;  end loop; &lt;br /&gt;  if ( t_Error_Found = 'N' ) &lt;br /&gt;  then &lt;br /&gt;    begin &lt;br /&gt;      tLineNum := tLineNum + 1; &lt;br /&gt;      insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;      ( tLineNum,'No foreign key errors found'); &lt;br /&gt;    end; &lt;br /&gt;  end if; &lt;br /&gt;  commit; &lt;br /&gt;  close TableCons; &lt;br /&gt;end loop; &lt;br /&gt;commit; &lt;br /&gt;end; &lt;br /&gt; &lt;br /&gt;/ &lt;br /&gt; &lt;br /&gt;select LineMsg &lt;br /&gt;from ck_log &lt;br /&gt;where LineMsg NOT LIKE 'Checking%' AND &lt;br /&gt;      LineMsg NOT LIKE 'No Probl%' &lt;br /&gt;order by LineNum &lt;br /&gt;/ &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;----------- cut ---------------------- cut -------------- cut -------------- &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;========= &lt;br /&gt;Examples: &lt;br /&gt;========= &lt;br /&gt; &lt;br /&gt;LINEMSG                                                    &lt;br /&gt;  &lt;br /&gt;-------------------------------------------------------------------------- &lt;br /&gt;Changing&lt;br /&gt;data in table EMP will lock table DEPT &lt;br /&gt;Create an index on the following columns to remove lock  &lt;br /&gt;problem                                                                        &lt;br /&gt; &lt;br /&gt;Column&lt;br /&gt;= DEPTNO (1) &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Changing data in table EMP will lock table EMP &lt;br /&gt;Create an index on the following columns to remove lock &lt;br /&gt;problem                                      &lt;br /&gt; &lt;br /&gt;Column = MGR (1) &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Changing data in table ITEMS will lock table ITEM_CATEGORIES &lt;br /&gt;Create an index on the following columns to remove lock  &lt;br /&gt;problem &lt;br /&gt; &lt;br /&gt;Column = ITEM_CAT (1) &lt;br /&gt;Column = ITEM_BUS_UNIT (2) &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Changing data in table ITEMS will lock table ITEM_CATEGORIES &lt;br /&gt;Create an index on the following columns to remove lock &lt;br /&gt;problem &lt;br /&gt; &lt;br /&gt;Column = ITEM_CAT (1) &lt;br /&gt;Column = ITEM_BUS_UNIT (2) &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Changing data in table CUSTOMER will lock table ORD &lt;br /&gt;Create an index on the following columns to remove lock &lt;br /&gt;problem  &lt;br /&gt; &lt;br /&gt;Column = CUSTID (1)&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Disclaimer &lt;br /&gt; &lt;br /&gt;EXCEPT WHERE EXPRESSLY PROVIDED OTHERWISE, THE INFORMATION, SOFTWARE,&lt;br /&gt;PROVIDED ON AN "AS IS" AND "AS AVAILABLE" BASIS. ORACLE EXPRESSLY DISCLAIMS&lt;br /&gt;ALL WARRANTIES OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT&lt;br /&gt;LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR&lt;br /&gt;PURPOSE AND NON-INFRINGEMENT. ORACLE MAKES NO WARRANTY THAT: (A) THE RESULTS&lt;br /&gt;THAT MAY BE OBTAINED FROM THE USE OF THE SOFTWARE WILL BE ACCURATE OR&lt;br /&gt;RELIABLE; OR (B) THE INFORMATION, OR OTHER MATERIAL OBTAINED WILL MEET YOUR&lt;br /&gt;EXPECTATIONS. ANY CONTENT, MATERIALS, INFORMATION OR SOFTWARE DOWNLOADED OR&lt;br /&gt;OTHERWISE OBTAINED IS DONE AT YOUR OWN DISCRETION AND RISK. ORACLE SHALL HAVE&lt;br /&gt;NO RESPONSIBILITY FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR LOSS OF DATA THAT&lt;br /&gt;RESULTS FROM THE DOWNLOAD OF ANY CONTENT, MATERIALS, INFORMATION OR SOFTWARE.&lt;br /&gt; &lt;br /&gt;ORACLE RESERVES THE RIGHT TO MAKE CHANGES OR UPDATES TO THE SOFTWARE AT ANY&lt;br /&gt;TIME WITHOUT NOTICE.&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Limitation of Liability &lt;br /&gt; &lt;br /&gt;IN NO EVENT SHALL ORACLE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,&lt;br /&gt;SPECIAL OR CONSEQUENTIAL DAMAGES, OR DAMAGES FOR LOSS OF PROFITS, REVENUE,&lt;br /&gt;DATA OR USE, INCURRED BY YOU OR ANY THIRD PARTY, WHETHER IN AN ACTION IN&lt;br /&gt;CONTRACT OR TORT, ARISING FROM YOUR ACCESS TO, OR USE OF, THE SOFTWARE.&lt;br /&gt; &lt;br /&gt;SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OR EXCLUSION OF LIABILITY.&lt;br /&gt;ACCORDINGLY, SOME OF THE ABOVE LIMITATIONS MAY NOT APPLY TO YOU.&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Abstract &lt;br /&gt; &lt;br /&gt;SCRIPT TO CHECK FOR FOREIGN KEY LOCKING ISSUES&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Product Name, Product Version&lt;br /&gt; Rdbms:07.0.X - 08.XX &lt;br /&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Platform &lt;br /&gt; Platform Independent&lt;br /&gt; &lt;br /&gt;Date Created &lt;br /&gt; 07-NOV-2002&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Instructions &lt;br /&gt; &lt;br /&gt;Execution Environment:&lt;br /&gt;     &lt;SQL, SQL*Plus&gt;&lt;br /&gt; &lt;br /&gt;Access Privileges:&lt;br /&gt;     If run as owner of objects no special priveleges required&lt;br /&gt; &lt;br /&gt;Usage:&lt;br /&gt;     sqlplus &lt;user&gt;/&lt;pw&gt; @[SCRIPTFILE]&lt;br /&gt; &lt;br /&gt;Instructions:&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;PROOFREAD THIS SCRIPT BEFORE USING IT! Due to differences in the way text &lt;br /&gt;editors, e-mail packages, and operating systems handle text formatting (spaces, &lt;br /&gt;tabs, and carriage returns), this script may not be in an executable state&lt;br /&gt;when you first receive it. Check over the script to ensure that errors of&lt;br /&gt;this type are corrected.The script will produce an output file named [outputfile].&lt;br /&gt;This file can be viewed in a browser or uploaded for support analysis.&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Description &lt;br /&gt; &lt;br /&gt;This script checks the current users Foreign Keys to make sure of the  &lt;br /&gt;following: &lt;br /&gt; &lt;br /&gt;        1) All the FK columns have indexes to prevent a possible locking &lt;br /&gt;         &lt;br /&gt;        2) Checks the ORDER OF THE INDEXED COLUMNS. To prevent the locking &lt;br /&gt;        problem the columns MUST be indexed in the same order as the FK is &lt;br /&gt;        defined. &lt;br /&gt; &lt;br /&gt;        3) If the script finds a mismatch, the script reports the correct  &lt;br /&gt;        order of columns that need to be added to prevent the locking &lt;br /&gt;        problem. &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;                            IMPORTANT, PLEASE NOTE &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;        This locking problem, due to a FK column not being indexed, is discussed &lt;br /&gt;        in the 8x/9x Concepts Manual under Data Integrity chapter. &lt;br /&gt;         &lt;br /&gt;        Starting with Oracle9i, Release 1 (9.0.1), Oracle no longer requires &lt;br /&gt;        a share lock on unindexed foreign keys when doing an update or delete on &lt;br /&gt;        the primary key. It still obtains the table-level share lock, but then &lt;br /&gt;        releases it immediately after obtaining it. If multiple primary keys are &lt;br /&gt;        update or deleted, the lock is obtained and released once for each row.&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;References &lt;br /&gt; &lt;br /&gt;&lt;Note:15476.1&gt; FAQ about Detecting and Resolving Locking Conflicts&lt;br /&gt; &lt;br /&gt;&lt;Note:33453.1&gt; REFERENTIAL INTEGRITY AND LOCKING&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Script &lt;br /&gt; &lt;br /&gt;======= &lt;br /&gt;Script: &lt;br /&gt;======= &lt;br /&gt; &lt;br /&gt;----------- cut ---------------------- cut -------------- cut -------------- &lt;br /&gt; &lt;br /&gt;SET ECHO off &lt;br /&gt;REM NAME:   TFSFKCHLK.SQL &lt;br /&gt;REM USAGE:"@path/tfsfkchk" &lt;br /&gt;REM -------------------------------------------------------------------------- &lt;br /&gt;REM REQUIREMENTS: &lt;br /&gt;REM    None -- checks only the USER_ views &lt;br /&gt;REM -------------------------------------------------------------------------- &lt;br /&gt;REM    This file checks the current users Foreign Keys to make sure of the  &lt;br /&gt;REM    following: &lt;br /&gt;REM &lt;br /&gt;REM    1) All the FK columns are have indexes to prevent a possible locking &lt;br /&gt;REM       problem that can slow down the database. &lt;br /&gt;REM &lt;br /&gt;REM    2) Checks the ORDER OF THE INDEXED COLUMNS. To prevent the locking &lt;br /&gt;REM       problem the columns MUST be index in the same order as the FK is &lt;br /&gt;REM       defined. &lt;br /&gt;REM    &lt;br /&gt;REM    3) If the script finds and miss match the script reports the correct  &lt;br /&gt;REM       order of columns that need to be added to prevent the locking &lt;br /&gt;REM       problem. &lt;br /&gt;REM &lt;br /&gt;REM    NOTES: &lt;br /&gt;REM&lt;br /&gt;REM     This locking problem, due to a FK column not being indexed, is discussed &lt;br /&gt;REM     in the 8x/9x Concepts Manual under Data Integrity chapter. &lt;br /&gt;REM      &lt;br /&gt;REM     Starting with Oracle9i, Release 1 (9.0.1), Oracle no longer requires &lt;br /&gt;REM     a share lock on unindexed foreign keys when doing an update or delete on &lt;br /&gt;REM     the primary key. It still obtains the table-level share lock, but then &lt;br /&gt;REM     releases it immediately after obtaining it. If multiple primary keys are &lt;br /&gt;REM     update or deleted, the lock is obtained and released once for each row.&lt;br /&gt;REM  &lt;br /&gt;REM ----------------------------------------------------------------------- &lt;br /&gt;REM EXAMPLE: &lt;br /&gt;REM&lt;br /&gt;REM    LINEMSG  &lt;br /&gt;REM    ------------------------------------------------------------------- &lt;br /&gt;REM    Changing data in table DEPT will lock table EMP&lt;br /&gt;REM    Create an index on table EMP with the following columns to remove lock problem&lt;br /&gt;REM&lt;br /&gt;REM    Column = DEPTNO (1)&lt;br /&gt;REM&lt;br /&gt;REM    Changing data in table ITEM_CATEGORIES will lock table ITEMS&lt;br /&gt;REM    Create an index on table ITEMS with the following columns to remove lock problem &lt;br /&gt;REM &lt;br /&gt;REM    Column = ITEM_CAT (1) &lt;br /&gt;REM    Column = ITEM_BUS_UNIT (2) &lt;br /&gt;REM     &lt;br /&gt;REM ------------------------------------------------------------------------- &lt;br /&gt;REM Main text of script follows: &lt;br /&gt; &lt;br /&gt;drop table ck_log; &lt;br /&gt; &lt;br /&gt;create table ck_log ( &lt;br /&gt;       LineNum number, &lt;br /&gt;       LineMsg varchar2(2000)); &lt;br /&gt; &lt;br /&gt;declare &lt;br /&gt;t_CONSTRAINT_TYPE            user_constraints.CONSTRAINT_TYPE%type; &lt;br /&gt;t_CONSTRAINT_NAME            USER_CONSTRAINTS.CONSTRAINT_NAME%type; &lt;br /&gt;t_TABLE_NAME                 USER_CONSTRAINTS.TABLE_NAME%type; &lt;br /&gt;t_R_CONSTRAINT_NAME          USER_CONSTRAINTS.R_CONSTRAINT_NAME%type; &lt;br /&gt;tt_CONSTRAINT_NAME           USER_CONS_COLUMNS.CONSTRAINT_NAME%type; &lt;br /&gt;tt_TABLE_NAME                USER_CONS_COLUMNS.TABLE_NAME%type; &lt;br /&gt;tt_COLUMN_NAME               USER_CONS_COLUMNS.COLUMN_NAME%type; &lt;br /&gt;tt_POSITION                  USER_CONS_COLUMNS.POSITION%type; &lt;br /&gt;tt_Dummy                     number; &lt;br /&gt;tt_dummyChar                 varchar2(2000); &lt;br /&gt;l_Cons_Found_Flag            VarChar2(1); &lt;br /&gt;Err_TABLE_NAME               USER_CONSTRAINTS.TABLE_NAME%type; &lt;br /&gt;Err_COLUMN_NAME              USER_CONS_COLUMNS.COLUMN_NAME%type; &lt;br /&gt;Err_POSITION                 USER_CONS_COLUMNS.POSITION%type; &lt;br /&gt; &lt;br /&gt;tLineNum number; &lt;br /&gt; &lt;br /&gt;cursor UserTabs is &lt;br /&gt;       select table_name &lt;br /&gt;       from   user_tables &lt;br /&gt;       order by table_name; &lt;br /&gt; &lt;br /&gt;cursor TableCons is &lt;br /&gt;       select CONSTRAINT_TYPE, &lt;br /&gt;              CONSTRAINT_NAME, &lt;br /&gt;              R_CONSTRAINT_NAME &lt;br /&gt;       from user_constraints &lt;br /&gt;       where OWNER = USER &lt;br /&gt;       and table_name = t_Table_Name &lt;br /&gt;       and CONSTRAINT_TYPE  = 'R' &lt;br /&gt;       order by TABLE_NAME, CONSTRAINT_NAME; &lt;br /&gt; &lt;br /&gt;cursor ConColumns is &lt;br /&gt;       select CONSTRAINT_NAME, &lt;br /&gt;              TABLE_NAME, &lt;br /&gt;              COLUMN_NAME, &lt;br /&gt;              POSITION &lt;br /&gt;       from user_cons_columns &lt;br /&gt;       where OWNER = USER &lt;br /&gt;       and   CONSTRAINT_NAME = t_CONSTRAINT_NAME &lt;br /&gt;       order by POSITION; &lt;br /&gt; &lt;br /&gt;cursor IndexColumns is &lt;br /&gt;       select TABLE_NAME, &lt;br /&gt;              COLUMN_NAME, &lt;br /&gt;              POSITION &lt;br /&gt;       from user_cons_columns &lt;br /&gt;       where OWNER = USER &lt;br /&gt;       and   CONSTRAINT_NAME = t_CONSTRAINT_NAME &lt;br /&gt;       order by POSITION; &lt;br /&gt; &lt;br /&gt;DebugLevel number := 99; -- &gt;&gt; 99 = dump all info` &lt;br /&gt;DebugFlag varchar(1) := 'N'; -- Turn Debugging on &lt;br /&gt;t_Error_Found  varchar(1); &lt;br /&gt; &lt;br /&gt;begin &lt;br /&gt; &lt;br /&gt;  tLineNum := 1000; &lt;br /&gt;  open UserTabs; &lt;br /&gt;  LOOP &lt;br /&gt;    Fetch UserTabs into t_TABLE_NAME; &lt;br /&gt;    t_Error_Found := 'N'; &lt;br /&gt;    exit when UserTabs%NOTFOUND; &lt;br /&gt; &lt;br /&gt;    -- Log current table &lt;br /&gt;    tLineNum := tLineNum + 1; &lt;br /&gt;    insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;    ( tLineNum, NULL ); &lt;br /&gt; &lt;br /&gt;    tLineNum := tLineNum + 1; &lt;br /&gt;    insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;    ( tLineNum, 'Checking Table '||t_Table_Name); &lt;br /&gt; &lt;br /&gt;    l_Cons_Found_Flag := 'N'; &lt;br /&gt;    open TableCons; &lt;br /&gt;    LOOP &lt;br /&gt;      FETCH TableCons INTO t_CONSTRAINT_TYPE, &lt;br /&gt;                    t_CONSTRAINT_NAME, &lt;br /&gt;               t_R_CONSTRAINT_NAME; &lt;br /&gt;      exit when TableCons%NOTFOUND; &lt;br /&gt; &lt;br /&gt;      if ( DebugFlag = 'Y' and DebugLevel &gt;= 99 ) &lt;br /&gt;      then &lt;br /&gt;        begin &lt;br /&gt;          tLineNum := tLineNum + 1; &lt;br /&gt;          insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;          ( tLineNum, 'Found CONSTRAINT_NAME = '|| t_CONSTRAINT_NAME); &lt;br /&gt; &lt;br /&gt;          tLineNum := tLineNum + 1; &lt;br /&gt;          insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;          ( tLineNum, 'Found CONSTRAINT_TYPE = '|| t_CONSTRAINT_TYPE); &lt;br /&gt; &lt;br /&gt;          tLineNum := tLineNum + 1; &lt;br /&gt;          insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;          ( tLineNum, 'Found R_CONSTRAINT_NAME = '|| t_R_CONSTRAINT_NAME); &lt;br /&gt;          commit; &lt;br /&gt;        end; &lt;br /&gt;      end if; &lt;br /&gt; &lt;br /&gt;      open ConColumns; &lt;br /&gt;      LOOP &lt;br /&gt;        FETCH ConColumns INTO &lt;br /&gt;                          tt_CONSTRAINT_NAME, &lt;br /&gt;                          tt_TABLE_NAME, &lt;br /&gt;                          tt_COLUMN_NAME, &lt;br /&gt;                          tt_POSITION; &lt;br /&gt;        exit when ConColumns%NOTFOUND; &lt;br /&gt;        if ( DebugFlag = 'Y' and DebugLevel &gt;= 99 ) &lt;br /&gt;        then &lt;br /&gt;          begin &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, NULL ); &lt;br /&gt; &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Found CONSTRAINT_NAME = '|| tt_CONSTRAINT_NAME); &lt;br /&gt; &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Found TABLE_NAME = '|| tt_TABLE_NAME); &lt;br /&gt; &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Found COLUMN_NAME = '|| tt_COLUMN_NAME); &lt;br /&gt; &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Found POSITION = '|| tt_POSITION); &lt;br /&gt;          commit; &lt;br /&gt;          end; &lt;br /&gt;      end if; &lt;br /&gt; &lt;br /&gt;      begin &lt;br /&gt;        select 1 into tt_Dummy &lt;br /&gt;        from user_ind_columns &lt;br /&gt;        where   TABLE_NAME =  tt_TABLE_NAME &lt;br /&gt;        and     COLUMN_NAME = tt_COLUMN_NAME &lt;br /&gt;        and     COLUMN_POSITION = tt_POSITION; &lt;br /&gt; &lt;br /&gt;        if ( DebugFlag = 'Y' and DebugLevel &gt;= 99 ) &lt;br /&gt;        then &lt;br /&gt;        begin &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Row Has matching Index' ); &lt;br /&gt;        end; &lt;br /&gt;        end if; &lt;br /&gt;      exception &lt;br /&gt;      when Too_Many_Rows then &lt;br /&gt;      if ( DebugFlag = 'Y' and DebugLevel &gt;= 99 ) &lt;br /&gt;        then &lt;br /&gt;          begin &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Row Has matching Index' ); &lt;br /&gt;          end; &lt;br /&gt;        end if; &lt;br /&gt; &lt;br /&gt;      when no_data_found then &lt;br /&gt;        if ( DebugFlag = 'Y' and DebugLevel &gt;= 99 ) &lt;br /&gt;        then &lt;br /&gt;          begin &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'NO MATCH FOUND' ); &lt;br /&gt;          commit; &lt;br /&gt;          end; &lt;br /&gt;        end if; &lt;br /&gt; &lt;br /&gt;        t_Error_Found := 'Y'; &lt;br /&gt; &lt;br /&gt;        select distinct TABLE_NAME &lt;br /&gt;        into tt_dummyChar &lt;br /&gt;        from user_cons_columns &lt;br /&gt;        where OWNER = USER &lt;br /&gt;        and   CONSTRAINT_NAME = t_R_CONSTRAINT_NAME; &lt;br /&gt; &lt;br /&gt;        tLineNum := tLineNum + 1;&lt;br /&gt;        insert into ck_log ( LineNum, LineMsg ) values&lt;br /&gt;        ( tLineNum, 'Changing data in table '||tt_dummyChar&lt;br /&gt;                    ||' will lock table ' ||tt_TABLE_NAME);&lt;br /&gt; &lt;br /&gt;        commit; &lt;br /&gt;        tLineNum := tLineNum + 1; &lt;br /&gt;        insert into ck_log ( LineNum, LineMsg ) values&lt;br /&gt;        ( tLineNum,'Create an index on table '||tt_TABLE_NAME&lt;br /&gt;                   ||' with the following columns to remove lock problem');&lt;br /&gt;        &lt;br /&gt;        open IndexColumns ; &lt;br /&gt;        loop &lt;br /&gt;          Fetch IndexColumns into Err_TABLE_NAME, &lt;br /&gt;              Err_COLUMN_NAME, &lt;br /&gt;              Err_POSITION; &lt;br /&gt;          exit when IndexColumns%NotFound; &lt;br /&gt;          tLineNum := tLineNum + 1; &lt;br /&gt;          insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;          ( tLineNum,'Column = '||Err_COLUMN_NAME||' ('||Err_POSITION||')'); &lt;br /&gt;        end loop; &lt;br /&gt;        close IndexColumns; &lt;br /&gt;      end; &lt;br /&gt;    end loop; &lt;br /&gt;    commit; &lt;br /&gt;  close ConColumns; &lt;br /&gt;  end loop; &lt;br /&gt;  if ( t_Error_Found = 'N' ) &lt;br /&gt;  then &lt;br /&gt;    begin &lt;br /&gt;      tLineNum := tLineNum + 1; &lt;br /&gt;      insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;      ( tLineNum,'No foreign key errors found'); &lt;br /&gt;    end; &lt;br /&gt;  end if; &lt;br /&gt;  commit; &lt;br /&gt;  close TableCons; &lt;br /&gt;end loop; &lt;br /&gt;commit; &lt;br /&gt;end; &lt;br /&gt;/ &lt;br /&gt; &lt;br /&gt;select LineMsg&lt;br /&gt;from ck_log&lt;br /&gt;where LineMsg NOT LIKE 'Checking%' AND&lt;br /&gt;      LineMsg NOT LIKE 'No foreign key%'&lt;br /&gt;order by LineNum&lt;br /&gt;/&lt;br /&gt; &lt;br /&gt;----------- cut ---------------------- cut -------------- cut -------------- &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;========= &lt;br /&gt;Examples: &lt;br /&gt;========= &lt;br /&gt; &lt;br /&gt;LINEMSG                                                    &lt;br /&gt;  &lt;br /&gt;-------------------------------------------------------------------------- &lt;br /&gt;Changing&lt;br /&gt;data in table DEPT will lock table EMP&lt;br /&gt;Create an index on table EMP with the following columns to remove lock problem&lt;br /&gt; &lt;br /&gt;Column = DEPTNO (1)&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Changing data in table ITEM_CATEGORIES will lock table ITEMS&lt;br /&gt;Create an index on table ITEMS with the following columns to remove lock problem &lt;br /&gt; &lt;br /&gt;Column = ITEM_CAT (1) &lt;br /&gt;Column = ITEM_BUS_UNIT (2) &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Changing data in table EMP will lock table EMP &lt;br /&gt;Create an index on table EMP with the following columns to remove lock problem &lt;br /&gt; &lt;br /&gt;Column = MGR (1) &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Changing data in table ORD will lock table CUSTOMER &lt;br /&gt;Create an index on table CUSTOMER with the following columns to remove lock problem  &lt;br /&gt; &lt;br /&gt;Column = CUSTID (1)&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Disclaimer &lt;br /&gt; &lt;br /&gt;EXCEPT WHERE EXPRESSLY PROVIDED OTHERWISE, THE INFORMATION, SOFTWARE,&lt;br /&gt;PROVIDED ON AN "AS IS" AND "AS AVAILABLE" BASIS. ORACLE EXPRESSLY DISCLAIMS&lt;br /&gt;ALL WARRANTIES OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT&lt;br /&gt;LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR&lt;br /&gt;PURPOSE AND NON-INFRINGEMENT. ORACLE MAKES NO WARRANTY THAT: (A) THE RESULTS&lt;br /&gt;THAT MAY BE OBTAINED FROM THE USE OF THE SOFTWARE WILL BE ACCURATE OR&lt;br /&gt;RELIABLE; OR (B) THE INFORMATION, OR OTHER MATERIAL OBTAINED WILL MEET YOUR&lt;br /&gt;EXPECTATIONS. ANY CONTENT, MATERIALS, INFORMATION OR SOFTWARE DOWNLOADED OR&lt;br /&gt;OTHERWISE OBTAINED IS DONE AT YOUR OWN DISCRETION AND RISK. ORACLE SHALL HAVE&lt;br /&gt;NO RESPONSIBILITY FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR LOSS OF DATA THAT&lt;br /&gt;RESULTS FROM THE DOWNLOAD OF ANY CONTENT, MATERIALS, INFORMATION OR SOFTWARE.&lt;br /&gt; &lt;br /&gt;ORACLE RESERVES THE RIGHT TO MAKE CHANGES OR UPDATES TO THE SOFTWARE AT ANY&lt;br /&gt;TIME WITHOUT NOTICE.&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Limitation of Liability &lt;br /&gt; &lt;br /&gt;IN NO EVENT SHALL ORACLE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,&lt;br /&gt;SPECIAL OR CONSEQUENTIAL DAMAGES, OR DAMAGES FOR LOSS OF PROFITS, REVENUE,&lt;br /&gt;DATA OR USE, INCURRED BY YOU OR ANY THIRD PARTY, WHETHER IN AN ACTION IN&lt;br /&gt;CONTRACT OR TORT, ARISING FROM YOUR ACCESS TO, OR USE OF, THE SOFTWARE.&lt;br /&gt; &lt;br /&gt;SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OR EXCLUSION OF LIABILITY.&lt;br /&gt;ACCORDINGLY, SOME OF THE ABOVE LIMITATIONS MAY NOT APPLY TO YOU.&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Abstract &lt;br /&gt; &lt;br /&gt;SCRIPT TO CHECK FOR FOREIGN KEY LOCKING ISSUES &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Product Name, Product Version&lt;br /&gt; Rdbms:07.0.X &lt;br /&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Platform &lt;br /&gt; Platform Independent&lt;br /&gt; &lt;br /&gt;Date Created &lt;br /&gt; 07-NOV-2002&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Instructions &lt;br /&gt; &lt;br /&gt;Execution Environment:&lt;br /&gt;     &lt;SQL, SQL*Plus&gt;&lt;br /&gt; &lt;br /&gt;Access Privileges:&lt;br /&gt;     If run as owner of objects no special priveleges required&lt;br /&gt; &lt;br /&gt;Usage:&lt;br /&gt;     sqlplus &lt;user&gt;/&lt;pw&gt; @[SCRIPTFILE]&lt;br /&gt; &lt;br /&gt;Instructions:&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;PROOFREAD THIS SCRIPT BEFORE USING IT! Due to differences in the way text &lt;br /&gt;editors, e-mail packages, and operating systems handle text formatting (spaces, &lt;br /&gt;tabs, and carriage returns), this script may not be in an executable state&lt;br /&gt;when you first receive it. Check over the script to ensure that errors of&lt;br /&gt;this type are corrected.The script will produce an output file named [outputfile].&lt;br /&gt;This file can be viewed in a browser or uploaded for support analysis.&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Description &lt;br /&gt; &lt;br /&gt;This script checks the current users Foreign Keys to make sure of the  &lt;br /&gt;following: &lt;br /&gt; &lt;br /&gt;        1) All the FK columns have indexes to prevent a possible locking &lt;br /&gt;         &lt;br /&gt;        2) Checks the ORDER OF THE INDEXED COLUMNS. To prevent the locking &lt;br /&gt;        problem the columns MUST be indexed in the same order as the FK is &lt;br /&gt;        defined. &lt;br /&gt; &lt;br /&gt;        3) If the script finds a mismatch, the script reports the correct  &lt;br /&gt;        order of columns that need to be added to prevent the locking &lt;br /&gt;        problem. &lt;br /&gt; &lt;br /&gt;                        IMPORTANT, PLEASE NOTE &lt;br /&gt; &lt;br /&gt;        The potential locking issues, due to a FK column not being indexed, &lt;br /&gt;        apply to versions prior to Oracle V7.1.5.   &lt;br /&gt;        &lt;br /&gt; &lt;br /&gt;        This locking problem is discussed in the Oracle 7 Server, &lt;br /&gt;        Application Developer's Guide Page 6-10 under the section  &lt;br /&gt;        "On Index on the Foreign Key" &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;References &lt;br /&gt; &lt;br /&gt;&lt;Note:15476.1&gt; FAQ about Detecting and Resolving Locking Conflicts&lt;br /&gt; &lt;br /&gt;&lt;Note:33453.1&gt; REFERENTIAL INTEGRITY AND LOCKING&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Script &lt;br /&gt; &lt;br /&gt;======= &lt;br /&gt;Script: &lt;br /&gt;======= &lt;br /&gt; &lt;br /&gt;----------- cut ---------------------- cut -------------- cut -------------- &lt;br /&gt; &lt;br /&gt;SET ECHO off &lt;br /&gt;REM NAME:   TFSFKCHLK.SQL &lt;br /&gt;REM USAGE:"@path/tfsfkchk" &lt;br /&gt;REM -------------------------------------------------------------------------- &lt;br /&gt;REM REQUIREMENTS: &lt;br /&gt;REM    None -- checks only the USER_ views &lt;br /&gt;REM -------------------------------------------------------------------------- &lt;br /&gt;REM PURPOSE: &lt;br /&gt;REM    This file checks the current users Foreign Keys to make sure of the  &lt;br /&gt;REM    following: &lt;br /&gt;REM &lt;br /&gt;REM    1) All the FK columns are have indexes to prevent a possible locking &lt;br /&gt;REM       problem that can slow down the database. &lt;br /&gt;REM &lt;br /&gt;REM    2) Checks the ORDER OF THE INDEXED COLUMNS. To prevent the locking &lt;br /&gt;REM       problem the columns MUST be index in the same order as the FK is &lt;br /&gt;REM       defined. &lt;br /&gt;REM    &lt;br /&gt;REM    3) If the script finds and miss match the script reports the correct  &lt;br /&gt;REM       order of columns that need to be added to prevent the locking &lt;br /&gt;REM       problem. &lt;br /&gt;REM &lt;br /&gt;REM    NOTES: &lt;br /&gt;REM &lt;br /&gt;REM      - This locking problem is discussed in the  &lt;br /&gt;REM        Oracle 7 Server, Application Developer's Guide Page 6-10  &lt;br /&gt;REM        under the section "No Index on the Foreign Key" &lt;br /&gt;REM  &lt;br /&gt;REM ----------------------------------------------------------------------- &lt;br /&gt;REM EXAMPLE: &lt;br /&gt;REM    LINEMSG  &lt;br /&gt;REM    ------------------------------------------------------------------- &lt;br /&gt;REM    Changing data in table ITEMS will lock table ITEM_CATEGORIES &lt;br /&gt;REM    Create an index on the following columns to remove lock problem &lt;br /&gt;REM &lt;br /&gt;REM    Column = ITEM_CAT (1) &lt;br /&gt;REM    Column = ITEM_BUS_UNIT (2) &lt;br /&gt;REM     &lt;br /&gt;REM    Changing data in table ITEMS will lock table ITEM_CATEGORIES &lt;br /&gt;REM    Create an index on the following columns to remove lock problem &lt;br /&gt;REM  &lt;br /&gt;REM    Column = ITEM_CAT (1) &lt;br /&gt;REM    Column = ITEM_BUS_UNIT (2) &lt;br /&gt;REM ----------------------------------------------------------------------- &lt;br /&gt;REM DISCLAIMER: &lt;br /&gt;REM    This script is provided for educational purposes only. It is NOT  &lt;br /&gt;REM    supported by Oracle World Wide Technical Support. &lt;br /&gt;REM    The script has been tested and appears to work as intended. &lt;br /&gt;REM    You should always run new scripts on a test instance initially. &lt;br /&gt;REM ------------------------------------------------------------------------- &lt;br /&gt;REM Main text of script follows: &lt;br /&gt; &lt;br /&gt;drop table ck_log; &lt;br /&gt; &lt;br /&gt;create table ck_log ( &lt;br /&gt;LineNum number, &lt;br /&gt;LineMsg varchar2(2000)); &lt;br /&gt; &lt;br /&gt;declare &lt;br /&gt;t_CONSTRAINT_TYPE            user_constraints.CONSTRAINT_TYPE%type; &lt;br /&gt;t_CONSTRAINT_NAME            USER_CONSTRAINTS.CONSTRAINT_NAME%type; &lt;br /&gt;t_TABLE_NAME   USER_CONSTRAINTS.TABLE_NAME%type; &lt;br /&gt;t_R_CONSTRAINT_NAME          USER_CONSTRAINTS.R_CONSTRAINT_NAME%type; &lt;br /&gt;tt_CONSTRAINT_NAME           USER_CONS_COLUMNS.CONSTRAINT_NAME%type; &lt;br /&gt;tt_TABLE_NAME                USER_CONS_COLUMNS.TABLE_NAME%type; &lt;br /&gt;tt_COLUMN_NAME               USER_CONS_COLUMNS.COLUMN_NAME%type; &lt;br /&gt;tt_POSITION              USER_CONS_COLUMNS.POSITION%type; &lt;br /&gt;tt_Dummy                     number; &lt;br /&gt;tt_dummyChar                 varchar2(2000); &lt;br /&gt;l_Cons_Found_Flag            VarChar2(1); &lt;br /&gt;Err_TABLE_NAME                USER_CONSTRAINTS.TABLE_NAME%type; &lt;br /&gt;Err_COLUMN_NAME               USER_CONS_COLUMNS.COLUMN_NAME%type; &lt;br /&gt;Err_POSITION          USER_CONS_COLUMNS.POSITION%type; &lt;br /&gt; &lt;br /&gt;tLineNum number; &lt;br /&gt; &lt;br /&gt;cursor UserTabs is &lt;br /&gt;       select table_name &lt;br /&gt;       from   user_tables &lt;br /&gt;       -- where Table_Name = 'WORKERS_COMP_CLAIMS' &lt;br /&gt;       order by table_name; &lt;br /&gt; &lt;br /&gt;cursor TableCons is &lt;br /&gt;       select CONSTRAINT_TYPE, &lt;br /&gt;              CONSTRAINT_NAME, &lt;br /&gt;              R_CONSTRAINT_NAME &lt;br /&gt;       from user_constraints &lt;br /&gt;       where OWNER = USER &lt;br /&gt;       and table_name = t_Table_Name &lt;br /&gt;       and CONSTRAINT_TYPE  = 'R' &lt;br /&gt;       order by TABLE_NAME, CONSTRAINT_NAME; &lt;br /&gt; &lt;br /&gt;cursor ConColumns is &lt;br /&gt;       select CONSTRAINT_NAME, &lt;br /&gt;    TABLE_NAME, &lt;br /&gt;              COLUMN_NAME, &lt;br /&gt;              POSITION &lt;br /&gt;       from user_cons_columns &lt;br /&gt;       where OWNER = USER &lt;br /&gt;       and   CONSTRAINT_NAME = t_CONSTRAINT_NAME &lt;br /&gt;       order by POSITION; &lt;br /&gt; &lt;br /&gt;cursor IndexColumns is &lt;br /&gt;       select TABLE_NAME, &lt;br /&gt;              COLUMN_NAME, &lt;br /&gt;              POSITION &lt;br /&gt;       from user_cons_columns &lt;br /&gt;       where OWNER = USER &lt;br /&gt;       and   CONSTRAINT_NAME = t_CONSTRAINT_NAME &lt;br /&gt;       order by POSITION; &lt;br /&gt; &lt;br /&gt;DebugLevel number := 99; -- &gt;&gt; 99 = dump all info` &lt;br /&gt;DebugFlag varchar(1) := 'N'; -- Turn Debugging on &lt;br /&gt;t_Error_Found  varchar(1); &lt;br /&gt; &lt;br /&gt;begin &lt;br /&gt; &lt;br /&gt;  tLineNum := 1000; &lt;br /&gt;  open UserTabs; &lt;br /&gt;  LOOP &lt;br /&gt;    Fetch UserTabs into t_TABLE_NAME; &lt;br /&gt;    t_Error_Found := 'N'; &lt;br /&gt;    exit when UserTabs%NOTFOUND; &lt;br /&gt; &lt;br /&gt;    -- Log current table &lt;br /&gt;    tLineNum := tLineNum + 1; &lt;br /&gt;    insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;    ( tLineNum, NULL ); &lt;br /&gt; &lt;br /&gt;    tLineNum := tLineNum + 1; &lt;br /&gt;    insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;    ( tLineNum, 'Checking Table '||t_Table_Name); &lt;br /&gt; &lt;br /&gt;    l_Cons_Found_Flag := 'N'; &lt;br /&gt;    open TableCons; &lt;br /&gt;    LOOP &lt;br /&gt;      FETCH TableCons INTO t_CONSTRAINT_TYPE, &lt;br /&gt;                    t_CONSTRAINT_NAME, &lt;br /&gt;               t_R_CONSTRAINT_NAME; &lt;br /&gt;      exit when TableCons%NOTFOUND; &lt;br /&gt; &lt;br /&gt;      if ( DebugFlag = 'Y' and DebugLevel &gt;= 99 ) &lt;br /&gt;      then &lt;br /&gt;        begin &lt;br /&gt;          tLineNum := tLineNum + 1; &lt;br /&gt;          insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;          ( tLineNum, 'Found CONSTRAINT_NAME = '|| t_CONSTRAINT_NAME); &lt;br /&gt; &lt;br /&gt;   tLineNum := tLineNum + 1; &lt;br /&gt;          insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;          ( tLineNum, 'Found CONSTRAINT_TYPE = '|| t_CONSTRAINT_TYPE); &lt;br /&gt; &lt;br /&gt;        tLineNum := tLineNum + 1; &lt;br /&gt;          insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;          ( tLineNum, 'Found R_CONSTRAINT_NAME = '|| t_R_CONSTRAINT_NAME); &lt;br /&gt;          commit; &lt;br /&gt;        end; &lt;br /&gt;      end if; &lt;br /&gt; &lt;br /&gt;      open ConColumns; &lt;br /&gt; LOOP &lt;br /&gt;        FETCH ConColumns INTO &lt;br /&gt;                          tt_CONSTRAINT_NAME, &lt;br /&gt;                          tt_TABLE_NAME, &lt;br /&gt;                          tt_COLUMN_NAME, &lt;br /&gt;                          tt_POSITION; &lt;br /&gt;        exit when ConColumns%NOTFOUND; &lt;br /&gt;        if ( DebugFlag = 'Y' and DebugLevel &gt;= 99 ) &lt;br /&gt;        then &lt;br /&gt;          begin &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, NULL ); &lt;br /&gt; &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;   ( tLineNum, 'Found CONSTRAINT_NAME = '|| tt_CONSTRAINT_NAME); &lt;br /&gt; &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Found TABLE_NAME = '|| tt_TABLE_NAME); &lt;br /&gt; &lt;br /&gt;tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Found COLUMN_NAME = '|| tt_COLUMN_NAME); &lt;br /&gt; &lt;br /&gt;    tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Found POSITION = '|| tt_POSITION); &lt;br /&gt;          commit; &lt;br /&gt;          end; &lt;br /&gt;      end if; &lt;br /&gt; &lt;br /&gt;      begin &lt;br /&gt;        select 1 into tt_Dummy &lt;br /&gt;        from user_ind_columns &lt;br /&gt;        where   TABLE_NAME =  tt_TABLE_NAME &lt;br /&gt;  and     COLUMN_NAME = tt_COLUMN_NAME &lt;br /&gt;        and     COLUMN_POSITION = tt_POSITION; &lt;br /&gt; &lt;br /&gt;        if ( DebugFlag = 'Y' and DebugLevel &gt;= 99 ) &lt;br /&gt;        then &lt;br /&gt;  begin &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Row Has matching Index' ); &lt;br /&gt;       end; &lt;br /&gt;        end if; &lt;br /&gt;      exception &lt;br /&gt;      when Too_Many_Rows then &lt;br /&gt;  if ( DebugFlag = 'Y' and DebugLevel &gt;= 99 ) &lt;br /&gt;        then &lt;br /&gt;          begin &lt;br /&gt;       tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'Row Has matching Index' ); &lt;br /&gt;          end; &lt;br /&gt;        end if; &lt;br /&gt; &lt;br /&gt;      when no_data_found then &lt;br /&gt;        if ( DebugFlag = 'Y' and DebugLevel &gt;= 99 ) &lt;br /&gt;        then &lt;br /&gt;          begin &lt;br /&gt;            tLineNum := tLineNum + 1; &lt;br /&gt;            insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;            ( tLineNum, 'NO MATCH FOUND' ); &lt;br /&gt;          commit; &lt;br /&gt;          end; &lt;br /&gt;        end if; &lt;br /&gt; &lt;br /&gt;      t_Error_Found := 'Y'; &lt;br /&gt; &lt;br /&gt;        select distinct TABLE_NAME &lt;br /&gt;        into tt_dummyChar &lt;br /&gt;        from user_cons_columns &lt;br /&gt;        where OWNER = USER &lt;br /&gt;        and   CONSTRAINT_NAME = t_R_CONSTRAINT_NAME; &lt;br /&gt; &lt;br /&gt;        tLineNum := tLineNum + 1; &lt;br /&gt;    insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;        ( tLineNum, 'Changing data in table '||tt_TABLE_NAME &lt;br /&gt;                    ||' will lock table ' ||tt_dummyChar); &lt;br /&gt; &lt;br /&gt;        commit; &lt;br /&gt;        tLineNum := tLineNum + 1; &lt;br /&gt;        insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;        ( tLineNum,'Create an index on the following columns to remove lock  &lt;br /&gt;problem'); &lt;br /&gt;        open IndexColumns ; &lt;br /&gt; loop &lt;br /&gt;          Fetch IndexColumns into Err_TABLE_NAME, &lt;br /&gt;              Err_COLUMN_NAME, &lt;br /&gt;              Err_POSITION; &lt;br /&gt;          exit when IndexColumns%NotFound; &lt;br /&gt;        tLineNum := tLineNum + 1; &lt;br /&gt;          insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;          ( tLineNum,'Column = '||Err_COLUMN_NAME||' ('||Err_POSITION||')'); &lt;br /&gt;          end loop; &lt;br /&gt;        close IndexColumns; &lt;br /&gt;      end; &lt;br /&gt;    end loop; &lt;br /&gt;    commit; &lt;br /&gt;  close ConColumns; &lt;br /&gt;  end loop; &lt;br /&gt;  if ( t_Error_Found = 'N' ) &lt;br /&gt;  then &lt;br /&gt;    begin &lt;br /&gt;      tLineNum := tLineNum + 1; &lt;br /&gt;      insert into ck_log ( LineNum, LineMsg ) values &lt;br /&gt;      ( tLineNum,'No foreign key errors found'); &lt;br /&gt;    end; &lt;br /&gt;  end if; &lt;br /&gt;  commit; &lt;br /&gt;  close TableCons; &lt;br /&gt;end loop; &lt;br /&gt;commit; &lt;br /&gt;end; &lt;br /&gt; &lt;br /&gt;/ &lt;br /&gt; &lt;br /&gt;select LineMsg &lt;br /&gt;from ck_log &lt;br /&gt;where LineMsg NOT LIKE 'Checking%' AND &lt;br /&gt;      LineMsg NOT LIKE 'No Probl%' &lt;br /&gt;order by LineNum &lt;br /&gt;/ &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;----------- cut ---------------------- cut -------------- cut -------------- &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;========= &lt;br /&gt;Examples: &lt;br /&gt;========= &lt;br /&gt; &lt;br /&gt;LINEMSG                                                    &lt;br /&gt;  &lt;br /&gt;-------------------------------------------------------------------------- &lt;br /&gt;Changing&lt;br /&gt;data in table EMP will lock table DEPT &lt;br /&gt;Create an index on the following columns to remove lock  &lt;br /&gt;problem                                                                        &lt;br /&gt; &lt;br /&gt;Column&lt;br /&gt;= DEPTNO (1) &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Changing data in table EMP will lock table EMP &lt;br /&gt;Create an index on the following columns to remove lock &lt;br /&gt;problem                                      &lt;br /&gt; &lt;br /&gt;Column = MGR (1) &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Changing data in table ITEMS will lock table ITEM_CATEGORIES &lt;br /&gt;Create an index on the following columns to remove lock  &lt;br /&gt;problem &lt;br /&gt; &lt;br /&gt;Column = ITEM_CAT (1) &lt;br /&gt;Column = ITEM_BUS_UNIT (2) &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Changing data in table ITEMS will lock table ITEM_CATEGORIES &lt;br /&gt;Create an index on the following columns to remove lock &lt;br /&gt;problem &lt;br /&gt; &lt;br /&gt;Column = ITEM_CAT (1) &lt;br /&gt;Column = ITEM_BUS_UNIT (2) &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Changing data in table CUSTOMER will lock table ORD &lt;br /&gt;Create an index on the following columns to remove lock &lt;br /&gt;problem  &lt;br /&gt; &lt;br /&gt;Column = CUSTID (1)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8434915659673660624-7656357632653783545?l=oracle10guru.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://oracle10guru.blogspot.com/feeds/7656357632653783545/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8434915659673660624&amp;postID=7656357632653783545' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8434915659673660624/posts/default/7656357632653783545'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8434915659673660624/posts/default/7656357632653783545'/><link rel='alternate' type='text/html' href='http://oracle10guru.blogspot.com/2008/09/how-to-prevent-locks.html' title='How to Prevent Locks'/><author><name>ASHISH MITTAL</name><uri>http://www.blogger.com/profile/08380549011082398501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_Va-OfRMZJqU/TFUVl69pGSI/AAAAAAAAAhk/-fi5rgc18xI/S220/NEW2.jpg'/></author><thr:total>0</thr:total></entry></feed>
