PostgreSQL - UPDATE失败时返回行内容

时间:2018-04-03 16:05:35

标签: postgresql

使用PostgreSQL更新行时(通过UPDATE语句),可以使用RETURNING *获取修改后的行内容。

我想知道在更新由于约束而失败时是否有任何方法可以获取未修改的行。例如,执行以下命令(使用RETURNING *)不会返回当前行值:

UPDATE sentence
SET content = 'This is a sentence', language_id=834
WHERE id = '0538f24a-2046-4da6-933d-409aa7b7c597'
RETURNING *;

它给出错误

ERROR:  duplicate key value violates unique constraint "sentence_language_id_content_key"
DETAIL:  Key (language_id, content)=(834, This is a sentence) already exists.

有没有办法返回未修改的行内容,或RETURNING *仅在数据修改实际发生时没有任何约束错误时才起作用?

1 个答案:

答案 0 :(得分:2)

继续使用更新并仍然返回冲突行的一个选项是创建一个在执行更新之前执行此检查的函数。如果主键已存在,则返回冲突行,如果不存在,则更新行。这种功能的一个例子可能是:

CREATE OR REPLACE FUNCTION my_func(cont TEXT, lang INT, idp TEXT) 
RETURNS SETOF sentence AS $$
DECLARE j RECORD;
BEGIN
  SELECT * FROM sentence WHERE content = cont AND 
                               language_id = lang INTO j;
  IF j IS NOT NULL THEN 
    RETURN NEXT j;
  ELSE
    RETURN QUERY UPDATE sentence SET content = cont, language_id= lang 
                 WHERE id = idp RETURNING *;
  END IF;
  EXCEPTION WHEN SQLSTATE '23505' THEN 
  RETURN QUERY SELECT * FROM sentence WHERE content = cont AND
                                            language_id= lang;
END$$ LANGUAGE plpgsql;

SELECT my_func('This is a sentence',834,'0538f24a-2046-4da6-933d-409aa7b7c597');

编辑:如果没有冲突且您仍然需要RETURNING *,只需在RETURN QUERY声明中添加UPDATE

...    
RETURN QUERY 
UPDATE sentence SET content = cont, language_id= lang WHERE id = idp 
RETURNING *;
...