44.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();