PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Empfohlener Ansatz, um viele Zeilen mit Castle ActiveRecord einzufügen und alle Duplikate zu ignorieren

Sie können dies mit einer einzigen SQL-Anweisung tun:

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)
   );

Die SELECT gibt die Zeile nur zurück, wenn sie noch nicht existiert, also wird sie nur in diesem Fall eingefügt.

Lösung für Massenbeilagen

Wenn Sie eine lange Liste von Rezepten haben, die Sie auf einmal einfügen möchten, können Sie:

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;

Lösung zum gleichzeitigen Einlegen einer Handvoll

Temporäre Tabelle wäre ein Overkill für nur ein paar Datensätze, wie Mike kommentierte.

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;