Postgresql
檢索特定於列的檢查約束的名稱
PostgreSQL 12
當我重命名表中的列時,我也想動態重命名匹配的檢查約束。
我有一個假設的表格:
CREATE TABLE hypothetical_table ( id SERIAL PRIMARY KEY, some_col text, some_col_also text );
有以下限制:
ALTER TABLE hypothetical_table ADD CONSTRAINT some_col_length_>_5 CHECK(char_length(some_col) > 5); ALTER TABLE hypothetical_table ADD CONSTRAINT some_col_also_length_>_5 CHECK(char_length(some_col_also) > 5);
我不知道列可能有什麼限制。我知道它們以列名為前綴。但是,就像
some_col
上面的約束一樣,該前綴可能與另一列的 (some_col_also
) 匹配。當我重命名此表中的列時,我也想重命名約束,以匹配新的列名。
那麼,如果我要重命名
some_col
,如何選擇與該列關聯的所有檢查約束?我嘗試
pg_catalog.pg_constraint
使用pg_catalog.pg_attribute
ONcon.conkey = pga.attnum
(conkey
未嵌套)加入,但這會返回許多與該列無關的約束。
如何選擇與該列關聯的所有檢查約束?
pg_constraint.conkey
是一個數組列,所以我們另外加入a.attnum = ANY(c.conkey)
關係的oid。像:SELECT conname -- pg_get_constraintdef(oid), * FROM pg_constraint c JOIN pg_attribute a ON a.attrelid = c.conrelid -- ! AND a.attnum = ANY(c.conkey) -- ! WHERE c.conrelid = 'hypothetical_table'::regclass AND c.contype = 'c' -- c = check constraint AND a.attname = 'some_col';
但我懷疑你的總體目標:
當我重命名表中的列時,我也想動態重命名匹配的檢查約束。
CHECK
在 Postgres 中,約束總是表約束,並且可以引用任意數量的表列。即使公式化為列約束!手冊:列檢查約束
SQL 標準規定
CHECK
列約束只能引用它們適用的列;只有CHECK
表約束可以引用多個列。PostgreSQL 不強制執行此限制;它對待列和表檢查約束是一樣的。所以
some_col
andsome_col_also
可以同時引用(多次)。兩者都可以在約束名稱中。除非您可以依賴嚴格的命名約定,否則我看不出一個完全動態的解決方案如何是防彈的。(你真的可以嗎?)。以下是對some_col
or的引用some_col_also
嗎?some_col_also_is_a_fruit -- oh, wait!
重寫約束表達式本身也需要注意。