Trả lời

22

Đây là không thể với một giá trị đơn giản DEFAULT, như the manual clearly states:

Giá trị là bất kỳ biểu hiện biến miễn phí (subqueries và tham khảo chéo với các cột khác trong bảng hiện tại không được phép).

Bạn có thể sử dụng một trigger thay vì:

CREATE OR REPLACE FUNCTION trg_foo_b_default() 
    RETURNS trigger AS 
$func$ 
BEGIN 

-- For just a few constant options, CASE does the job: 
NEW.b := 
    CASE NEW.a 
    WHEN 'peter' THEN 'doctor' 
    WHEN 'weirdo' THEN 'shrink' 
    WHEN 'django' THEN 'undertaker' 
    ELSE NULL 
    END; 

/* -- For more, or dynamic options, you could use a lookup table: 
SELECT INTO NEW.b t.b 
FROM def_tbl t 
WHERE t.a = NEW.a; 
*/ 

RETURN NEW; 

END 
$func$ LANGUAGE plpgsql; 

CREATE TRIGGER b_default 
BEFORE INSERT ON foo 
FOR EACH ROW 
WHEN (NEW.b IS NULL AND NEW.a IS NOT NULL) 
EXECUTE PROCEDURE trg_foo_b_default(); 

Để làm điều này hiệu quả hơn tôi sử dụng một điều khoản WHEN (có sẵn từ Postgres 9.0) với định nghĩa kích hoạt. Bằng cách này, chức năng kích hoạt chỉ được thực thi, khi nó thực sự hữu ích. Tôi giả sử ở đây, chúng tôi có thể cho phép b IS NULL trượt nếu a IS NULL.

Hoạt động tương tự, nhưng khác nhau tinh tế thời trang từ giá trị DEFAULT.
Với giá trị mặc định, bạn có thể chèn rõ ràng NULL để ghi đè giá trị mặc định. Điều đó là không thể ở đây, NULL trong b được thay thế bằng giá trị bắt nguồn từ a.

+0

Cảm ơn câu trả lời được xây dựng và súc tích – mosid

Các vấn đề liên quan