Postgresql
如何在同一個表的列之間定義一對多約束?
我正在 PostgreSQL 中創建一個 IDs 表來表示多個外部 ID 之間的關係 - 稱它們為
a
,b
和c
.我碰巧知道外國ID之間有一對多的關係:
a 1..* b
b 1..* c
a
我想將它們表示為一個表(見下文),但在&b
、 & 和 之間b
強制執行一對多不變數c
。那可能嗎?
範例:以下插入是非法的:
給定以下合法表格:
這必須由 完成,因為它對於約束
TRIGGER
來說太複雜了CHEKC
對於更新,您需要類似的觸發器/功能
CREATE TABLE tabl1 ("pk" varchar(5), "a" varchar(6), "b" varchar(6), "c" varchar(6)) ; INSERT INTO tabl1 ("pk", "a", "b", "c") VALUES ('p1', 'a1', 'b11', 'c111'), ('p2', 'a1', 'b11', 'c112'), ('p3', 'a1', 'b12', 'c121'), ('p4', 'a1', 'b12', 'c122'), ('p5', 'a2', 'b21', 'c211'), ('p6', 'a2', 'b21', 'c212'), ('p7', 'a2', 'b22', 'c221'), ('p8', 'a2', 'b22', 'c222'), ('p9', NULL, 'b31', 'c311'), ('p10', 'a3', NULL, 'c312'), ('p11', 'a3', 'b31', NULL), ('p12', NULL, NULL, 'c314'), ('p13', NULL, 'b31', NULL), ('p14', 'a3', NULL, NULL) ;
CREATE OR REPLACE FUNCTION check_insert() RETURNS TRIGGER AS $$ BEGIN IF EXISTS(SELECT 1 FROM tabl1 WHERE "c" = NEW."c" AND "b" = NEW."b" ) then raise EXCEPTION 'The column % already with %',NEW."c",NEW."b"; ELSIF EXISTS(SELECT 1 FROM tabl1 WHERE "a" <> NEW."a" AND "b" = NEW."b" ) then raise EXCEPTION 'The column % already has already a column',NEW."b"; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql;
CREATE TRIGGER trigger_name BEFORE INSERT ON tabl1 FOR EACH ROW EXECUTE PROCEDURE check_insert();
INSERT INTO tabl1 ("pk", "a", "b", "c") VALUES ('p15', 'a1', 'b11', 'c111')
錯誤:列 c111 已包含 b11
上下文: PL/pgSQL 函式 check_insert() 第 4 行,位於 RAISE
INSERT INTO tabl1 ("pk", "a", "b", "c") VALUES ('p16' , 'a1' , 'b21' , 'c213' )
錯誤:b21 列已經有一個列
上下文: PL/pgSQL 函式 check_insert() 第 6 行,位於 RAISE
INSERT INTO tabl1 ("pk", "a", "b", "c") VALUES ('p17', 'a2', 'b11' ,'c214')
錯誤:b11 列已經有一個列
上下文: PL/pgSQL 函式 check_insert() 第 6 行,位於 RAISE
SELECT * FROM tabl1
PK | 一個 | 乙 | C :-- | :--- | :--- | :--- p1 | a1 | b11 | c111 p2 | a1 | b11 | c112 p3 | a1 | b12 | c121 p4 | a1 | b12 | c122 p5 | a2 | b21 | c211 p6 | a2 | b21 | c212 p7 | a2 | b22 | c221 p8 | a2 | b22 | c222 p9 | *空*| b31 | c311 p10 | a3 | *空*| c312 p11 | a3 | b31 | *空* p12 | *空*| *空*| c314 第 13 頁 | *空*| b31 | *空* p14 | a3 | *空*| *空值*
db<>在這裡擺弄