简体   繁体   English

Oracle Query输出不正确

[英]Oracle Query output incorrect

            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... 对于检查约束(表级别,如BONUS_CK)...它应该仅在一行中显示数据,并用逗号分隔列名...

like bonus,tax 像奖金,税

Now it displays 2 rows for table level constraint ie bonus_ck Also query should work with all versions(10g,11g,12c) 现在,它针对表级约束显示2行,即bonus_ck。查询也应适用于所有版本(10g,11g,12c)

Please help with eliminating this duplicate row for table level... 请帮助消除此重复的表级行...

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 . 首先,在底部,您具有dba_constraintsdba_cons_columns之间的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. 如果您不希望这样做,则必须从查询的主要部分中删除dba_cons_columns 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. 在类似情况下,另一种选择是将dba_cons_columns保留在dba_cons_columns并添加一个GROUP BY其中包含dba_constraints中选择的dba_constraints中的所有列。 However, search_condition is a LONG and you can't GROUP BY a LONG column. 但是, search_conditionLONG ,您不能GROUP BY LONG列。

If you want a comma-separated list of column names, use the LISTAGG function. 如果要用逗号分隔的列名列表,请使用LISTAGG函数。 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. LISTAGG将分组为一行的所有值连接在一起。

Similarly, to detect whether you have a multi-column or single-column check constraint, you need another subquery on dba_cons_columns . 同样,要检测您是否具有多列检查约束或单列检查约束,您需要在dba_cons_columnsdba_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. 您目前正在尝试在CASE表达式中使用两个不同的WHEN子句来做到这一点:我建议只使用一个:写WHEN uc.constraint_type = 'C' THEN ...然后有一个子查询来计算约束中的列,并根据需要显示单列或多列。

Finally, please note that Oracle is not SQL Server. 最后,请注意,Oracle不是SQL Server。 It seems you are using a couple of terms from SQL Server that do not exist in Oracle. 看来您正在使用SQL Server中Oracle中不存在的几个术语。 Remove the text 'clustered': there is no such terminology in Oracle. 删除“聚集”文本: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. (Oracle的确有按索引组织的表,但我从未使用过。)还应摆脱WHEN uc.constraint_type = 'DEFAULT' ... ,因为未使用约束为Oracle中的列设置默认值。

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. 我决定将CHECK on column ...上的CHECK on single column更改为CHECK on single column上的CHECK on single column因为单列名称在查询中的其他位置,并且似乎不值得重复。 You can always put a LISTAGG expression in there to get the column name out. 您总是可以在其中放置一个LISTAGG表达式来获取列名。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM