INSERT или возврат строки, если запись уже существует в таблице с ограничением UNIQUE - PullRequest
1 голос
/ 04 августа 2010

Привет,

У меня есть эта таблица на сервере 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 Ответ

3 голосов
/ 04 августа 2010

Просто вставьте и выполните некоторую обработку исключений:

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

...