INSERT [...] ON CONFLICT可用于外键违规吗?

pet*_*sey 9 sql postgresql upsert sql-insert postgresql-9.5

特定

=> select * from referenced;
 referenced_id | name  
---------------+-------
             1 | one
             2 | two
             3 | three
Run Code Online (Sandbox Code Playgroud)

=> select * from entries;
 entry_id | referenced_id |      name      
----------+---------------+------------------
        1 |             3 | references three
Run Code Online (Sandbox Code Playgroud)

在哪里referenced_identry_id是主键.

entries如果entry_id已经存在或引用的项不存在,我想要一个insert语句来跳过该插入.第一个很容易做到:

INSERT INTO entries
VALUES (1, 2, 'references two')
ON CONFLICT (entry_id) DO NOTHING;
Run Code Online (Sandbox Code Playgroud)

是否有可能在这里检查是否存在外键?

Erw*_*ter 9

是的,将输入行连接到引用的表,从而删除FK列上没有匹配的行:

INSERT INTO entries(entry_id, referenced_id, name)
SELECT val.entry_id, val.referenced_id, val.name
FROM  (
  VALUES (1, 2, 'references two')
         -- more?
  ) val (entry_id, referenced_id, name)
JOIN   referenced USING (referenced_id)  -- drop rows without matching FK
ON     CONFLICT (entry_id) DO NOTHING;   -- drop rows with duplicate id
Run Code Online (Sandbox Code Playgroud)

UPSERT本身(INSERT ... ON CONFLICT DO NOTHING)仅对唯一违规做出反应.手册:

ON CONFLICT可用于指定引发唯一约束或排除约束违规错误的备用操作.(参见下面的UN CONFLICT条款.)

  • @JuanCarlosOropeza:您可以以相同的方式加入同一个表,只需确保连接条件只能匹配***行.否则你必须使用不同的技术. (2认同)