2009-02-23 19 views
5

Tôi muốn một giải pháp để thực thi một ràng buộc chỉ khi một cột không phải là null. Tôi không thể tìm cách để làm điều này trong tài liệu.Làm thế nào tôi có thể thực thi một ràng buộc chỉ khi một cột không phải là null trong Postgresql?

create table mytable(
    table_identifier_a INTEGER, 
    table_identifier_b INTEGER, 
    table_value1,...) 

Làm theo bản chất của dữ liệu, tôi sẽ có số nhận dạng b và giá trị khi tạo bảng. Sau khi chúng tôi nhận được dữ liệu bổ sung, tôi sẽ có thể điền mã định danh a. Tại thời điểm này tôi muốn đảm bảo một unique key of (identifier_a, value1) nhưng chỉ khi identifier_a tồn tại.

Hy vọng điều đó có ý nghĩa, Bất kỳ ai có ý tưởng nào?

Trả lời

6

Ummm. Ràng buộc duy nhất không ngăn cản nhiều giá trị NULL.

CREATE TABLE mytable (
    table_identifier_a INTEGER NULL, 
    table_identifier_b INTEGER NOT NULL, 
    table_value1   INTEGER NOT NULL, 

    UNIQUE(table_identifier_a, table_identifier_b) 
); 

Lưu ý rằng chúng ta có thể chèn NULLs muliple vào nó, ngay cả khi identifier_b trận đấu:

test=# INSERT INTO mytable values(NULL, 1, 2); 
INSERT 0 1 
test=# INSERT INTO mytable values(NULL, 1, 2); 
INSERT 0 1 
test=# select * from mytable; 
table_identifier_a | table_identifier_b | table_value1 
--------------------+--------------------+-------------- 
        |     1 |   2 
        |     1 |   2 
(2 rows) 

Nhưng chúng ta không thể tạo ra trùng lặp (a, b) cặp:

test=# update mytable set table_identifier_a = 3; 
ERROR: duplicate key value violates unique constraint "mytable_table_identifier_a_key" 

Tất nhiên, bạn có vấn đề: Bảng của bạn không có khóa chính. Bạn có thể có vấn đề về mô hình dữ liệu. Nhưng bạn không cung cấp đủ chi tiết để khắc phục điều đó.

+0

Vấn đề mô hình dữ liệu không phải của tôi, khách hàng của nó :)! Cảm ơn. –

0

Bạn có thể xử lý việc này bằng trình kích hoạt thay vì ràng buộc.

0

Nếu tôi là bạn, tôi sẽ chia bảng thành hai bảng và có thể tạo chế độ xem kết hợp chúng khi cần.

1

Nếu nó là khả thi để hoàn thành toàn bộ hoạt động trong vòng một giao dịch, nó có thể thay đổi thời gian mà Postgres đánh giá hạn chế, tức là .:

START; 
SET CONSTRAINTS <...> DEFERRED; 
<SOME INSERT/UPDATE/DELETE> 
COMMIT; 

Trong trường hợp này, các hạn chế được đánh giá ở cam kết. Xem: Postgres 7.4 Doc - Set constraints hoặc Postgres 8.3 Doc

1

Thực ra, tôi có thể chia nhỏ thành hai bảng. Bạn đang lập mô hình hai loại khác nhau của sự vật. Đầu tiên là phiên bản đầu tiên, chỉ là một phần, và phiên bản thứ hai là toàn bộ. Khi thông tin cần thiết để đưa loại thứ nhất đến thứ hai, hãy di chuyển hàng từ bảng này sang bảng khác.

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