2016-06-22 7 views
0

2つのオプションの列を持つ表があります。 行がテーブルに挿入されると、2つの列のうちの1つがNULLになりません。PostgreSQLのトリガーを使用した非null制約

私は、MySQLのため、この解決策を見つけた:

CREATE TABLE foo (
    FieldA INT, 
    FieldB INT 
); 

DELIMITER // 
CREATE TRIGGER InsertFieldABNotNull BEFORE INSERT ON foo 
FOR EACH ROW BEGIN 
    IF (NEW.FieldA IS NULL AND NEW.FieldB IS NULL) THEN 
    SIGNAL SQLSTATE '45000' 
    SET MESSAGE_TEXT = '\'FieldA\' and \'FieldB\' cannot both be null'; 
    END IF; 
END// 
CREATE TRIGGER UpdateFieldABNotNull BEFORE UPDATE ON foo 
FOR EACH ROW BEGIN 
    IF (NEW.FieldA IS NULL AND NEW.FieldB IS NULL) THEN 
    SIGNAL SQLSTATE '45000' 
    SET MESSAGE_TEXT = '\'FieldA\' and \'FieldB\' cannot both be null'; 
    END IF; 
END// 
DELIMITER ; 

INSERT INTO foo (FieldA, FieldB) VALUES (NULL, 10); -- OK 
INSERT INTO foo (FieldA, FieldB) VALUES (10, NULL); -- OK 
INSERT INTO foo (FieldA, FieldB) VALUES (NULL, NULL); -- gives error 
UPDATE foo SET FieldA = NULL; -- gives error 

どのように私は、PostgreSQLのためにそれを翻訳することができますか?あなたが挿入またはNULL両方の値を持つタプルを変更することはできません。このように

CREATE TABLE foo (
    FieldA INT, 
    FieldB INT, 
    CHECK (NOT (FieldA IS NULL AND FieldB IS NULL))); 

+0

チェック制約をサポートしていないため、この醜い回避策が必要なのはMySQLだけです。 Postgresではこれが簡単です。 –

答えて

1

は、あなたは、単にテーブル制約を使用することができます。

teststar=# INSERT INTO foo (FieldA, FieldB) VALUES (NULL, 10); 
INSERT 0 1 
teststar=# INSERT INTO foo (FieldA, FieldB) VALUES (10, NULL); 
INSERT 0 1 
teststar=# INSERT INTO foo (FieldA, FieldB) VALUES (NULL, NULL); 
ERROR: new row for relation "foo" violates check constraint "foo_check" 
DETAIL: Failing row contains (null, null). 
teststar=# UPDATE foo SET FieldA = NULL; 
ERROR: new row for relation "foo" violates check constraint "foo_check" 
DETAIL: Failing row contains (null, null). 
teststar=# 
+0

非常に分かりやすく使いやすい!ありがとうございました! – Fabio

関連する問題