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