簡體   English   中英

如何查找給定列是否存在唯一鍵約束

[英]How to find whether unique key constraint exists for given columns

我正在使用perl腳本,我需要運行更新查詢。 但我需要檢查更新sql命令是否違反唯一鍵約束。 所以,如果我有一個表tb(C1,C2,C3) ,我的更新查詢如下:

update tb set C1='b1' where C2='a1' ;

有沒有辦法嘗試更新之前查找列C1,C2是否存在唯一鍵約束? 即: UNIQUE(C1,C2)

您可以在系統目錄中查詢唯一約束 ,尤其是pg_constraintpg_attribute

SELECT c.conname, pg_get_constraintdef(c.oid)
FROM   pg_constraint c
JOIN  (
   SELECT array_agg(attnum::int) AS attkey
   FROM   pg_attribute
   WHERE  attrelid = 'tb'::regclass  -- table name optionally schema-qualified
   AND    attname  = ANY('{c1,c2}') 
   ) a ON c.conkey::int[] <@ a.attkey AND c.conkey::int[] @> a.attkey
WHERE  c.contype  = 'u'
AND    c.conrelid = 'tb'::regclass;
  • 對象標識符類型 regclass有助於明確標識您的表。

  • 系統目錄信息函數pg_get_constraintdef()為您提供格式良好的信息,這對您的請求並不是絕對必要的。

  • 還使用數組運算符 <@@>來確保數組完全匹配。 (列的順序未知。)系統列分別為smallintsmallint[] 轉換為integer以使其與這些運算符一起使用。

  • 直接在系統目錄中查找列名稱時區分大小寫。 如果在創建時沒有雙引號C1C2 ,則必須在此上下文中使用c1c2

  • 還可能存在強制唯一性的多列主鍵約束 要在查詢中使用,請改為使用:

     WHERE c.contype IN ('u', 'p') 

在@ Roman的小提琴的基礎上,這個也展示了pk案例:

- > SQLfiddle

獨特的指數

以上兩者(唯一和pk約束)都是通過唯一索引實現的。 此外,還可以存在與正式聲明的唯一約束有效相同的唯一索引 要捕獲所有這些 ,請以類似的方式查詢系統目錄pg_index

SELECT c.relname AS idx_name
FROM  (
   SELECT indexrelid, string_to_array(indkey::text, ' ')::int[] AS indkey
   FROM   pg_index
   WHERE  indrelid = 'tb'::regclass
   AND    indisunique                    -- contains "indisprimary"
   ) i
JOIN  (
   SELECT array_agg(attnum::int) AS attkey
   FROM   pg_attribute
   WHERE  attrelid = 'tb'::regclass
   AND    attname  = ANY('{c1,c2}')
   ) a ON i.indkey <@ a.attkey AND i.indkey @> a.attkey
JOIN   pg_class c ON c.oid = i.indexrelid;

這里的特殊困難是內部類型int2vector 我通過轉換文本並轉換為int[]來處理它。

請注意,目錄表的實現可能會在主要內容中發生變化。 不太可能這些查詢中斷,但可能。

您可以通過檢查pg_catalog.pg_constraint表來查明是否存在約束(不可移植),但這不會告訴您插入是否會違反約束,即使可能也會出現競爭。

正確的做法是嘗試插入並適當地處理故障。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM