0

I'm performing an Oracle-based data load, and an app that is accessing the database is enforcing some virtual foreign keys that the database doesn't enforce via the ALL_CONS_COLUMNS table. Since the app is a black box (meaning I don't have access to the specs or source code), I'm forced to go hunting for these "possible" keys by getting a list of all the primary keys in the DB, and then finding all tables that have the same combination of fields present in their structure. I'm trying to find an efficient and automated way to do this, especially considering the database is huge in size. Any ideas?

  • Possible duplicate of [Tools for discovering de facto foreign keys in databases?](https://stackoverflow.com/questions/7031203/tools-for-discovering-de-facto-foreign-keys-in-databases) – philipxy Sep 27 '19 at 01:59
  • "Any ideas?" is not a valid question. Also this shows no research. Also this is nevertheless a faq. Before considering posting please always google your error message or many clear, concise & precise phrasings of your question/problem/goal, with & without your particular strings/names & site:stackoverflow.com & tags, & read many answers. If you post a question, use one phrasing as title. See [ask] & the voting arrow mouseover texts. – philipxy Sep 27 '19 at 02:01

1 Answers1

1

Here's something to get started with:

WITH cteIndexes AS (select ui.TABLE_NAME, ui.INDEX_NAME, ui.INDEX_TYPE, ui.UNIQUENESS,
                           ic.COLUMN_NAME, ic.COLUMN_POSITION
                      from user_indexes ui
                      INNER JOIN USER_IND_COLUMNS ic
                        ON ic.TABLE_NAME = ui.TABLE_NAME
                      WHERE ui.uniqueness = 'UNIQUE'),
     cteCandidate_keys AS (SELECT c.TABLE_NAME, c.COLUMN_NAME, c.COLUMN_ID
                             FROM cteIndexes i
                             INNER JOIN USER_TAB_COLUMNS c
                               ON c.COLUMN_NAME = i.COLUMN_NAME
                             WHERE c.TABLE_NAME <> i.TABLE_NAME
                             ORDER BY c.TABLE_NAME, c.COLUMN_ID)
SELECT 'UNIQUE KEYS' AS TABLE_NAME, NULL AS COLUMN_NAME,
       NULL AS COLUMN_POSITION, NULL AS COLUMN_ID
  FROM DUAL
UNION ALL
SELECT TABLE_NAME, COLUMN_NAME, NULL, NULL
  FROM cteIndexes
UNION ALL
SELECT NULL, NULL, NULL, NULL FROM DUAL
UNION ALL
SELECT 'CANDIDATE FOREIGN KEYS', NULL, NULL, NULL FROM DUAL
UNION ALL
SELECT TABLE_NAME, COLUMN_NAME, NULL, COLUMN_ID
  FROM cteCandidate_keys

Fold, spindle, and mutilate as needed. :-)

dbfiddle here