0
            CREATE OR REPLACE PROCEDURE test_con(p_table_owner IN varchar2, p_table_name IN varchar2, p_result OUT sys_refcursor) AS BEGIN OPEN p_result
FOR
SELECT *
FROM
    (SELECT CASE
                  WHEN uc.constraint_type ='C' THEN
                         (SELECT DECODE(COUNT(*), 1, 'CHECK on single column', 'CHECK Table level')
                          FROM dba_cons_columns ucc2
                          WHERE ucc2.constraint_name = uc.constraint_name
                          AND ucc2.owner = uc.owner
                          AND ucc2.table_name = uc.table_name)
                  WHEN uc.constraint_type = 'P' THEN 'PRIMARY KEY'
                  ELSE ''
              END AS constraint_type,
              uc.constraint_name AS CONSTRAINT_NAME,
              uc.delete_rule AS "DELETE_ACTION",
              NULL AS "UPDATE_ACTION",
              uc.status AS "STATUS_ENABLED",
              NULL AS "STATUS_FOR_REPLICATION",
              uc.search_condition AS "CONSTRAINT_KEYS",
              NULL AS data_compression,
              NULL AS default_uid,
              NULL AS partition_qty,
              (SELECT LISTAGG(ucc1.column_name, ',') WITHIN GROUP (ORDER BY ucc1.column_name) 
                 FROM dba_cons_columns ucc1
                WHERE uc.constraint_name = ucc1.constraint_name
                  AND uc.table_name = ucc1.table_name
                  AND uc.owner = ucc1.owner) AS column_names
       FROM dba_constraints uc
       WHERE uc.OWNER = 'HR'
         AND uc.TABLE_NAME = 'EMP'
         );

 END;














SELECT *
FROM
    (SELECT CASE
                  WHEN uc.constraint_type ='C' THEN
                         (SELECT DECODE(COUNT(*), 1, 'CHECK on single column', 'CHECK Table level')
                          FROM dba_cons_columns ucc2
                          WHERE ucc2.constraint_name = uc.constraint_name
                          AND ucc2.owner = uc.owner
                          AND ucc2.table_name = uc.table_name)
                  WHEN uc.constraint_type = 'P' THEN 'PRIMARY KEY'
                  ELSE ''
              END AS constraint_type,
              uc.constraint_name AS CONSTRAINT_NAME,
              uc.delete_rule AS "DELETE_ACTION",
              NULL AS "UPDATE_ACTION",
              uc.status AS "STATUS_ENABLED",
              NULL AS "STATUS_FOR_REPLICATION",
              uc.search_condition AS "CONSTRAINT_KEYS",
              NULL AS data_compression,
              NULL AS default_uid,
              NULL AS partition_qty,
              (SELECT LISTAGG(ucc1.column_name, ',') WITHIN GROUP (ORDER BY ucc1.column_name) 
                 FROM dba_cons_columns ucc1
                WHERE uc.constraint_name = ucc1.constraint_name
                  AND uc.table_name = ucc1.table_name
                  AND uc.owner = ucc1.owner) AS column_names
       FROM dba_constraints uc
       WHERE uc.OWNER = 'HR'
         AND uc.TABLE_NAME = 'EMP'
         );



         SELECT *
FROM
    (SELECT CASE
                  WHEN uc.constraint_type ='C' THEN
                         (SELECT DECODE(COUNT(*), 1, 'CHECK on single column', 'CHECK Table level')
                          FROM dba_cons_columns ucc2
                          WHERE ucc2.constraint_name = uc.constraint_name
                          AND ucc2.owner = uc.owner
                          AND ucc2.table_name = uc.table_name)
                  WHEN uc.constraint_type = 'P' THEN 'PRIMARY KEY'
                  ELSE ''
              END AS constraint_type,
              uc.constraint_name AS CONSTRAINT_NAME,
              uc.delete_rule AS "DELETE_ACTION",
              NULL AS "UPDATE_ACTION",
              uc.status AS "STATUS_ENABLED",
              NULL AS "STATUS_FOR_REPLICATION",
              uc.search_condition AS "CONSTRAINT_KEYS",
              NULL AS data_compression,
              NULL AS default_uid,
              NULL AS partition_qty,
              (SELECT LISTAGG(ucc1.column_name, ',') WITHIN GROUP (ORDER BY ucc1.column_name) 
                 FROM dba_cons_columns ucc1
                WHERE uc.constraint_name = ucc1.constraint_name
                  AND uc.table_name = ucc1.table_name
                  AND uc.owner = ucc1.owner) AS column_names
       FROM dba_constraints uc
       WHERE uc.OWNER = 'HR'
         AND uc.TABLE_NAME = 'EMP'
         );


         SELECT *
