Синтаксическая ошибка в запросе. Нужна помощь.

Запрос - вариации на тему upsert . Если выполнять Update отдельно - все работает нормально. В одном запросе с insert - выдает синтаксическую ошибку. Версия Postgresql - 8.4.

CREATE TABLE tbl( KEY  int, val int);
 
INSERT INTO tbl(KEY,val)
   SELECT DISTINCT(KEY), 0 FROM unnest('{0,1,2,3,4,5}'::int[]) AS KEY
       WHERE KEY NOT IN (
         UPDATE tbl SET val = 1
             WHERE KEY = any('{0,1,2,3,4,5}'::int[])
         returning KEY
);

Ошибка:

ERROR:  syntax error at OR near "tbl"
Строка 6:  UPDATE tbl SET val = 1
                  ^
 
********** Error **********
 
ERROR: syntax error at OR near "tbl"
SQL state: 42601
Character: 167

Буду благодарен за ответ.

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Первое, что приходит на ум -

Первое, что приходит на ум - два уровня вложенности - не уверен, что это можно.
Второе, что думается - это с логической точки зрения нонсенс. Вы изменяете таблицу, вставляя записи и одновременно пытаетесь эту же таблицу изменять - по идее СУБД должна вас далеко и сразу послать.
Третье, UPDATE не возвращает ничего, таким образом в IN будет пусто, т.е. непонятно что и зачем вы пытаетесь сделать в UPDATE.
Четвёртое в INSERT отсуствует VALUES.
В общем, чтобы вам помочь, нужно сперва понять, что вы хотите, а вы наворотили что-то выше моего понимания

> Первое, что приходит на ум

> Первое, что приходит на ум - два уровня вложенности - не уверен, что это можно.

select * from (select * from (select * from (select 1) as foobar ) as bar ) as foo;

> Второе, что думается - это с логической точки зрения нонсенс.

По идее сперва должен выполнится внутрений запрос, котрый вернет id измененных столбцов, а потом - внешний, который произведет вставку для всех остальных.

> Третье, UPDATE не возвращает ничего ...

http://www.postgresql.org/docs/8.4/static/sql-update.html The optional RETURNING clause causes UPDATE to compute and return value(s) based on each row actually updated. Any expression using the table's columns, and/or columns of other tables mentioned in FROM, can be computed. The new (post-update) values of the table's columns are used. The syntax of the RETURNING list is identical to that of the output list of SELECT.

Случай, когда ничего не изменено, нужно, действительно, обрабатывать отдельно. Спасибо за наводку. Но это легко лечится банальным Select Null union ...

> Четвёртое в INSERT отсуствует VALUES.

Если в insert поступают строки из select - то синтаксис именно такой.
Попробуйте: Insert into tbl(key,val) select 1,2;

И всё же вы так и не

И всё же вы так и не ответили, что вы хотите сделать таким запросом

Вариации на тему UPSERT -

Вариации на тему UPSERT - если ключ есть, то значение обновляется, если нет - то вставляется.

Посмотрите эту ссылку. Похожий на ваш вопрос

http://stackoverflow.com/questions/7191902/cannot-select-from-update-ret...
В одном из ответов говориться, что до версии 9.1 операторы DELETE, UPDATE, INSERT не могут быть использованы в подзапросах.

спасибо

спасибо

Переводил документацию для 9-ки и наткнулся

Похоже что это именно то, что вам нужно. Работать надо с WITH:

WITH moved_rows AS (
    DELETE FROM products
    WHERE
        "date" >= '2010-10-01' AND
        "date" < '2010-11-01'
    RETURNING *
)
INSERT INTO products_log
SELECT * FROM moved_rows;

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Back to top

(С) Виктор Вислобоков, 2008-2023