45.11. Пакеты #
Функции PL/pgSQL могут работать с объектами, собранными в пакеты. Пакет — это по сути схема, которая помогает организовать взаимосвязанные именованные объекты, поэтому его можно создать как обычной командой CREATE SCHEMA
, так и специальной командой CREATE PACKAGE
. Однако пакет может содержать только функции, процедуры и составные типы.
Когда вы создаёте пакет, вы также должны создать функцию инициализации. Функция инициализации представляет собой функцию PL/pgSQL с именем __init__
, которая не имеет аргументов и возвращает void
. Обратите внимание, что функция инициализации должна быть определена до любой другой функции пакета, а все переменные, объявленные в функции инициализации, являются глобальными, поэтому к ним могут обращаться функции других пакетов, используя запись с точкой. Например, на переменную bar
, объявленную в функции __init__
пакета foo
, можно ссылаться как foo.bar
.
В Postgres Pro предоставляются модификаторы определения функций для работы с пакетами. Модификатор #package
определяет, что это функция пакета и она может напрямую использовать переменные этого пакета. Модификатор #import
определяет, что функция может обращаться к переменным других пакетов, используя запись с точкой, как описано выше. При создании функций внутри пакета командой CREATE PACKAGE
модификатор #package
опускается. Модификатор #private
определяет, что функция является внутренней, то есть на неё нельзя ссылаться снаружи пакета, но она необходима для обслуживающих процессов пакета. Модификатор #export
определяет, что переменная пакета является публичной, то есть на неё можно ссылаться снаружи пакета. Когда вызывается функция с модификатором #package
, содержащий её пакет инициализируется, если он ещё не был инициализирован в текущем сеансе. Функцию с модификатором #package
можно создать только в схеме, содержащей функцию инициализации. Эти пакеты инициализируются автоматически, если они ещё не были инициализированы в текущем сеансе. Если указан модификатор #import
, функция будет иметь доступ к переменным пакетов, указанных в списке через запятую. Эти пакеты инициализируются автоматически, если они ещё не были инициализированы в текущем сеансе. В пакетах, созданных командой CREATE PACKAGE
, модификатор #import
, указанный для функции инициализации, влияет на все функции пакета, но при использовании команды CREATE SCHEMA
он должен быть определён отдельно для __init__
и других функций пакета. Модификатор #import
также можно использовать в анонимных блоках кода.
В следующем примере использования модификатора #import
процедура showValues
вызывает функцию p
из пакета htp
и функцию set_action
из пакета dbms_application_info
.
CREATE OR REPLACE PROCEDURE showValues(p_Str varchar) AS $$ #import htp, dbms_application_info BEGIN CALL dbms_application_info.set_action('Show hello'); CALL htp.p('<p>' || p_Str || '</p>'); END; $$LANGUAGE plpgsql;
В PL/pgSQL имеется встроенная функция plpgsql_reset_packages()
, которая сбрасывает состояние всех пакетов в данном сеансе.
SELECT plpgsql_reset_packages();