FROM
    (SELECT CASE
                  WHEN uc.constraint_type ='C' THEN
                         (SELECT DECODE(COUNT(*), 1, 'CHECK on column ' || LISTAGG(ucc2.column_name, ',') WITHIN GROUP (ORDER BY ucc2.column_name) , 'CHECK Table level')
                          FROM dba_cons_columns ucc2
                          WHERE ucc2.constraint_name = uc.constraint_name
                          AND ucc2.owner = uc.owner
                          AND ucc2.table_name = uc.table_name)
                  WHEN uc.constraint_type = 'P' THEN 'PRIMARY KEY (clustered)'
                  WHEN uc.constraint_type = 'DEFAULT' THEN 'DEFAULT on column ' || ucc1.column_name
                  ELSE ''
              END AS constraint_type,
              uc.constraint_name AS CONSTRAINT_NAME,
              uc.delete_rule AS "DELETE_ACTION",
              NULL AS "UPDATE_ACTION",
              uc.status AS "STATUS_ENABLED",
              NULL AS "STATUS_FOR_REPLICATION",
              uc.search_condition AS "CONSTRAINT_KEYS",
              NULL AS data_compression,
              NULL AS default_uid,
              NULL AS partition_qty,
              (SELECT LISTAGG(ucc1.column_name, ',') WITHIN GROUP (ORDER BY ucc1.column_name) 
                 FROM dba_cons_columns ucc1
                WHERE uc.constraint_name = ucc1.constraint_name
                  AND uc.table_name = ucc1.table_name
                  AND uc.owner = ucc1.owner) AS column_names
       FROM dba_constraints uc,
       dba_cons_columns ucc1
       WHERE   uc.constraint_name = ucc1.constraint_name
     AND uc.table_name = ucc1.table_name
     AND uc.owner = ucc1.owner
       AND   uc.OWNER = 'HR'
         AND uc.TABLE_NAME = 'EMP'

          UNION ALL SELECT 'DEFAULT on column ' || cc.column_name,
                    'DF_' || cc.column_name AS CONSTRAINT_NAME,
                    NULL AS "DELETE_ACTION",
                    NULL AS "UPDATE_ACTION",
                    NULL AS "STATUS_ENABLED",
                    NULL AS "STATUS_FOR_REPLICATION",
                    cc.data_default AS "CONSTRAINT_KEYS",
                    NULL AS data_compression,
                    NULL AS default_uid,
                    NULL AS partition_qty,
                    cc.column_name
   FROM dba_tab_columns cc
   WHERE cc.owner='HR'
     AND cc.table_name='EMP'
     AND data_default IS NOT NULL );




     SELECT *
