2015-06-29 22 views
0

我想知道,如果一列有PK或沒有,所以我加入user_tab_colsuser_constraints得到查詢的類型,如果列類型=「P」的結果= 1如何編寫一個查詢來獲取表的所有列並檢查它是否有pk或不是?

我編寫從
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列結果(重複)我知道,因爲我需要j oin列,但如果我這樣做,我只得到3行(因爲user_constraints只包含3行)。

如何編寫查詢以獲取表的所有列並檢查它是否有pk或no?

回答

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 
; 

你會得到空的沒有任何約束類型列,並有可能在同一約束名稱/多列類型,如果你有複合的約束。

如果某些列受到多個約束(例如,同時具有外鍵約束的(主鍵的一部分)主鍵。

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                    
+0

感謝您的查詢,但具體怎麼一個表名? – Moudiz

+0

只需像通常那樣在連接之後(在'order by之前)添加'where cols.table_name ='XXX''。 – Mat

+0

啊是的,我加了'和'它給了我不同的結果。不管怎樣,謝謝。 – Moudiz

相關問題