1

對於一個文字遊戲,我想CHECK約束添加到VARCHAR陣列列:爲VARCHAR檢查約束[]和varchar [] []表中的

CREATE TABLE words_games (
     gid SERIAL PRIMARY KEY, 
     created timestamptz NOT NULL, 

     player1 integer REFERENCES words_users(uid) ON DELETE CASCADE NOT NULL, 
     player2 integer REFERENCES words_users(uid) ON DELETE CASCADE, 

     played1 timestamptz, 
     played2 timestamptz, 

     hand1 varchar[7] NOT NULL CHECK (ALL(hand1) ~ '^[*A-Z]$'), 
     hand2 varchar[7] NOT NULL CHECK (ALL(hand2) ~ '^[*A-Z]$'), 
     pile varchar[116] NOT NULL CHECK (ALL(pile) ~ '^[*A-Z]$'), 

     board varchar[15][15] NOT NULL CHECK (ALL(board) ~ '^[.A-Z]$'), 
     style integer NOT NULL CHECK (1 <= style AND style <= 4) 
); 

,但得到的語法錯誤:

ERROR: syntax error at or near "ALL" 
LINE 8:   hand1 varchar[7] NOT NULL CHECK (ALL(hand1) ~ '^[A-Z... 
               ^

可能是因爲ALL關鍵字應該在右側?

任何人都可以請推薦一種方法來實現檢查約束在這裏?

+1

這是一個[長期限制(http://www.postgresql.org/message-id/[email protected] .pgh.pa.us)。唯一的解決方法是爲'LIKE' /'〜'/ etc創建一個反函數。 (在你的情況下,它也需要是不可變的)。 – pozs

+0

或者,你可以[創建一個域類型](http://www.postgresql.org/docs/current/static/sql-createdomain.html)(它可以有自己的檢查約束)並使用該域的數組代替。 – pozs

+2

@pozs不幸的是,[域的數組尚未支持](http://www.postgresql.org/docs/current/static/arrays.html)。 – Abelisto

回答

2

是的,不可能使用all()any()作爲左對比參數。創建函數:

create or replace function check_array_regexp_all(text[], text) returns boolean as $$ 
    select bool_and(x) from (select unnest($1) ~ $2 as x) t; 
$$ language sql immutable; 

,並用它來約束:

... 
hand1 varchar[7] NOT NULL CHECK (check_array_regexp_all(hand1, '^[*A-Z]$')), 
...