Невозможно выбрать из предложения UPDATE RETURNING в postgres - PullRequest
12 голосов
/ 25 августа 2011

Я изолирую проблему от гораздо более сложного запроса. Здесь тестовый сценарий

DROP TABLE test; 
CREATE TABLE test (
  id integer,
  description varchar(100)
);

INSERT INTO test(id, description) VALUES (1,'new'); 
INSERT INTO test(id, description) VALUES (2,'new'); 

Если я выполню запрос:

SELECT * FROM test WHERE id IN (UPDATE test set description='test' RETURNING id)

Я получаю следующую ошибку:

ОШИБКА: синтаксическая ошибка в или около "теста" ЛИНИЯ 1: ВЫБРАТЬ * ИЗ ТЕСТА, ГДЕ id (ОБНОВИТЬ описание набора тестов = 'test' RE ... ^

*** Fehler ***

ОШИБКА: синтаксическая ошибка в или около "теста" Состояние SQL: 42601 Zeichen: 37

Тем не менее, если я только запускаю statemennt

UPDATE test set value='test' RETURNING id

Я получаю результат с 2 строками:

1 2

Если я подставлю этот результат, у меня будет такой запрос:

SELECT * FROM test WHERE id IN (1,2);

с результатом:

1; "тест" 2, "тест"

Почему я не получаю тот же результат с моим первоначальным утверждением?

Ответы [ 7 ]

32 голосов
/ 26 августа 2011

До PostgreSQL 9.1 INSERT / UPDATE / DELETE можно было использовать только как операторы верхнего уровня.Вот почему вы получаете синтаксическую ошибку.

Начиная с 9.1 вы можете использовать операторы, модифицирующие данные, с общими табличными выражениями.Ваш пример запроса будет выглядеть так:

WITH updated AS (UPDATE test SET description = 'test' RETURNING id)
SELECT * FROM test WHERE id IN (SELECT id FROM updated);

Будьте внимательны при выборе из только что измененной таблицы.Таким образом, вы можете получить запутанные результаты.Поскольку запросы выполняются в одном и том же снимке, команда SELECT не увидит эффектов оператора UPDATE.

7 голосов
/ 25 августа 2011

Вы обновляете две строки в запросе UPDATE, добавляете предложение WHERE, чтобы ограничить затронутые строки.

UPDATE test SET description = 'test' WHERE id = 1 RETURNING id

, чтобы вернуть одну строку .

3 голосов
/ 25 августа 2011

Вам не хватает IN: ... WHERE id IN (UPDATE ...?

Однако, если я запускаю только состояние "UPDATE test set set value = 'test' RETURNING id ", я получаю результат с 2 строками. Почему это так?

У вашего UPDATE нет предложения WHERE, и поэтому он обновляет каждую строку, из которых есть две.

1 голос
/ 20 июля 2012
UPDATE test set description='test' RETURNING *

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

Но я подозреваю, что вы пытались что-то более сложное?

1 голос
/ 25 августа 2011

Вы не ограничиваете свой пункт where.Вам нужно иметь id = (бла-бла) или id IN (бла-бла)

0 голосов
/ 20 октября 2016

Я - дополнение от Муравьев Аасма, если выбрать на том же столе, используя:

WITH updated AS (UPDATE test SET description = 'test' RETURNING id, description)
SELECT * FROM updated;
0 голосов
/ 05 октября 2015
DROP TABLE IF EXISTS test_tab;

CREATE TABLE test_tab (
  id integer,
  description varchar(100)
);

INSERT INTO test_tab(id, description) VALUES (1,'new'); 
INSERT INTO test_tab(id, description) VALUES (2,'new'); 

SELECT * from test_tab;

DO $$
DECLARE
    myID    test_tab.id%TYPE;
    testID  test_tab.id%TYPE;
    cur_IDs CURSOR for select id from test_tab;
BEGIN
    OPEN cur_IDs;
    LOOP
        FETCH cur_IDs into testID;
        EXIT WHEN testID is NULL;

        UPDATE test_tab SET description='test' WHERE id = testID RETURNING id into myID;
        raise notice 'myID %', myID;
    END LOOP;
    CLOSE cur_IDs;
END$$;


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