2008-11-26 93 views
4

當編寫大型事務(大量插入,刪除,更新)並因此違反Informix中的約束(v10,但也應用於其他版本)時,我收到了一條不太有用的消息,例如,我違反了約束條件r190_710 。我怎樣才能找出哪個表和關鍵字被一定的約束所覆蓋?我只知道名字?如何從Informix中的名稱獲取約束詳細信息?

回答

6

託尼·安德魯斯建議(指向一個不同的終點爲URL):

Informix Guide to SQL: Reference看來你應該看看系統目錄表sysconstraints中和SYSINDICES。

該手冊介紹了Informix系統目錄。

SysConstraints表是分析約束的起點,當然,您可以在該表中找到約束名稱,然後從中找出其他詳細信息。

但是,您還必須查看其他表,而不僅僅是(甚至直接)SysIndices。

例如,我在我的數據庫的表上有很多NOT NULL約束。對於那些,約束類型是'N',並且不需要在別處尋找更多信息。

約束類型'P'表示主鍵;那需要通過SysIndexes視圖或SysIndices表進行更多的分析。同樣,約束類型'U'表示唯一約束,並需要SysIndexes視圖或SysIndices表中的額外信息。

約束類型'C'表示檢查約束;在SysChecks表中找到約束的文本(和二進制編譯後的表格)(數據類型'T'和'B';數據或多或少用Base-64編碼,儘管沒有'='填充最後在62和63上使用不同的字符)。

最後,約束類型'R'表示參照完整性約束。您可以使用SysReferences表來找出引用哪個表,然後使用SysIndexes或SysIndices來確定引用表和引用表上的哪些索引被使用,並從中發現相關的列。這可能會變得非常多毛!

0

從衝浪www.iiug.org(國際Informix用戶組),我發現這個不太容易的解決方案。

(1)從約束名稱獲取引用約束數據(通過將「AND st.tabname MATCHES?」替換爲「AND sc.constrname =?」,您可以獲取表的所有約束)。該聲明選擇了比此處所需的更多的字段,因爲它們在其他情況下可能很有趣。

SELECT si.part1, si.part2, si.part3, si.part4, si.part5, 
    si.part6, si.part7, si.part8, si.part9, si.part10, 
    si.part11, si.part12, si.part13, si.part14, si.part15, si.part16, 
    st.tabname, rt.tabname as reftable, sr.primary as primconstr, 
    sr.delrule, sc.constrid, sc.constrname, sc.constrtype, 
    si.idxname, si.tabid as tabid, rc.tabid as rtabid 
FROM 'informix'.systables st, 'informix'.sysconstraints sc, 
    'informix'.sysindexes si, 'informix'.sysreferences sr, 
    'informix'.systables rt, 'informix'.sysconstraints rc 
WHERE st.tabid = sc.tabid 
    AND st.tabtype != 'Q' 
    AND st.tabname NOT MATCHES 'cdr_deltab_[0-9][0-9][0-9][0-9][0-9][0-9]*' 
    AND rt.tabid = sr.ptabid 
    AND rc.tabid = sr.ptabid 
    AND sc.constrid = sr.constrid 
    AND sc.tabid = si.tabid 
    AND sc.idxname = si.idxname 
    AND sc.constrtype = 'R' 
    AND sc.constrname = ? 
    AND sr.primary = rc.constrid 
ORDER BY si.tabid, sc.constrname 

(2)使用第一部分-part16以確定哪些列由約束影響:部分[n]的含有不同於0的值包含用於列的列數。使用(3)找到列的名稱。

如果constrtype是 'R'(參考)使用下面的語句找到引用表的部分:

SELECT part1, part2, part3, part4, part5, part6, part7, part8, 
    part9, part10, part11, part12, part13, part14, part15, part16 
FROM 'informix'.sysindexes si, 'informix'.sysconstraints sc 
WHERE si.tabid = sc.tabid 
AND si.idxname = sc.idxname 
AND sc.constrid = ? -- primconstr from (1) 

