如果条目已存在于具有UNIQUE约束的表中,则INSERT或返回行

时间:2010-08-04 17:02:32

标签: postgresql insert unique

问候,

我在postgreSQL 8.4服务器上有这个表:

CREATE TABLE tags (
 tagid        bigserial                 PRIMARY KEY,
 name         text                      NOT NULL,
 value        text                      NOT NULL,
 UNIQUE(name,value)
);

正常的INSERT行为是在新值破坏唯一性约束时抛出错误。我更喜欢它不抛出错误并返回新的tagid,如果然后插入成功,或返回匹配唯一性约束的现有条目的tagid。

我使用此功能执行此操作:

CREATE OR REPLACE FUNCTION insert_tags(my_name text, my_value text)
RETURNS bigint AS $$
DECLARE
 retval bigint;
BEGIN
 SELECT tagid INTO retval FROM tags WHERE name = my_name AND value = my_value;
 IF FOUND THEN 
  RETURN retval; 
 END IF;
 INSERT INTO tags (name, value) VALUES (my_name, my_value) RETURNING tagid INTO retval;
 RETURN retval;
END;
$$ LANGUAGE plpgsql;

在最坏的情况下,在插入之前完成两次表查找。有没有更好的方法,可能在一次查找?

1 个答案:

答案 0 :(得分:3)

只需插入并执行一些异常处理:

CREATE OR REPLACE FUNCTION insert_tags(my_name text, my_value text)
RETURNS bigint AS $$
DECLARE
 retval bigint;
BEGIN
    INSERT INTO tags (name, value) VALUES (my_name, my_value) RETURNING tagid INTO retval;
    RETURN retval;

    EXCEPTION
        WHEN unique_violation THEN
            SELECT tagid INTO retval FROM tags WHERE name = my_name AND value = my_value;
            RETURN retval;
END;
$$ LANGUAGE plpgsql;

您可以在手册中找到有关此内容的更多信息: http://www.postgresql.org/docs/current/static/plpgsql-control-structures.html#PLPGSQL-ERROR-TRAPPING