PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Approccio consigliato per inserire molte righe con Castle ActiveRecord e ignorare eventuali duplicati

Puoi farlo con una singola istruzione 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)
   );

Il SELECT restituisce la riga solo se non esiste già, quindi verrà inserita solo in questo caso.

Soluzione per inserti sfusi

Se hai una lunga lista di ricette da inserire subito, potresti:

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;

Soluzione per inserirne una manciata alla volta

La tabella temporanea sarebbe esagerata solo per pochi record, come ha commentato 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;