(3)從(1)可以在tabid和rtabid(用於參考約束)現在可以用來獲取的表像的列:

SELECT colno, colname 
FROM 'informix'.syscolumns 
WHERE tabid = ? -- tabid(for referenced) or rtabid(for referencing) from (1) 
    AND colno = ? -- via parts from (1) and (2) 
ORDER BY colno 

(4)如果constrtype是「C」,然後得到這樣的檢查信息:

SELECT type, seqno, checktext 
FROM 'informix'.syschecks 
WHERE constrid = ? -- constrid from (1) 

相當毛毛確實

3

列在一個表中與他們的約束

SELECT 
    a.tabname, b.constrname, d.colname 
FROM 
    systables a, sysconstraints b, sysindexes c, syscolumns d 
WHERE 
    a.tabname = 'your_table_name_here' 
AND 
    b.tabid = a.tabid 
AND 
    c.idxname = b.idxname 
AND 
    d.tabid = a.tabid 
AND 
(
    d.colno = c.part1 or 
    d.colno = c.part2 or 
    d.colno = c.part3 or 
    d.colno = c.part4 or 
    d.colno = c.part5 or 
    d.colno = c.part6 or 
    d.colno = c.part7 or 
    d.colno = c.part8 or 
    d.colno = c.part9 or 
    d.colno = c.part10 or 
    d.colno = c.part11 or 
    d.colno = c.part12 or 
    d.colno = c.part13 or 
    d.colno = c.part14 or 
    d.colno = c.part15 or 
    d.colno = c.part16 
) 
ORDER BY 
    a.tabname, 
    b.constrname, 
    d.colname 
+0

太棒了!這完全爲我節省了一個小時的工作! – 2014-08-14 15:12:24

0

得到表受約束「r190_710」:

select TABNAME from SYSTABLES where TABID IN 
(select TABID from sysconstraints where CONSTRID IN 
(select CONSTRID from sysreferences where PTABID IN 
(select TABID from sysconstraints where CONSTRNAME= "r190_710") 
) 
); 
0

如果你的約束被命名爲constraint_c6,下面是如何轉儲它的定義(以及排序,你仍然需要連接行,因爲它們將被空格分隔):

OUTPUT TO '/tmp/constraint_c6.sql' WITHOUT HEADINGS 
SELECT ch.checktext 
FROM syschecks ch, sysconstraints co 
WHERE ch.constrid = co.constrid 
    AND ch.type = 'T' -- text lines only 
    AND co.constrname = 'constraint_c6' 
ORDER BY ch.seqno; 
0

我一直在使用以下查詢來獲取有關不同類型約束的更多信息。 它基於系統表中的一些洞察以及關於系統目錄的幾個解釋。

sysconstraints.constrtype表示約束的類型:

  • P =主鍵
  • U =唯一鍵/交替鍵
  • N =非空
  • C =檢查
  • R =參考/外鍵
select 
    tab.tabname, 
    constr.*, 
    chk.*, 
    c1.colname col1, 
    c2.colname col2, 
    c3.colname col3, 
    c4.colname col4, 
    c5.colname col5 
from sysconstraints constr 
    join systables tab on tab.tabid = constr.tabid 
    left outer join syschecks chk on chk.constrid = constr.constrid and chk.type = 'T' 
    left outer join sysindexes i on i.idxname = constr.idxname 
    left outer join syscolumns c1 on c1.tabid = tab.tabid and c1.colno = abs(i.part1) 
    left outer join syscolumns c2 on c2.tabid = tab.tabid and c2.colno = abs(i.part2) 
    left outer join syscolumns c3 on c3.tabid = tab.tabid and c3.colno = abs(i.part3) 
    left outer join syscolumns c4 on c4.tabid = tab.tabid and c4.colno = abs(i.part4) 
    left outer join syscolumns c5 on c5.tabid = tab.tabid and c5.colno = abs(i.part5) 
where constr.constrname = 'your constraint name' 
相關問題