FROM
    (SELECT CASE
                  WHEN uc.constraint_type ='C' THEN
                         (SELECT DECODE(COUNT(*), 1, 'CHECK on column ' || LISTAGG(ucc2.column_name, ',') WITHIN GROUP (ORDER BY ucc2.column_name) , 'CHECK Table level')
                          FROM dba_cons_columns ucc2
                          WHERE ucc2.constraint_name = uc.constraint_name
                          AND ucc2.owner = uc.owner
                          AND ucc2.table_name = uc.table_name)
                  WHEN uc.constraint_type = 'P' THEN 'PRIMARY KEY (clustered)'
                  WHEN uc.constraint_type = 'DEFAULT' THEN 'DEFAULT on column ' 
                  ELSE ''
              END AS constraint_type,
              uc.constraint_name AS CONSTRAINT_NAME,
              uc.delete_rule AS "DELETE_ACTION",
              NULL AS "UPDATE_ACTION",
              uc.status AS "STATUS_ENABLED",
              NULL AS "STATUS_FOR_REPLICATION",
              uc.search_condition AS "CONSTRAINT_KEYS",
              NULL AS data_compression,
              NULL AS default_uid,
              NULL AS partition_qty,
              (SELECT LISTAGG(ucc1.column_name, ',') WITHIN GROUP (ORDER BY ucc1.column_name) 
                 FROM dba_cons_columns ucc1
                WHERE uc.constraint_name = ucc1.constraint_name
                  AND uc.table_name = ucc1.table_name
                  AND uc.owner = ucc1.owner) AS column_names
       FROM dba_constraints uc

       WHERE   
      uc.OWNER = 'HR'
         AND uc.TABLE_NAME = 'EMP'

          UNION ALL SELECT 'DEFAULT on column ' || cc.column_name,
                    'DF_' || cc.column_name AS CONSTRAINT_NAME,
                    NULL AS "DELETE_ACTION",
                    NULL AS "UPDATE_ACTION",
                    NULL AS "STATUS_ENABLED",
                    NULL AS "STATUS_FOR_REPLICATION",
                    cc.data_default AS "CONSTRAINT_KEYS",
                    NULL AS data_compression,
                    NULL AS default_uid,
                    NULL AS partition_qty,
                    cc.column_name
   FROM dba_tab_columns cc
   WHERE cc.owner='HR'
     AND cc.table_name='EMP'
     AND data_default IS NOT NULL );



     SELECT *
FROM
    (SELECT CASE
                  WHEN uc.constraint_type ='C' THEN
                         (SELECT DECODE(COUNT(*), 1, 'CHECK on column ' || LISTAGG(ucc2.column_name, ',') WITHIN GROUP (ORDER BY ucc2.column_name) , 'CHECK Table level')
                          FROM dba_cons_columns ucc2
                          WHERE ucc2.constraint_name = uc.constraint_name
                          AND ucc2.owner = uc.owner
                          AND ucc2.table_name = uc.table_name)
                  WHEN uc.constraint_type = 'P' THEN 'PRIMARY KEY (clustered)'
                  WHEN uc.constraint_type = 'DEFAULT' THEN 'DEFAULT on column ' 
                  ELSE ''
              END AS constraint_type,
              uc.constraint_name AS CONSTRAINT_NAME,
              uc.delete_rule AS "DELETE_ACTION",
              NULL AS "UPDATE_ACTION",
              uc.status AS "STATUS_ENABLED",
              NULL AS "STATUS_FOR_REPLICATION",
              uc.search_condition AS "CONSTRAINT_KEYS",
              NULL AS data_compression,
              NULL AS default_uid,
              NULL AS partition_qty,
              (SELECT LISTAGG(ucc1.column_name, ',') WITHIN GROUP (ORDER BY ucc1.column_name) 
                 FROM dba_cons_columns ucc1
                WHERE uc.constraint_name = ucc1.constraint_name
                  AND uc.table_name = ucc1.table_name
                  AND uc.owner = ucc1.owner) AS column_names
       FROM dba_constraints uc

       WHERE   
      uc.OWNER = 'HR'
         AND uc.TABLE_NAME = 'T'

          UNION ALL SELECT 'DEFAULT on column ' || cc.column_name,
                    'DF_' || cc.column_name AS CONSTRAINT_NAME,
                    NULL AS "DELETE_ACTION",
                    NULL AS "UPDATE_ACTION",
                    NULL AS "STATUS_ENABLED",
                    NULL AS "STATUS_FOR_REPLICATION",
                    cc.data_default AS "CONSTRAINT_KEYS",
                    NULL AS data_compression,
                    NULL AS default_uid,
                    NULL AS partition_qty,
                    cc.column_name
   FROM dba_tab_columns cc
   WHERE cc.owner='HR'
     AND cc.table_name='T'
     AND data_default IS NOT NULL );

