PostgreSQL зацикливает внешние функции. Это возможно?
Я делаю сравнительный анализ PostgreSQL и SQLServer для целей миграции. Теперь я оцениваю T-SQL против PL/pgSQL, дело в том, что в T-SQL вы можете использовать циклы или объявлять переменные, например:
declare @counter int
set @counter = 0
while @counter < 10
begin
set @counter = @counter + 1
print 'The counter is ' + cast(@counter as char)
end
Нет необходимости помещать его в функцию или процедуру. Могу ли я сделать это в PostgreSQL?
Выполняя поиск в Интернете, я нашел отрицательный ответ, делая это в MySQL, но я не нашел такого ответа для Postgres.
2 ответа
Вы не можете DECLARE
(глобальные) переменные ( ну, есть способы обойти это), ни цикл с простым SQL - за исключением рекурсивных CTE, предоставляемых @bma.
Тем не менее, есть DO
заявление для такого специального процедурного кодекса. Представлено с Postgres 9.0. Работает как одноразовая функция, но ничего не возвращает. Вы можете RAISE
notices et al, твой пример будет работать нормально:
DO
$do$
DECLARE
_counter int := 0;
BEGIN
WHILE _counter < 10
LOOP
_counter := _counter + 1;
RAISE NOTICE 'The counter is %', _counter; -- coerced to text automatically
END LOOP;
END
$do$
Если не указано иное, язык в теле plpgsql
, Вы можете использовать любой зарегистрированный процедурный язык, если вы его объявите (например: LANGUAGE plpython
).
Postgres также предлагает generate_series()
генерировать наборы ad-hoc, что может избавить от необходимости зацикливания во многих случаях. Попробуйте поискать здесь на SO для примеров.
Также вы можете использовать WHERE
предложение в CTE, изменяющем данные, в простом SQL для форкирования случаев и эмуляции IF .. THEN .. ELSE .. END
...
Вы можете рекурсивно запрашивать наборы результатов, используя WITH RECURSIVE, предполагая, что вы используете Postgresql 8.4+. Документы: http://www.postgresql.org/docs/current/static/queries-with.html
Это позволит вам зациклить ваш набор и обрабатывать данные различными способами.