Sql Oracle查询输出不正确

Sql Oracle查询输出不正确,sql,oracle,Sql,Oracle,对于检查约束(表级别,如BONUS_-CK)…它应仅在一行中显示数据,列名称以逗号分隔 比如奖金,税收 现在,它为表级约束显示2行,即加成 此外,查询应适用于所有版本(10g、11g、12c) 请帮助消除表级的重复行…在您的查询中,有几点我需要更改 首先,在底部,在dba\u约束和dba\u约束列之间有一个连接。这将导致查询中多列约束的每列有一行。如果您不想这样做,则必须从查询的主要部分删除dba\u cons\u列。在类似的情况下,另一个选项是将联接保持在dba\u cons\u列上,并添加一

对于检查约束(表级别,如BONUS_-CK)…它应仅在一行中显示数据,列名称以逗号分隔

比如奖金,税收

现在,它为表级约束显示2行,即加成 此外,查询应适用于所有版本(10g、11g、12c)


请帮助消除表级的重复行…

在您的查询中,有几点我需要更改

首先,在底部,在
dba\u约束
dba\u约束列
之间有一个连接。这将导致查询中多列约束的每列有一行。如果您不想这样做,则必须从查询的主要部分删除
dba\u cons\u列
。在类似的情况下,另一个选项是将联接保持在
dba\u cons\u列上
,并添加一个
groupby
,其中包含您从中选择的
dba\u约束中的所有列。但是,
search\u条件
是一个
LONG
列,您不能
LONG
列分组

如果需要以逗号分隔的列名列表,请使用
listag
函数。例如,要获取约束中的列列表,可以在子查询中使用以下命令:

            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 );
LISTAGG
将分组为一行的所有值连接在一起

类似地,要检测是否有多列或单列检查约束,需要在
dba\u cons\u columns
上进行另一个子查询。您目前正试图在您的
CASE
表达式中使用两个不同的
WHEN
子句来实现这一点:我建议只使用一个:write
WHEN uc.constraint\u type='C',然后…
,然后使用一个子查询来计算约束中的列数,并将单列或多列显示为合适

最后,请注意Oracle不是SQL Server。看起来您使用的是SQL Server中的几个术语,而Oracle中不存在这些术语。删除文本“clustered”:Oracle中没有此类术语。(Oracle确实有索引组织的表,但我从未使用过它们。)当uc.constraint_type='DEFAULT'…
时,也要去掉行
,因为Oracle中的列的默认值不是使用约束设置的

我最终得出以下结论,这似乎符合您的要求:

              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

我决定将
CHECK on column…
更改为
CHECK on single column
,因为该单列名称位于查询的其他位置,似乎不值得重复。您可以始终在其中放置一个
listag
表达式来获取列名

谢谢Luke…我终于编辑了你的共享查询,并解决了我的所有期望。谢谢
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'
         );