我想知道列是否有PK
或者没有,所以我加入user_tab_cols
和user_constraints
来获取查询的类型,如果列的类型= ' P'结果= 1
我正在编写一个查询,从user_tab_cols
(连接表和列名称),user_constraints
中选择(以获取列的类型和名称约束)
select tb.table_name,
tb.column_name,
case
when uc.constraint_type ='P' then
1
else
0
end as PK,
uc.constraint_name
from user_tab_cols tb ,user_constraints uc
where tb.table_name = 'tab1'
and uc.table_name = tb.table_name
我的问题是我得到了重复的列,我有10列表tab1,我得到20列结果(重复)我知道因为我需要加入列与两者,但如果我这样做我只得到3行(因为user_constraints只包含3行)。
如何编写查询以获取表的所有列并检查它是否有pk?
答案 0 :(得分:2)
如果您想要源表中的所有列,并且缺少user_cons_columns
视图以获取适用于哪个列的约束,则需要使用左连接。
尝试这样的事情:
select cols.table_name
, cols.column_name
, col_cons.constraint_name
, usr_cons.constraint_type
from user_tab_columns cols
left join user_cons_columns col_cons
on col_cons.table_name = cols.table_name
and col_cons.column_name = cols.column_name
left join user_constraints usr_cons
on usr_cons.table_name = cols.table_name
and usr_cons.constraint_name = col_cons.constraint_name
where cols.table_name = 'YOUR_TABLE_NAME_HERE'
order by cols.column_name
;
对于没有任何类型约束的列,您将获得空值,如果您有复合约束,则可能会为多列创建相同的约束名称/类型。
如果某些列受到多个限制,您也会有多行,例如: a(一部分)主键,也有外键约束。
create table bar (a int primary key);
create table foo (a int, b int, c int
, constraint foo_pk primary key (a,b)
, constraint foo_fk foreign key(a) references bar(a));
select cols.table_name
, cols.column_name
, col_cons.constraint_name
, usr_cons.constraint_type
from user_tab_columns cols
left join user_cons_columns col_cons
on col_cons.table_name = cols.table_name
and col_cons.column_name = cols.column_name
left join user_constraints usr_cons
on usr_cons.table_name = cols.table_name
and usr_cons.constraint_name = col_cons.constraint_name
order by table_name, column_name
;
TABLE_NAME COLUMN_NAME CONSTRAINT_NAME CONSTRAINT_TYPE
------------------------------ ------------------------------ ------------------------------ ---------------
BAR A SYS_C007382 P
FOO A FOO_FK R
FOO A FOO_PK P
FOO B FOO_PK P
FOO C