Вие сами сте удебелили основното изречение в ръководството:
Цялото тяло на SQL функция се анализира, преди която и да е от тях да бъде изпълнена.
Прочетете също за Стадия на анализатора в ръководството.
Състои се от две основни части:парсер и процеса на трансформация . Цитирайки ръководството:
процесът на трансформация взема дървото, предадено обратно от синтактичния анализатор, като вход и прави семантичната интерпретация, необходима, за да се разбере кои таблици, функции и оператори се препращат от заявката.
Ако SQL функция съдържа следните команди:
CREATE TABLE foo (...);
INSERT INTO foo VALUES(...);
И двете изявления се планират практически по едно и също време (въз основа на една и съща моментна снимка на системните каталози). Следователно, INSERT
не може да види таблицата "foo", вероятно създадена с предишния CREATE
команда. Това създава един от следните проблеми :
-
Ако няма други таблица с име "foo" във вашия
search_patch
(все още), Postgres се оплаква когато се опитва да създаде функцията:ERROR: relation "foo" does not exist
-
Ако друга таблица с име "foo" вече съществува във вашия
search_patch
(и не използвате противоречиви имена на колони), Postgres ще планираINSERT
въз основа на тази вече съществуваща таблица. Обикновено това води до грешка по време на изпълнение , ако някакви стойности причиняват конфликти в (грешната!) таблицата. Или, с малко късмет, може дори да пише в тази таблица без съобщение за грешка! Много подъл бъг.
Това не може да се случи с PL/pgSQL функция, защото третира SQL командите като подготвени изрази, планирани и изпълнени последователно . Така всеки израз може да види обекти, създадени в предишни оператори.
Следователно, изрази, които никога не се посещават, никога дори не се планират - за разлика от SQL функциите. А планът за изпълнение на изразите може да се кешира в рамките на същата сесия - също за разлика от SQL функциите. Прочетете подробности за кеширането на план във функциите PL/pgSQL в ръководството тук.
Всеки подход има предимства за някои случаи на употреба. Допълнително четене:
- Разлика между език sql и език plpgsql във функциите на PostgreSQL