Skip to main content

Identify Missing PrimaryKeys in tables

-- DEFINE &TableOwnerPattern = &1
-- DEFINE &TableNamePattern = &2

-- COLUMN owner            FORMAT A25  HEADING 'Owner'
-- COLUMN table_name       FORMAT A30  HEADING 'Table'
-- COLUMN constraint_name  FORMAT A30  HEADING 'FK constraint'
-- COLUMN column_list      FORMAT A62  HEADING 'FK columns(s)'   WORD WRAP

WITH constr AS 
(
SELECT c.owner, 
       c.table_name, 
       c.constraint_name, 
       listagg(col.column_name, ', ') within group (ORDER BY col.column_name) column_list_alphabetic,
       listagg(col.column_name, ', ') within group (ORDER BY col.position)    column_list
  FROM dba_constraints c
  JOIN dba_cons_columns col ON ( col.owner = c.owner AND col.constraint_name = c.constraint_name AND col.table_name = c.table_name )
 WHERE c.constraint_type = 'R'
   AND c.owner           like '&TableOwnerPattern'
   AND c.table_name      like '&TableNamePattern' 
 GROUP BY c.owner, c.table_name, c.constraint_name
),
idx AS
(
SELECT table_owner, table_name, 
       listagg(column_name, ', ') within group (ORDER BY column_name)     column_list_alphabetic,
       listagg(column_name, ', ') within group (ORDER BY column_position) column_list
  FROM dba_ind_columns
 WHERE table_owner     like '&TableOwnerPattern'
   AND table_name      like '&TableNamePattern' 
 GROUP BY table_owner, table_name, index_owner, index_name
)
SELECT constr.owner, constr.table_name, constr.constraint_name, constr.column_list
  FROM constr
 WHERE NOT EXISTS ( SELECT 1 FROM idx WHERE constr.owner = idx.table_owner AND constr.table_name = idx.table_name 
                                        AND ( idx.column_list_alphabetic = constr.column_list_alphabetic 
                                              OR instr(idx.column_list,constr.column_list) = 1 )
                  );

Comments

Popular posts from this blog

Insert script with multiple cursors and condition check

DECLARE CURSOR C1 IS   SELECT ID FROM TABLE_NAME_1 WHERE COLUMN IN ('');   CURSOR C2     IS       SELECT ID FROM TABLE_NAME_2 WHERE COLUMN IN ('');              CURSOR C3 (CP_TABLE_01_ID NUMBER,CP_TABLE_02_ID NUMBER)         IS           SELECT COUNT(*) AS COUNT_UP           FROM TABLE_NAME_3           WHERE COLUMN_CONDITION_01=CP_TABLE_02_ID           AND COLUMN_CONDITION_02=CP_TABLE_01_ID; COUNT_UP NUMBER; BEGIN FOR R1 IN C1 LOOP     FOR R2 IN C2     LOOP          OPEN C3(R1.ID,R2.ID);        FETCH C3 INTO COUNT_UP;        CLOSE C3;               IF (COUNT_UP=0) THEN           INSERT           INTO TABL...

REF Cursor

REF CURSOR WILL BE DYNAMICALLY OPENS OR OPEN BASED ON A LOGIC. DECLARE TYPE C1 IS REF CURSOR ; CURSOR C IS SELECT * FROM DUAL; REF_CURSOR RC; BEGIN IF (TO_CHAR(SYSDATE, 'DD' ) = 30 ) THEN OPEN REF_CURSOR FOR 'SELECT * FROM TABLE1' ; ELSIF ( TO_CHAR(SYSDATE, 'DD' ) = 29 ) THEN OPEN REF_CURSOR FOR SELECT * FROM TABLE2; ELSE OPEN REF_CURSOR FOR SELECT * FROM DUAL; END IF ; OPEN C; END ;