Możesz to zrobić za pomocą pojedynczej instrukcji SQL:
INSERT INTO user_recipe
SELECT new_UserId, new_RecipeId
FROM user_recipe
WHERE NOT EXISTS (
SELECT *
FROM user_recipe
WHERE (UserId, RecipeId) = (new_UserId, new_RecipeId)
);
SELECT
zwraca tylko wiersz, jeśli jeszcze nie istnieje, więc zostanie wstawiony tylko w tym przypadku.
Rozwiązanie dla wstawek zbiorczych
Jeśli masz długą listę przepisów do wstawienia na raz, możesz:
CREATE TEMP TABLE i(userId int, recipeid int) ON COMMIT DROP;
INSERT INTO i VALUES
(1,2), (2,4), (2,4), (2,7), (2,43), (23,113), (223,133);
INSERT INTO user_recipe
SELECT DISTINCT i.* -- remove dupes from the insert candidates themselves
FROM i
LEFT JOIN user_recipe u USING (userid, recipeid)
WHERE u.userid IS NULL;
Rozwiązanie do wstawiania garści na raz
Stół tymczasowy byłby przesadą dla zaledwie kilku rekordów, jak skomentował Mike.
INSERT INTO user_recipe
SELECT i.*
FROM (
SELECT DISTINCT * -- only if you need to remove possible dupes
FROM (
VALUES (1::int, 2::int)
,(2, 3)
,(2, 4)
,(2, 4) -- dupe will be removed
,(2, 43)
,(23, 113)
,(223, 133)
) i(userid, recipeid)
) i
LEFT JOIN user_recipe u USING (userid, recipeid)
WHERE u.userid IS NULL;