我目前正在使用正则表达式来转换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
答案 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
。