PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Abordagem recomendada para inserir muitas linhas com Castle ActiveRecord e ignorar quaisquer dupes


Você pode fazer isso com uma única instrução 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)
   );

O SELECT só retorna a linha se ela ainda não existir, então ela só será inserida neste caso.

Solução para inserções em massa


Se você tiver uma longa lista de receitas para inserir de uma só vez, poderá:
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;

Solução para inserir um punhado de cada vez


Tabela temporária seria um exagero para apenas alguns registros, como Mike comentou.
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;