41.2. СÑÑÑкÑÑÑа PL/pgSQL #
ФÑнкÑии, напиÑаннÑе на PL/pgSQL, опÑеделÑÑÑÑÑ Ð½Ð° ÑеÑвеÑе командами CREATE FUNCTION. Ð¢Ð°ÐºÐ°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° обÑÑно вÑглÑдиÑ, напÑимеÑ, Ñак:
CREATE FUNCTION somefunc(integer, text) RETURNS integer
AS 'Ñело ÑÑнкÑии'
LANGUAGE plpgsql; ÐÑли ÑаÑÑмаÑÑиваÑÑ CREATE FUNCTION, Ñело ÑÑнкÑии пÑедÑÑавлÑÐµÑ Ñобой пÑоÑÑо ÑекÑÑовÑÑ ÑÑÑокÑ. ЧаÑÑо Ð´Ð»Ñ Ð½Ð°Ð¿Ð¸ÑÐ°Ð½Ð¸Ñ Ñела ÑÑнкÑии Ñдобнее заклÑÑаÑÑ ÑÑÑ ÑÑÑÐ¾ÐºÑ Ð² доллаÑÑ (Ñм. ÐодÑаздел 4.1.2.4), а не в обÑÑнÑе апоÑÑÑоÑÑ. ÐÑли не пÑименÑÑÑ Ð·Ð°ÐºÐ»ÑÑение в доллаÑÑ, вÑе апоÑÑÑоÑÑ Ð¸Ð»Ð¸ обÑаÑнÑе коÑÑе ÑеÑÑÑ Ð² Ñеле ÑÑнкÑии пÑидÑÑÑÑ ÑкÑаниÑоваÑÑ, дÑблиÑÑÑ Ð¸Ñ
. ÐоÑÑи во вÑеÑ
пÑимеÑаÑ
в ÑÑой главе Ñело ÑÑнкÑий заклÑÑаеÑÑÑ Ð² доллаÑÑ.
PL/pgSQL ÑÑо блоÑно-ÑÑÑÑкÑÑÑиÑованнÑй ÑзÑк. ТекÑÑ Ñела ÑÑнкÑии должен бÑÑÑ Ð±Ð»Ð¾ÐºÐ¾Ð¼. СÑÑÑкÑÑÑа блока:
[ <<меÑка>> ] [ DECLAREобÑÑвлениÑ] BEGINопеÑаÑоÑÑEND [меÑка];
Ðаждое обÑÑвление и каждÑй опеÑаÑÐ¾Ñ Ð² блоке Ð´Ð¾Ð»Ð¶Ð½Ñ Ð·Ð°Ð²ÐµÑÑаÑÑÑÑ Ñимволом «;» (ÑоÑка Ñ Ð·Ð°Ð¿ÑÑой). Ðлок, вложеннÑй в дÑÑгой блок, должен имеÑÑ ÑоÑÐºÑ Ñ Ð·Ð°Ð¿ÑÑой поÑле END, как показано вÑÑе. Ðднако ÑиналÑнÑй END, завеÑÑаÑÑий Ñело ÑÑнкÑии, не ÑÑебÑÐµÑ ÑоÑки Ñ Ð·Ð°Ð¿ÑÑой.
ÐодÑказка
РаÑпÑоÑÑÑанÑнной оÑибкой ÑвлÑеÑÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ ÑоÑки Ñ Ð·Ð°Ð¿ÑÑой ÑÑÐ°Ð·Ñ Ð¿Ð¾Ñле BEGIN. ÐÑо непÑавилÑно и пÑиведÑÑ Ðº ÑинÑакÑиÑеÑкой оÑибке.
ÐеÑка ÑÑебÑеÑÑÑ ÑолÑко Ñогда, когда нÑжно иденÑиÑиÑиÑоваÑÑ Ð±Ð»Ð¾Ðº в опеÑаÑоÑе EXIT, или дополниÑÑ Ð¸Ð¼ÐµÐ½Ð° пеÑеменнÑÑ
, обÑÑвленнÑÑ
в ÑÑом блоке. ÐÑли меÑка Ñказана поÑле END, Ñо она должна ÑовпадаÑÑ Ñ Ð¼ÐµÑкой в наÑале блока.
ÐлÑÑевÑе Ñлова не ÑÑвÑÑвиÑелÑÐ½Ñ Ðº ÑегиÑÑÑÑ Ñимволов. Ðак и в обÑÑнÑÑ SQL-ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°Ñ , иденÑиÑикаÑоÑÑ Ð½ÐµÑвно пÑеобÑазÑÑÑÑÑ Ðº Ð½Ð¸Ð¶Ð½ÐµÐ¼Ñ ÑегиÑÑÑÑ, еÑли они не взÑÑÑ Ð² двойнÑе кавÑÑки.
ÐомменÑаÑии в PL/pgSQL коде ÑабоÑаÑÑ Ñак же, как и в обÑÑном SQL. Ðвойное ÑиÑе (--) наÑÐ¸Ð½Ð°ÐµÑ ÐºÐ¾Ð¼Ð¼ÐµÐ½ÑаÑий, коÑоÑÑй завеÑÑаеÑÑÑ Ð² конÑе ÑÑÑоки. ÐлоÑнÑй комменÑаÑий наÑинаеÑÑÑ Ñ /* и завеÑÑаеÑÑÑ */. ÐлоÑнÑе комменÑаÑии могÑÑ Ð±ÑÑÑ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð½Ñми.
ÐÑбой опеÑаÑÐ¾Ñ Ð² вÑполнÑемой ÑекÑии блока Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð½Ñм блоком. ÐложеннÑе блоки иÑполÑзÑÑÑÑÑ Ð´Ð»Ñ Ð»Ð¾Ð³Ð¸ÑеÑкой гÑÑппиÑовки неÑколÑÐºÐ¸Ñ Ð¾Ð¿ÐµÑаÑоÑов или локализаÑии облаÑÑи дейÑÑÐ²Ð¸Ñ Ð¿ÐµÑеменнÑÑ Ð´Ð»Ñ Ð³ÑÑÐ¿Ð¿Ñ Ð¾Ð¿ÐµÑаÑоÑов. Ðо вÑÐµÐ¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð½Ð¾Ð³Ð¾ блока пеÑеменнÑе, обÑÑвленнÑе в нÑм, ÑкÑÑваÑÑ Ð¿ÐµÑеменнÑе внеÑÐ½Ð¸Ñ Ð±Ð»Ð¾ÐºÐ¾Ð² Ñ Ñакими же именами. ЧÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑиÑÑ Ð´Ð¾ÑÑÑп к внеÑним пеÑеменнÑм, нÑжно дополниÑÑ Ð¸Ñ Ð¸Ð¼ÐµÐ½Ð° меÑкой блока. ÐапÑимеÑ:
CREATE FUNCTION somefunc() RETURNS integer AS $$
<< outerblock >>
DECLARE
quantity integer := 30;
BEGIN
RAISE NOTICE 'СейÑÐ°Ñ quantity = %', quantity; -- ÐÑводиÑÑÑ 30
quantity := 50;
--
-- ÐложеннÑй блок
--
DECLARE
quantity integer := 80;
BEGIN
RAISE NOTICE 'СейÑÐ°Ñ quantity = %', quantity; -- ÐÑводиÑÑÑ 80
RAISE NOTICE 'Ðо внеÑнем блоке quantity = %', outerblock.quantity; -- ÐÑводиÑÑÑ 50
END;
RAISE NOTICE 'СейÑÐ°Ñ quantity = %', quantity; -- ÐÑводиÑÑÑ 50
RETURN quantity;
END;
$$ LANGUAGE plpgsql;ÐÑимеÑание
СÑÑеÑÑвÑÐµÑ ÑкÑÑÑÑй «внеÑний блок», окÑÑжаÑÑий Ñело каждой ÑÑнкÑии на PL/pgSQL. ÐÑÐ¾Ñ Ð±Ð»Ð¾Ðº ÑодеÑÐ¶Ð¸Ñ Ð¾Ð±ÑÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð°ÑамеÑÑов ÑÑнкÑии (еÑли они еÑÑÑ), а Ñакже некоÑоÑÑе ÑпеÑиалÑнÑе пеÑеменнÑе, Ñакие как FOUND (Ñм. ÐодÑаздел 41.5.5). ÐÑÐ¾Ñ Ð±Ð»Ð¾Ðº Ð¸Ð¼ÐµÐµÑ Ð¼ÐµÑкÑ, ÑовпадаÑÑÑÑ Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ ÑÑнкÑии, Ñаким обÑазом, паÑамеÑÑÑ Ð¸ ÑпеÑиалÑнÑе пеÑеменнÑе могÑÑ Ð±ÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ ÑÑнкÑии.
Ðажно не пÑÑаÑÑ Ð¸ÑполÑзование BEGIN/END Ð´Ð»Ñ Ð³ÑÑппиÑовки опеÑаÑоÑов в PL/pgSQL Ñ Ð¾Ð´Ð½Ð¾Ð¸Ð¼ÑннÑми SQL-командами Ð´Ð»Ñ ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ ÑÑанзакÑиÑми. BEGIN/END в PL/pgSQL ÑлÑÐ¶Ð°Ñ ÑолÑко Ð´Ð»Ñ Ð³ÑÑппиÑовки пÑедложений; они не наÑинаÑÑ Ð¸ не заканÑиваÑÑ ÑÑанзакÑии. УпÑавление ÑÑанзакÑиÑми в PL/pgSQL опиÑÑваеÑÑÑ Ð² Разделе 41.8. ÐÑоме Ñого, блок Ñ Ð¿Ñедложением EXCEPTION по ÑÑÑи ÑоздаÑÑ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð½ÑÑ ÑÑанзакÑиÑ, коÑоÑÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ оÑмениÑÑ, не заÑÑÐ°Ð³Ð¸Ð²Ð°Ñ Ð²Ð½ÐµÑнÑÑ ÑÑанзакÑиÑ. ÐодÑобнее ÑÑо опиÑано в ÐодÑазделе 41.6.8.