Vous pouvez le faire avec une seule instruction 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)
);
Le SELECT
ne renvoie la ligne que si elle n'existe pas déjà, elle ne sera donc insérée que dans ce cas.
Solution pour les insertions en vrac
Si vous avez une longue liste de recettes à insérer en une fois, vous pouvez :
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;
Solution pour insérer une poignée à la fois
Une table temporaire serait exagérée pour quelques enregistrements seulement, comme l'a commenté 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;