2009-02-23 13 views
5

Chciałbym rozwiązanie wymusić ograniczenie tylko wtedy, gdy kolumna nie jest pusta. Nie mogę znaleźć sposobu, aby to zrobić w dokumentacji.Jak wymusić ograniczenie tylko wtedy, gdy kolumna nie jest pusta w Postgresql?

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

Do charakteru danych, będę mieć identyfikator b i wartość, gdy tabela zostanie utworzona. Po otrzymaniu dodatkowych danych będę mógł wypełnić identyfikator a. W tym momencie chciałbym zapewnić unique key of (identifier_a, value1), ale tylko jeśli istnieje identyfikator_a.

Mam nadzieję, że ma to sens, Czy ktoś ma jakieś pomysły?

Odpowiedz

6

Ummm. Unikalne ograniczenia nie zapobiegają wielu wartościom 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) 
); 

pamiętać, że możemy wstawić muliple null do niego, nawet gdy identifier_b mecze:

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) 

Ale nie możemy utworzyć duplikat (a, b) pary:

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

Oczywiście, masz problem: Twoja tabela nie ma klucza głównego. You prawdopodobnie masz problem z modelem danych. Ale nie podałeś wystarczająco szczegółowych informacji, aby to naprawić.

+0

Problem z modelem danych nie jest mój, to klienci :)! Dzięki. –

0

Można sobie z tym poradzić za pomocą wyzwalacza zamiast ograniczenia.

0

Gdybym był tobą, podzieliłbym stolik na dwie tabele i ewentualnie stworzyłem widok, który łączy je w razie potrzeby.

1

Jeśli jest to możliwe, aby zakończyć całą operację w ciągu jednej transakcji, możliwe jest, aby zmienić czas, który Postgres ocenia ograniczenia, tj .:

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

W tym przypadku, ograniczenie jest oceniany na popełnić. Zobacz: Postgres 7.4 Doc - Set constraints lub Postgres 8.3 Doc

1

Właściwie prawdopodobnie podzielę to na dwie tabele. Modelujesz dwa różne rodzaje rzeczy. Pierwsza to wersja początkowa, która jest tylko częściowa, a druga to całość. Gdy informacje potrzebne do wniesienia pierwszego rodzaju rzeczy do drugiego, przenieś wiersz z jednego stołu do drugiego.

Powiązane problemy