我想UPDATE记录是否存在,否则在我的Java项目的一个查询中将值INSERT到表中。
DO
$do$
BEGIN
IF EXISTS
(SELECT 1 NOTES WHERE USER_ID = '2' AND EVENT_ID ='4') THEN
UPDATE NOTES SET NOTES='MY notes' WHERE USER_ID = '2' AND EVENT_ID ='4'
ELSE
INSERT INTO NOTES VALUES
((SELECT max(NOTES_ID)+1 FROM NOTES), '4, 2','1',''); END IF; END
$do$
这是我迄今为止所拥有的,但是自从Postgres 9.5以来,必须有一些变化,我得到了:
ERROR: syntax error at or near "ELSE"
LINE 7: ELSE
答案 0 :(得分:0)
有很多方法可以实现这一目标。您可以使用新的UPSERT语法EXISTS
(只修复Clodoaldo提到的分号)或使用FOUND
变量:
DO $do$
BEGIN
UPDATE NOTES SET NOTES='MY notes' WHERE USER_ID = '2' AND EVENT_ID ='4';
IF NOT FOUND THEN
INSERT INTO NOTES VALUES ((SELECT max(NOTES_ID)+1 FROM NOTES), '4, 2','1','');
END IF;
END $do$;
但要注意racing conditions。
答案 1 :(得分:0)
不需要PL / pgSQL块。
这可以使用可写CTE的单个SQL语句来完成:
with updated as (
UPDATE NOTES
SET NOTES='MY notes'
WHERE USER_ID = 2
AND EVENT_ID = 4
returning *
)
INSERT INTO NOTES (notes_id, event_id, user_id, notes)
select (SELECT max(NOTES_ID)+1 FROM NOTES), --<< Do NOT do this!!
4,
2,
'My notes'
where not exists (select * from updated);
请注意,使用max(notes_id) + 1
生成“唯一”ID对于并发使用并不安全,如果表大小增加,则无法很好地扩展。
另外:你应该使用数字文字来表示数字,而不是字符串。 2
是一个数字'2'
是一个字符串。
如果您在(user_id, event_id)
上有一个唯一索引(您应该了解问题的性质),您还可以使用Postgres 9.5中引入的insert on conflict
INSERT INTO NOTES (notes_id, event_id, user_id, notes)
VALUES (
(SELECT max(NOTES_ID)+1 FROM NOTES), --<< Do NOT do this!
4, 2, 'My notes')
ON CONFLICT (user_id, event_id)
DO UPDATE set notes = excluded.notes;
警告:
如果您想以可靠,并发安全且可扩展的方式生成唯一ID,拥有来使用序列。 NOT 使用反模式max() + 1