将INSERT IGNORE转换为Postgres INSERT

时间:2016-10-05 13:59:35

标签: sql regex postgresql

我目前正在使用正则表达式来转换Postgres语法上的sql语法。我正在使用geany来替换文本。现在,我尝试改变的语法就是这个:

INSERT IGNORE INTO item_question_ (question_fk_,item_fk_) VALUES(1002,162);

进入:

INSERT INTO item_question_ (question_fk_,item_fk_) VALUES (1002,151) 
WHERE NOT EXISTS 
(SELECT 1 FROM item_questionnaire_ WHERE question_fk_=1002 AND item_fk_ = 151)

我很亲密,但绝对不是。我有这个正则表达式:

(INSERT IGNORE INTO (.*)_ (.*) VALUES(.*);) //Find information
INSERT INTO \2_ \3 VALUES \4 WHERE NOT EXISTS (SELECT 1 FROM \2_ WHERE )// Transform information

事实是我错过了最重要的部分:WHERE条款。

如何获取值question_fk_,item_fk_1002,151来构建where子句?

附加说明:Postgres版本低于9.5。我无法使用ON CONFLICT IGNORE

4 个答案:

答案 0 :(得分:2)

PostgreSQL 9.5+:用ON CONFLICT IGNORE替换原始查询中的IGNORE,这是PostgreSQL语法,如果任何约束失败,则忽略更新。

答案 1 :(得分:1)

正如其他人所提到的,只需使用Postgres 9.5+中的ON CONFLICT IGNORE即可。但是,既然你说DB版本小于9.5,那么这就是你完成这项任务的正则表达式解决方案:

INSERT IGNORE INTO (.*) \((.*),(.*)\) VALUES \((.*),(.*)\); // capture

INSERT INTO \1 (\2, \3) VALUES (\4, \5) WHERE NOT EXISTS (SELECT 1 FROM \1 WHERE \2 = \4 AND \3 = \5) // replace

但请记住,此正则表达式仅适用于插入2个项目。

答案 2 :(得分:0)

在查询末尾添加ON CONFLICT DO NOTHING

答案 3 :(得分:-1)

使用子查询:

INSERT INTO item_question_ (question_fk_, item_fk_) 
    SELECT q, i
    FROM (SELECT 1002 as q, 151 as i) t
    WHERE NOT EXISTS (SELECT 1
                      FROM item_questionnaire_ iq
                      WHERE iq.question_fk_= t.q AND iq.item_fk_ = t.i
                     );

这也允许您只输入一次值。

注意:我注意到被引用的表是不同的。我认为这是故意的,但我期待这个问题是一个唯一的约束违规。

另请注意,自Postgres 9.5以来,更好的方法是使用ON CONFLICT IGNORE,但您的问题主要是关于使用NOT EXISTS