Возможно ли использование предложения RETURNING из UPDATE в качестве предложения запроса для предложения запроса INSERT? - PullRequest
2 голосов
/ 08 июля 2010

Я пытаюсь использовать предложение PostgreSQL RETURNING для UPDATE в операторе UPDATE и сталкиваюсь с проблемами.

Postgres разрешает предложение запроса в INSERT, например:

INSERT INTO films 
SELECT * FROM tmp_films WHERE date_prod < '2004-05-07';

Я хотел бы использовать предложение RETURNING из UPDATE в качестве предложения запроса для INSERT, например:

INSERT INTO user_status_history(status)
UPDATE user_status SET status = 'ACTIVE' WHERE status = 'DISABLED' RETURNING status

Все ссылки на Postgres, которые я могу найти, предполагают, что предложение RETURNING ведет себя точно так же, какПредложение SELECT, однако, когда я запускаю что-то подобное, я получаю следующее:

ОШИБКА: синтаксическая ошибка в или около «ОБНОВЛЕНИЕ»

ЛИНИЯ 2: ОБНОВЛЕНИЕ user_statuses

Несмотря на возможность выполнения части UPDATE вышеуказанного запроса без ошибок.

Возможно ли использование предложения RETURNING из UPDATE в качестве предложения запроса для предложения запроса INSERT?

Цель состоит в том, чтобы обновить одну таблицу и вставить в другую с помощью одного запроса, если это возможно.

Ответы [ 3 ]

4 голосов
/ 17 октября 2011

В PostgreSQL 9.1 (или выше) вы можете использовать новую функциональность, которая позволяет использовать команды изменения данных (INSERT / UPDATE / DELETE) в предложениях WITH , таких как:

WITH updated_rows AS
(
    UPDATE products
    SET ...
    WHERE ...
    RETURNING *
)
INSERT INTO products_log
SELECT * FROM updated_rows;

В PostgreSQL 9.0 (или ниже) вы можете встроить команду UPDATE в одну функцию, а затем использовать эту функцию из другой функции, которая выполняет команду INSERT, например:

FUNCTION update_rows()
RETURNS TABLE (id integer, descrip varchar)
AS $$
BEGIN
    RETURN QUERY
        UPDATE products
        SET ...
        WHERE ...
        RETURNING *;
END;
$$ LANGUAGE plpgsql;

FUNCTION insert_rows()
RETURNS void
AS $$
BEGIN
    INSERT INTO products_log
    SELECT * FROM update_rows() AS x;
END;
$$ LANGUAGE plpgsql;
1 голос
/ 08 июля 2010

Прямо сейчас, нет.

Была функция, которая почти превратила его в PostgreSQL 9.0, известный как Записываемые CTE , который делает то, что вы думаете (хотясинтаксис другой).

В настоящее время вы можете сделать это через триггер или в виде двух отдельных операторов.

0 голосов
/ 08 июля 2010

Я думаю, что это невозможно, как вы пытаетесь сделать. Я бы предложил вам написать триггер AFTER UPDATE, который мог бы выполнить вставку, а затем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...