For check constraint(table level like BONUS_CK)...it should display data only in one row with comma-separated column names...

like bonus,tax

Now it displays 2 rows for table level constraint i.e bonus_ck Also query should work with all versions(10g,11g,12c)

Please help with eliminating this duplicate row for table level...

0

1 Answer 1

1

Going through your query, there are a few things that I would change.

Firstly, at the bottom, you have a join between dba_constraints and dba_cons_columns. This will cause your query to have one row for each column of a multi-column constraint. If you don't want this, you will have to remove dba_cons_columns from the main part of your query. In situations similar to this, another option would be to keep the join on dba_cons_columns and add a GROUP BY containing all columns in dba_constraints that you were selecting from. However, search_condition is a LONG and you can't GROUP BY a LONG column.

If you want a comma-separated list of column names, use the LISTAGG function. For example, to get the list of columns in a constraint, you could use the following in a subquery:

              SELECT LISTAGG(ucc1.column_name, ',') WITHIN GROUP (ORDER BY ucc1.column_name) 
                 FROM dba_cons_columns ucc1
                WHERE uc.constraint_name = ucc1.constraint_name
                  AND uc.table_name = ucc1.table_name
                  AND uc.owner = ucc1.owner

LISTAGG concatenates together all values grouped into a single row.

Similarly, to detect whether you have a multi-column or single-column check constraint, you need another subquery on dba_cons_columns. You are presently attempting to use two different WHEN clauses in your CASE expression to do this: I would suggest using just the one: write WHEN uc.constraint_type = 'C' THEN ... and then have a subquery that counts up the number of columns in the constraint and shows either single-column or multi-column as appropriate.

Finally, please note that Oracle is not SQL Server. It seems you are using a couple of terms from SQL Server that do not exist in Oracle. Remove the text 'clustered': there is no such terminology in Oracle. (Oracle does have index-organized tables but I've never used them.) Also get rid of the line WHEN uc.constraint_type = 'DEFAULT' ..., as default values for columns in Oracle are not set using constraints.

I ended up with the following, which appears to do what you want:

SELECT *
FROM
    (SELECT CASE
                  WHEN uc.constraint_type ='C' THEN
                         (SELECT DECODE(COUNT(*), 1, 'CHECK on single column', 'CHECK Table level')
                          FROM dba_cons_columns ucc2
                          WHERE ucc2.constraint_name = uc.constraint_name
                          AND ucc2.owner = uc.owner
                          AND ucc2.table_name = uc.table_name)
                  WHEN uc.constraint_type = 'P' THEN 'PRIMARY KEY'
                  ELSE ''
              END AS constraint_type,
              uc.constraint_name AS CONSTRAINT_NAME,
              uc.delete_rule AS "DELETE_ACTION",
              NULL AS "UPDATE_ACTION",
              uc.status AS "STATUS_ENABLED",
              NULL AS "STATUS_FOR_REPLICATION",
              uc.search_condition AS "CONSTRAINT_KEYS",
              NULL AS data_compression,
              NULL AS default_uid,
              NULL AS partition_qty,
              (SELECT LISTAGG(ucc1.column_name, ',') WITHIN GROUP (ORDER BY ucc1.column_name) 
                 FROM dba_cons_columns ucc1
                WHERE uc.constraint_name = ucc1.constraint_name
                  AND uc.table_name = ucc1.table_name
                  AND uc.owner = ucc1.owner) AS column_names
       FROM dba_constraints uc
       WHERE uc.OWNER = 'HR'
         AND uc.TABLE_NAME = 'EMP'
         );

I decided to change CHECK on column ... to CHECK on single column because the single column name is elsewhere in the query and it didn't seem worth repeating it. You can always put a LISTAGG expression in there to get the column name out.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Luke...I have edited your shared query finally with all of my expectations and solved them..thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.