2012-05-28 4 views
1

Я пытаюсь создать функцию plpgsql в Postgres 8.4, которая использует CTE внутри, но это дает мне синтаксическую ошибку. Не разрешены ли они?Использование CTE в plpgsql

(что-то вроде этого, имейте в виду, что я пишу это без моего кода.)

With foo as (SELECT id,a as alias FROM foo); 
UPDATE zoo SET b = alias FROM foo WHERE id = foo.id; 
^Error here 
+1

удалить точку с запятой после foo) – wildplasser

+0

Это не проблема, я уже пробовал. – jpp1jpp1

ответ

3
WITH foo as (
    SELECT id 
     , a AS zalias 
    FROM footable 
    ) 
UPDATE zoo z 
SET b = f.zalias 
FROM foo f 
WHERE z.id = f.id 
    ; 

Примечание: "псевдоним" является зарезервированным словом.

ОБНОВЛЕНИЕ по состоянию на комментарий Эрвина Брандстетера: CTE недействителен в инструкции UPDATE в 8.4. Вам понадобится 9.1 или выше. Поскольку CTE на самом деле является своего рода мгновенным представлением, вы можете поместить тело CTE в представление и сослаться на это.

CREATE VIEW foo as (
    SELECT id 
     , a AS zalias 
    FROM footable 
    ); 
UPDATE zoo z 
SET b = f.zalias 
FROM foo f 
WHERE z.id = f.id 
    ; 
DROP VIEW foo; 
+0

'alias' - это [зарезервированное слово] (http://www.postgresql.org/docs/current/interactive/sql-keywords-appendix.html) только в SQL: 1999, но не в более поздних версиях стандарта, а не в PostgreSQL. Поэтому безопасно использовать его свободно. –

+0

Я стою исправлены. Кажется, я помню, что когда функции не имели именованных параметров (pg 8.3?), Псевдоним был ключевым словом. Я все же предпочитаю избегать этого. – wildplasser

+0

Спасибо, я закончил использовать подход temp view. – jpp1jpp1

2

data modifying CTE (это то, что она есть) является не доступны в PostgreSQL 8.4.

Ваше заявление будет работать с незначительными патчами, поскольку @wildplasser демонстрирует в PostgreSQL 9.1 или более поздней версии, где были введены данные, модифицирующие CTE.

Очень простая замена 8.4 будет подзапрос:

UPDATE zoo z 
SET b = f.alias 
FROM (SELECT id, a as alias FROM foo) f 
WHERE z.id = f.id; 

Пример можно дополнительно упростить (но, возможно, реальный мир случай является более сложным):

UPDATE zoo z 
SET b = f.a 
FROM foo f 
WHERE z.id = f.id; 

Запомнить to table-qualify в противном случае неоднозначное имя столбца id в предложении WHERE.

+0

Действительно ли это данные, модифицирующие CTE? Похож на общий, поскольку это не заявление DDL внутри CTE. – vyegorov

+0

@vyegorov: Сначала я не был уверен. Но я изучил руководство и попробовал тест на кластере 8.4: никакой радости. –

+0

Я не решался добавить, что окончательное сокращение до 'update ... FROM ...' – wildplasser

Смежные вопросы