Home > Software engineering >  How to get schema name, table name and primary key in oracle database?
How to get schema name, table name and primary key in oracle database?

Time:01-03

I want to get schema name, table name and a boolean column for primary keys (if primary key exists in the table).

I used this query to do the task:

select DISTINCT  row_number() over(order by q.Schema, q.TableName, q.constraint_type) as Id
                                       ,q.Schema
                                       ,q.TableName
                                       ,q.constraint_type



                                   from (
                                        select at.owner as Schema
                                             , at.table_name as TableName
                                            ,ac.constraint_type
                                          from ALL_TABLES at 
                                          left join ALL_CONSTRAINTS ac
                                          on ac.owner = at.owner and ac.table_name = at.table_name 
                                         where at.temporary = 'N'
                                           and at.owner in ( 'Source_schema' )
                                           and at.owner not in ( 'CTXSYS', 'MDSYS', 'SYSTEM', 'XDB','SYS' )
                                           and ac.constraint_type in ('P','R','C') or ac.constraint_type != null





                                         group by at.owner, at.table_name,ac.constraint_type  ) q 
                                         order by q.TableName asc

I want to get all the table names and in the third column I want to know if that table contains a primary key. With this query, I am getting duplicate table names because it can contain more than one keys. But I only want to have a flag which tells if there is a primary key in that table. Here is the output of the above query which has duplicate table names: Output

CodePudding user response:

Isn't that what you asked for? This condition:

and ac.constraint_type in ('P','R','C')

will return 3 constraint types, while you need only primary keys. Therefore, remove R and C.


Alternatively, if you modify query a little bit so that constraint_type contains all types and add another column (a flag, which shows whether that table contains a primary key or not), you'd get this (I commented filter at line #16):

SQL>   SELECT ROW_NUMBER () OVER (ORDER BY q.schema, q.tablename) AS id,
  2           q.schema,
  3           q.tablename,
  4           LISTAGG (q.constraint_type, ', ')
  5              WITHIN GROUP (ORDER BY q.constraint_type) constraint_type,
  6           MAX (CASE WHEN q.constraint_type = 'P' THEN '*' ELSE NULL END) contains_pk
  7      FROM (SELECT DISTINCT
  8                   at.owner AS schema,
  9                   at.table_name AS tablename,
 10                   ac.constraint_type
 11              FROM all_tables at
 12                   LEFT JOIN all_constraints ac
 13                      ON     ac.owner = at.owner
 14                         AND ac.table_name = at.table_name
 15             WHERE        at.temporary = 'N'
 16                      --AND at.owner IN ('Source_schema')        --> commented
 17                      AND at.owner NOT IN ('CTXSYS',
 18                                           'MDSYS',
 19                                           'SYSTEM',
 20                                           'XDB',
 21                                           'SYS')
 22                      AND ac.constraint_type IN ('P', 'R', 'C')
 23                   OR ac.constraint_type IS NOT NULL) q
 24  GROUP BY q.schema, q.tablename
 25  ORDER BY q.tablename ASC;

Result:

        ID SCHEMA               TABLENAME                      CONSTRAINT C
---------- -------------------- ------------------------------ ---------- -
         1 SCOTT                ADVISER                        P, R       *
         2 SCOTT                BOOK_NAMES                     C, P       *
         3 SCOTT                CARTE                          P, R       *
         4 SCOTT                COMPTE                         P          *
         5 SCOTT                DEPARTMENT                     P          *
         6 SCOTT                DOCUMENT_TO_DROP               P          *
         7 SCOTT                EMP                            C
         8 SCOTT                EMPLEADO1                      C
         9 SCOTT                EMPLEADO2                      C
        10 SCOTT                EMPLOYEES                      C
        11 SCOTT                FILIALI_CHIUSE                 C
        12 SCOTT                NEW_DEPT                       P          *
        13 SCOTT                NOVCET                         P          *
        14 SCOTT                ORDERS                         P          *
        15 SCOTT                PERSONAL_INFO                  C
        16 SCOTT                RECORDING                      C, P, R    *
        17 SCOTT                TEACHER                        P          *
        18 SCOTT                VIEWS                          P          *

18 rows selected.

SQL>

[EDIT] According to comments you posted, you'd want to see tables that don't have any constraints. Currently, you can't because of conditions you put into the query - you explicitly specified that constraint type can't be NULL (note that such a condition isn't != null but is not null). Therefore, remove it. For example:

SQL> WITH
  2     data
  3     AS
  4        (SELECT DISTINCT at.owner, at.table_name, ac.constraint_type
  5           FROM all_tables at
  6                LEFT JOIN all_constraints ac
  7                   ON     ac.owner = at.owner
  8                      AND ac.table_name = at.table_name
  9          WHERE     at.temporary = 'N'
 10                AND at.owner NOT IN ('CTXSYS',
 11                                     'MDSYS',
 12                                     'SYSTEM',
 13                                     'XDB',
 14                                     'SYS'))
 15    SELECT ROW_NUMBER () OVER (ORDER BY owner, table_name) rn,
 16           owner,
 17           table_name,
 18           LISTAGG (constraint_type, ', ')
 19              WITHIN GROUP (ORDER BY constraint_Type) constraint_type,
 20           MAX (CASE WHEN constraint_type = 'P' THEN '*' ELSE NULL END) contains_pk
 21      FROM data
 22  GROUP BY owner, table_name
 23  ORDER BY owner, table_name;

Result:

        RN OWNER           TABLE_NAME                     CONSTRAINT_TYPE CONTAINS_PK
---------- --------------- ------------------------------ --------------- -----------
         1 ISPO            TOAD_PLAN_TABLE
         2 SCOTT           ACCNT_PROFILE_SPCL
         3 SCOTT           ADVISER                        P, R            *
         4 SCOTT           AUSRÜSTUNG
         5 SCOTT           AUTH_USER_REGISTRATION
         6 SCOTT           BF_USER
         7 SCOTT           BONUS
         8 SCOTT           BOOK_NAMES                     C, P            *
         9 SCOTT           CARTE                          P, R            *
        10 SCOTT           CATALOG
<snip>
        71 SCOTT           TUSER
        72 SCOTT           VIEWS                          P               *
        73 SCOTT           WAFFEN

73 rows selected.

SQL>
  • Related