我正在尝试解决以下问题(使用Oracle 11g数据库):我需要使用ALL_CONS_COLUMNS
表获取所有表列以及有关引用约束的信息(此列引用的表和列的名称),例如:
No. Column Details
--- ----------- ------------------------------------------------------
1 foo_id Type : NUMBER(9)
Constr : "foo_fk" References foo_table(id)
2 bar_id Type : NUMBER(9)
Constr : "bar_fk" References bar_table(id)
2 date_created Type : Date
有关表的约束的信息存储在ALL_CONSTRAINTS
中,约束(表和列名称)的详细描述存储在ALL_CONS_COLUMNS
中。
现在我有了这段代码:
SELECT
ROWNUM as "No.",
t.COLUMN_NAME as "Имя столбца",
'Type: ' || t.DATA_TYPE || (SELECT CASE
WHEN ac.CONSTRAINT_TYPE = 'R'
THEN chr(10) || 'Constr: ' || allcc.CONSTRAINT_NAME ||
' References ' || (SELECT TABLE_NAME FROM ALL_CONS_COLUMNS WHERE CONSTRAINT_NAME = ac.R_CONSTRAINT_NAME) ||
'(' || (SELECT COLUMN_NAME FROM ALL_CONS_COLUMNS WHERE CONSTRAINT_NAME = ac.R_CONSTRAINT_NAME) || ')'
ELSE ''
END AS Contype FROM DUAL) As "Атрибуты",
ac.CONSTRAINT_TYPE
FROM
ALL_CONS_COLUMNS allcc
INNER JOIN
ALL_TAB_COLUMNS t
ON t.TABLE_NAME = allcc.TABLE_NAME
AND t.COLUMN_NAME = allcc.COLUMN_NAME
INNER JOIN
(SELECT (CASE WHEN CONSTRAINT_TYPE = 'R' THEN 'R' ELSE NULL END) as CONSTRAINT_TYPE, CONSTRAINT_NAME, R_CONSTRAINT_NAME FROM ALL_CONSTRAINTS) ac
ON ac.CONSTRAINT_NAME = allcc.CONSTRAINT_NAME
WHERE
t.TABLE_NAME = 'SUPPLIES';
但是如果列具有多个约束,则它将在每个约束的输出中重复:
No. Column Details:
1 ID_SUPPLIER Type: NUMBER
2 ID_SHOP Type: NUMBER
3 DATE_SUPPLY Type: DATE
4 ID Type: NUMBER
5 ID_SHOP Type: NUMBER
Constr: FK_SUPPLIES_SHOP References SHOPS(ID)
6 ID_SUPPLIER Type: NUMBER
Constr: FK_SUPPLIES_SUPPLIER References SUPPLIERS(ID)
在此示例中,ID_SUPPLIER为2个约束重复两次(引用而非null)。 是否可以避免重复并在不使用PL \ SQL的情况下解决此问题?
答案 0 :(得分:1)
您可以使用窗口函数来删除重复的行;在这里,我使用ROW_NUMBER()
:
select rownum as no,
v1.*
from (SELECT t.COLUMN_NAME,
'Type: ' || t.DATA_TYPE ||
(SELECT CASE
WHEN ac.CONSTRAINT_TYPE = 'R' THEN
chr(10) || 'Constr: ' || allcc.CONSTRAINT_NAME || ' References ' ||
(SELECT TABLE_NAME
FROM ALL_CONS_COLUMNS
WHERE CONSTRAINT_NAME = ac.R_CONSTRAINT_NAME) || '(' ||
(SELECT COLUMN_NAME
FROM ALL_CONS_COLUMNS
WHERE CONSTRAINT_NAME = ac.R_CONSTRAINT_NAME) || ')'
ELSE
''
END AS Contype
FROM DUAL) As description,
ac.CONSTRAINT_TYPE,
row_number() over(partition by allcc.column_name order by(case constraint_type
when 'R' then
1
else
2
end)) as rn
FROM ALL_CONS_COLUMNS allcc
INNER JOIN ALL_TAB_COLUMNS t
ON t.TABLE_NAME = allcc.TABLE_NAME
AND t.COLUMN_NAME = allcc.COLUMN_NAME
INNER JOIN (SELECT (CASE
WHEN CONSTRAINT_TYPE = 'R' THEN
'R'
ELSE
NULL
END) as CONSTRAINT_TYPE,
CONSTRAINT_NAME,
R_CONSTRAINT_NAME
FROM ALL_CONSTRAINTS) ac
ON ac.CONSTRAINT_NAME = allcc.CONSTRAINT_NAME
WHERE t.TABLE_NAME = 'SUPPLIES') v1
where rn = 1;
这个