2016-04-22 40 views
12

poprawna składnia upsert z postgresql 9.5, poniżej zapytania pokazuje błąd column reference "gallery_id" is ambiguous, dlaczego?Jak poprawnie wstawić w postgres 9.5

var dbQuery = `INSERT INTO category_gallery (
    category_id, gallery_id, create_date, create_by_user_id 
) VALUES ($1, $2, $3, $4) 
    ON CONFLICT (category_id) 
    DO UPDATE SET 
    category_id = $1, 
    last_modified_date = $3, 
    last_modified_by_user_id = $4 
    WHERE gallery_id = $2`; 

Próbowałem zmiany WHERE gallery_id = $2; do WHERE category_gallery.gallery_id = $2; następnie pokazuje błąd there is no unique or exclusion constraint matching the ON CONFLICT specification, ale Nie chcę ustawić gallery_id lub category_id jako unikalny becuase Chcę że obie kolumny są takie same wtedy zrobić aktualizację ....

Jak poprawnie wstawić w PostgreSQL 9.5?

jeśli ON CONFLICT potrzebujesz unikalnej kolumny, czy powinienem użyć innej metody, jak?



Chcę pewny wielokrotne kolumny zarówno konflikt następnie należy aktualizować, co jest poprawne wykorzystanie

var dbQuery = `INSERT INTO category_gallery (
    category_id, gallery_id, create_date, create_by_user_id 
) VALUES ($1, $2, $3, $4) 
    ON CONFLICT (category_id, gallery_id) 
    DO UPDATE SET 
    category_id = $1, 
    last_modified_date = $3, 
    last_modified_by_user_id = $4 
    WHERE gallery_id = $2`; 


var dbQuery = `INSERT INTO category_gallery (
    category_id, gallery_id, create_date, create_by_user_id 
) VALUES ($1, $2, $3, $4) 
    ON CONFLICT (category_id AND gallery_id) 
    DO UPDATE SET 
    category_id = $1, 
    last_modified_date = $3, 
    last_modified_by_user_id = $4 
    WHERE gallery_id = $2`; 

stół (category_id nie gallery_id niepowtarzalną kolumnę)

category_id | gallery_id | create_date | create_by_user_id | last_modified_date | last_modified_by_user_id 
1 | 1 | ... 
1 | 2 | ... 
2 | 2 | ... 
1 | 3 | ... 

Odpowiedz

28

Konstrukcja ON CONFLICT wymaga ograniczenia UNIQUE do działania. Z dokumentacji na INSERT .. ON CONFLICT clause:

Opcjonalny ON CONFLICT klauzula określa alternatywny działania do wychowywania niepowtarzalny naruszenie lub wykluczenie wiązania błąd naruszenie. Dla każdego pojedynczego wiersza proponowanego do wstawienia albo wstawianie przebiega, albo, jeśli ograniczenie lub indeks arbitra określone przez conflict_target jest naruszone, podejmowane jest alternatywne działanie konfliktu. ON CONFLICT DO NOTHING po prostu unika wstawiania wiersza jako alternatywnego działania. ON CONFLICT DO UPDATE aktualizuje istniejący wiersz, który koliduje z wierszem proponowanym do wstawienia jako jego alternatywną akcją.

Teraz pytanie nie jest bardzo jasne, ale prawdopodobnie trzeba się UNIQUE presję na 2 kolumnach połączonych: (category_id, gallery_id).

ALTER TABLE category_gallery 
    ADD CONSTRAINT category_gallery_uq 
    UNIQUE (category_id, gallery_id) ; 

Jeżeli rząd do wprowadzenia mecze zarówno wartości z rzędu już na stole, a następnie zamiast INSERT, zrobić UPDATE:

INSERT INTO category_gallery (
    category_id, gallery_id, create_date, create_by_user_id 
) VALUES ($1, $2, $3, $4) 
    ON CONFLICT (category_id, gallery_id) 
    DO UPDATE SET 
    last_modified_date = EXCLUDED.create_date, 
    last_modified_by_user_id = EXCLUDED.create_by_user_id ; 

Można użyć kolumnach UNIQUE:

ON CONFLICT (category_id, gallery_id) 

lub nazwą ograniczenia:

ON CONFLICT ON CONSTRAINT category_gallery_uq 
+0

dzięki za odpowiedź, ale nie chcę, aby id_categorii lub gallery_id była unikalną kolumną, o której mowa. Chcę się upewnić, że category_id i gallery_id są takie same, a następnie utworzyć nowy wiersz, proszę zobaczyć mój przykład daty aktualizacji w pytaniu – user1575921

+0

wow, dzięki! Nie rozumiem, spróbuj teraz teraz – user1575921

+0

tak, jeśli już istnieje "id_kolumny = 1 i id_ galerii = 3", a następnie aktualizuj, nie wstawiaj. Używam twojego skryptu, jeśli chcę zaktualizować 'category_id = 2 gdzie gallery_id = 3' nie działa. czy powinienem dodać kolejny skrypt aktualizacji? – user1575921

1

jak uproszczoną alternatywę dla the currently accepted answer The UNIQUE Ograniczenie może być anonimowo dodany po utworzeniu tabeli:

CREATE TABLE table_name (
    id TEXT PRIMARY KEY, 
    col TEXT, 
    UNIQUE (id, col) 
); 

Następnie, zapytanie upsert staje (podobny do tego, co zostało już odpowiedział):

INSERT INTO table_name (id, col) VALUES ($1, $2) 
ON CONFLICT (id, col) 
    DO UPDATE SET col = $2;