45.1. ФÑнкÑии на PL/Python
ФÑнкÑии на PL/Python обÑÑвлÑÑÑÑÑ ÑÑандаÑÑнÑм обÑазом Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ CREATE FUNCTION:
CREATE FUNCTIONимÑ_ÑÑнкÑии(аÑгÑменÑÑ) RETURNSвозвÑаÑаемÑй_ÑипAS $$ # Тело ÑÑнкÑии на PL/Python $$ LANGUAGE plpython3u;
Тело ÑÑнкÑии ÑодеÑÐ¶Ð¸Ñ Ð¿ÑоÑÑо ÑкÑÐ¸Ð¿Ñ Ð½Ð° ÑзÑке Python. Ðогда вÑзÑваеÑÑÑ ÑÑнкÑиÑ, ÐµÑ Ð°ÑгÑменÑÑ Ð¿ÐµÑедаÑÑÑÑ Ð² виде ÑлеменÑов ÑпиÑка args; именованнÑе аÑгÑменÑÑ Ñакже пеÑедаÑÑÑÑ ÑкÑипÑÑ Python как обÑÑнÑе пеÑеменнÑе. С именованнÑми аÑгÑменÑами ÑкÑÐ¸Ð¿Ñ Ð¾Ð±ÑÑно лÑÑÑе ÑиÑаеÑÑÑ. РезÑлÑÑÐ°Ñ Ð¸Ð· кода Python возвÑаÑаеÑÑÑ Ð¾Ð±ÑÑнÑм ÑпоÑобом: командой return или yield (в ÑлÑÑае ÑÑнкÑии, возвÑаÑаÑÑей множеÑÑво). ÐÑли возвÑаÑаемое знаÑение не опÑеделено, Python возвÑаÑÐ°ÐµÑ None. ÐÑполниÑÐµÐ»Ñ PL/Python пÑеобÑазÑÐµÑ None ÑзÑка Python в знаÑение NULL ÑзÑка SQL. РпÑоÑедÑÑе код Python должен возвÑаÑаÑÑ None (обÑÑно Ð´Ð»Ñ ÑÑого пÑоÑедÑÑа завеÑÑаеÑÑÑ Ð±ÐµÐ· опеÑаÑоÑа return или иÑполÑзÑеÑÑÑ Ð¾Ð¿ÐµÑаÑÐ¾Ñ return без аÑгÑменÑа); в пÑоÑивном ÑлÑÑае вÑдаÑÑÑÑ Ð¾Ñибка.
ÐапÑимеÑ, ÑÑнкÑиÑ, возвÑаÑаÑÑее болÑÑее из двÑÑ ÑелÑÑ ÑиÑел, можно опÑеделиÑÑ Ñак:
CREATE FUNCTION pymax (a integer, b integer)
RETURNS integer
AS $$
if a > b:
return a
return b
$$ LANGUAGE plpython3u;Ðод на Python, заданнÑй в каÑеÑÑве Ñела обÑÑвлÑемой ÑÑнкÑии, ÑÑановиÑÑÑ Ñелом ÑÑнкÑии Python. ÐапÑимеÑ, Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½Ð½Ð¾Ð³Ð¾ вÑÑе обÑÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑÑаеÑÑÑ ÑÑнкÑиÑ:
def __plpython_procedure_pymax_23456():
if a > b:
return a
return bÐдеÑÑ 23456 â ÑÑо OID, коÑоÑÑй Postgres Pro пÑиÑвоил данной ÑÑнкÑии.
ÐнаÑÐµÐ½Ð¸Ñ Ð°ÑгÑменÑов задаÑÑÑÑ Ð² глобалÑнÑÑ Ð¿ÐµÑеменнÑÑ . СоглаÑно пÑавилам видимоÑÑи в Python, Ñонким ÑледÑÑвием ÑÑого ÑвлÑеÑÑÑ Ñо, ÑÑо пеÑеменной аÑгÑменÑа нелÑÐ·Ñ Ð¿ÑиÑвоиÑÑ Ð²Ð½ÑÑÑи ÑÑнкÑии вÑÑажение, вклÑÑаÑÑее Ð¸Ð¼Ñ Ñамой ÑÑой пеÑеменной, еÑли ÑолÑко ÑÑа пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð½Ðµ обÑÑвлена глобалÑной в ÑекÑÑем блоке. ÐапÑимеÑ, ÑледÑÑÑий код не бÑÐ´ÐµÑ ÑабоÑаÑÑ:
CREATE FUNCTION pystrip(x text) RETURNS text AS $$ x = x.strip() # оÑибка return x $$ LANGUAGE plpython3u;
Ñак как пÑиÑваивание x знаÑÐµÐ½Ð¸Ñ Ð´ÐµÐ»Ð°ÐµÑ x локалÑной пеÑеменной Ð´Ð»Ñ Ð²Ñего блока, и пÑи ÑÑом x в пÑавой ÑаÑÑи пÑиÑÐ²Ð°Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¾ÐºÐ°Ð·ÑваеÑÑÑ ÐµÑÑ Ð½Ðµ опÑеделÑнной локалÑной пеÑеменной x, а не паÑамеÑÑом ÑÑнкÑии PL/Python. Ðобавив опеÑаÑÐ¾Ñ global, ÑÑо можно иÑпÑавиÑÑ:
CREATE FUNCTION pystrip(x text) RETURNS text AS $$ global x x = x.strip() # ÑепеÑÑ Ð²ÑÑ Ð² поÑÑдке return x $$ LANGUAGE plpython3u;
Ðднако ÑекомендÑеÑÑÑ Ð½Ðµ полагаÑÑÑÑ Ð½Ð° Ñакие оÑобенноÑÑи ÑеализаÑии PL/Python, а пÑинÑÑÑ, ÑÑо паÑамеÑÑÑ ÑÑнкÑии пÑедназнаÑÐµÐ½Ñ ÑолÑко Ð´Ð»Ñ ÑÑениÑ.