F.44. pg_variables

Модуль pg_variables содержит функции для работы с переменными различных типов. Созданные переменные существуют в течение текущей пользовательской сессии.

F.44.1. Установка

Расширение pg_variables включено в состав Postgres Pro. Установив Postgres Pro, вы должны выполнить команду CREATE EXTENSION, чтобы подготовить pg_variables к работе, следующим образом:

CREATE EXTENSION pg_variables;

F.44.2. Использование

Модуль pg_variables содержит функции, позволяющие создавать переменные скалярных типов, переменные-записи и переменные-массивы, читать их и управлять ими. Синтаксис и описания функций представлены в следующих разделах:

Разобранные примеры использования вы можете найти в Подразделе F.44.4.

F.44.2.1. Использование транзакционных переменных

По умолчанию переменные создаются как нетранзакционные. Успешно созданная переменная продолжает существовать на протяжении всего сеанса, вне зависимости от возможных откатов транзакций. Например:

SELECT pgv_set('vars', 'int1', 101); BEGIN; SELECT pgv_set('vars', 'int2', 102); ROLLBACK; SELECT * FROM pgv_list() order by package, name; package | name | is_transactional ---------+------+------------------ vars | int1 | f vars | int2 | f

Если вы хотите использовать переменную с поддержкой транзакций и точек сохранения, передайте дополнительный флаг is_transactional в последнем параметре функции, создающей переменную:

BEGIN; SELECT pgv_set('vars', 'trans_int', 101, true); SAVEPOINT sp1; SELECT pgv_set('vars', 'trans_int', 102, true); ROLLBACK TO sp1; COMMIT; SELECT pgv_get('vars', 'trans_int', NULL::int); pgv_get --------- 101

Вы должны указывать флаг is_transactional при каждом изменении значения транзакционной переменной с помощью функций pgv_set() и pgv_insert(). В противном случае произойдёт ошибка. Другим функциям передавать этот флаг не нужно.

SELECT pgv_insert('pack', 'var_record', row(123::int, 'text'::text), true); SELECT pgv_insert('pack', 'var_record', row(456::int, 'another text'::text)); ERROR: variable "var_record" already created as TRANSACTIONAL SELECT pgv_delete('pack', 'var_record', 123::int); 

Если вызовы функций pgv_free() или pgv_remove() откатываются, затрагиваемые транзакционные переменные восстанавливаются, в отличие от нетранзакционных, которые удаляются необратимо. Например:

SELECT pgv_set('pack', 'var_reg', 123); SELECT pgv_set('pack', 'var_trans', 456, true); BEGIN; SELECT pgv_free(); ROLLBACK; SELECT * FROM pgv_list(); package | name | is_transactional ---------+-----------+------------------ pack | var_trans | t

F.44.3. Функции

F.44.3.1. Скалярные переменные

Следующие функции поддерживают скалярные переменные:

ФункцияВозвращает
pgv_set(package text, name text, value anynonarray, is_transactional bool default false)void
pgv_get(package text, name text, var_type anynonarray, strict bool default true)anynonarray

Для функции pgv_get() вы должны сначала создать пакет и переменную, воспользовавшись функцией pgv_set(). Если указанный пакет или переменная не существуют, происходит ошибка:

SELECT pgv_get('vars', 'int1', NULL::int); ERROR: unrecognized package "vars"
SELECT pgv_get('vars', 'int1', NULL::int); ERROR: unrecognized variable "int1"

Функция pgv_get() проверяет тип переменной. Если заданный тип не соответствует типу переменной, выдаётся ошибка:

SELECT pgv_get('vars', 'int1', NULL::text); ERROR: variable "int1" requires "integer" value

F.44.3.2. Записи

Следующие функции поддерживают наборы переменных типа запись.

ФункцияВозвращаетОписание
pgv_insert(package text, name text, r record, is_transactional bool default false)voidВставляет запись в набор переменных для заданного пакета. Если пакет или переменная не существуют, они создаются автоматически. Первый столбец записи r — первичный ключ. Если запись с таким же первичным ключом уже существует или этот набор переменных имеет другую структуру, выдаётся ошибка.
pgv_update(package text, name text, r record)booleanИзменяет запись с соответствующим первичным ключом (он задаётся в первом столбце r). Возвращает true, если запись была найдена. Если этот набор переменных имеет другую структуру, выдаётся ошибка.
pgv_delete(package text, name text, value anynonarray)booleanУдаляет запись с соответствующим первичным ключом (он задаётся в первом столбце r). Возвращает true, если запись была найдена.
pgv_select(package text, name text)set of recordsВозвращает записи из набора переменных.
pgv_select(package text, name text, value anynonarray)recordВозвращает записи из набора переменных с соответствующими первичными ключами (первичный ключ задаётся в первом столбце r).
pgv_select(package text, name text, value anyarray)set of recordsВозвращает записи из набора переменных с соответствующими первичными ключами (первичный ключ задаётся в первом столбце r).

Для использования функций pgv_update(), pgv_delete() и pgv_select() вы должны сначала создать пакет и переменную, воспользовавшись функцией pgv_insert(). Тип переменной и тип записи должны быть одинаковыми, иначе выдаётся ошибка.

F.44.3.3. Массивы

Следующие функции поддерживают переменные-массивы:

ФункцияВозвращает
pgv_set(package text, name text, value anyarray, is_transactional bool default false)void
pgv_get(package text, name text, var_type anyarray, strict bool default true)anyarray

Инструкции по использованию этих функций совпадают с приведёнными в Подразделе F.44.3.1 для скалярных переменных.

F.44.3.4. Функции разного назначения

ФункцияВозвращаетОписание
pgv_exists(package text, name text)boolВозвращает true, если существует пакет и переменная.
pgv_exists(package text)boolВозвращает true, если существует указанный пакет.
pgv_remove(package text, name text)voidУдаляет переменную с заданным именем. Указанный пакет и переменная должны существовать, иначе выдаётся ошибка.
pgv_remove(package text)voidУдаляет заданный пакет и все его переменные. Указанный пакет должен существовать, иначе выдаётся ошибка.
pgv_free()voidУдаляет все пакеты и переменные.
pgv_list()table(package text, name text, is_transactional bool)Выводит список всех существующих переменных с именем соответствующего пакета и признаком того, что переменная транзакционная.
pgv_stats()table(package text, allocated_memory bigint)Возвращает список созданных пакетов и объём памяти, используемый переменными, в байтах. Если вы используете транзакционные переменные, в этот список также включаются все удалённые пакеты, которые могут быть восстановлены командой ROLLBACK. Эта функция поддерживается только в Postgres Pro версии 9.6 и новее.

F.44.3.5. Устаревшие функции

F.44.3.5.1. Целочисленные переменные

Следующие функции считаются устаревшими. Используйте вместо них универсальные функции для скалярных переменных.

ФункцияВозвращает
pgv_set_int(package text, name text, value int, is_transactional bool default false)void
pgv_get_int(package text, name text, strict bool default true)int
F.44.3.5.2. Текстовые переменные

Следующие функции считаются устаревшими. Используйте вместо них универсальные функции для скалярных переменных.

ФункцияВозвращает
pgv_set_text(package text, name text, value text, is_transactional bool default false)void
pgv_get_text(package text, name text, strict bool default true)text
F.44.3.5.3. Числовые переменные

Следующие функции считаются устаревшими. Используйте вместо них универсальные функции для скалярных переменных.

ФункцияВозвращает
pgv_set_numeric(package text, name text, value numeric, is_transactional bool default false)void
pgv_get_numeric(package text, name text, strict bool default true)numeric
F.44.3.5.4. Переменные даты/времени

Следующие функции считаются устаревшими. Используйте вместо них универсальные функции для скалярных переменных.

ФункцияВозвращает
pgv_set_timestamp(package text, name text, value timestamp, is_transactional bool default false)void
pgv_get_timestamp(package text, name text, strict bool default true)timestamp
F.44.3.5.5. Переменные даты/времени с часовым поясом

Следующие функции считаются устаревшими. Используйте вместо них универсальные функции для скалярных переменных.

ФункцияВозвращает
pgv_set_timestamptz(package text, name text, value timestamptz, is_transactional bool default false)void
pgv_get_timestamptz(package text, name text, strict bool default true)timestamptz
F.44.3.5.6. Переменные даты

Следующие функции считаются устаревшими. Используйте вместо них универсальные функции для скалярных переменных.

ФункцияВозвращает
pgv_set_date(package text, name text, value date, is_transactional bool default false)void
pgv_get_date(package text, name text, strict bool default true)date
F.44.3.5.7. Переменные Jsonb

Следующие функции считаются устаревшими. Используйте вместо них универсальные функции для скалярных переменных.

ФункцияВозвращает
pgv_set_jsonb(package text, name text, value jsonb, is_transactional bool default false)void
pgv_get_jsonb(package text, name text, strict bool default true)jsonb

F.44.4. Примеры

Определение скалярных переменных с помощью функции pgv_set() и получение их значений с помощью pgv_get():

SELECT pgv_set('vars', 'int1', 101); SELECT pgv_set('vars', 'int2', 102); SELECT pgv_set('vars', 'text1', 'text variable'::text); SELECT pgv_get('vars', 'int1', NULL::int); pgv_get ------------- 101 SELECT pgv_get('vars', 'int2', NULL::int); pgv_get ------------- 102 SELECT pgv_get('vars', 'text1', NULL::text); pgv_get --------------- text variable

В предположении, что создана следующая таблица tab, рассмотрите несколько примеров с переменными-записями:

CREATE TABLE tab (id int, t varchar); INSERT INTO tab VALUES (0, 'str00'), (1, 'str11');

Для работы с переменными-записями можно использовать следующие функции:

SELECT pgv_insert('vars', 'r1', tab) FROM tab; SELECT pgv_select('vars', 'r1'); pgv_select ------------ (1,str11) (0,str00) SELECT pgv_select('vars', 'r1', 1); pgv_select ------------ (1,str11) SELECT pgv_select('vars', 'r1', 0); pgv_select ------------ (0,str00) SELECT pgv_select('vars', 'r1', ARRAY[1, 0]); pgv_select ------------ (1,str11) (0,str00) SELECT pgv_delete('vars', 'r1', 1); SELECT pgv_select('vars', 'r1'); pgv_select ------------ (0,str00)

Проанализируйте поведение транзакционной переменной var_text при изменении до и после точки сохранения:

SELECT pgv_set('pack', 'var_text', 'before transaction block'::text, true); BEGIN; SELECT pgv_set('pack', 'var_text', 'before savepoint'::text, true); SAVEPOINT sp1; SELECT pgv_set('pack', 'var_text', 'savepoint sp1'::text, true); SAVEPOINT sp2; SELECT pgv_set('pack', 'var_text', 'savepoint sp2'::text, true); RELEASE sp2; SELECT pgv_get('pack', 'var_text', NULL::text); pgv_get --------------- savepoint sp2 ROLLBACK TO sp1; SELECT pgv_get('pack', 'var_text', NULL::text); pgv_get ------------------ before savepoint ROLLBACK; SELECT pgv_get('pack', 'var_text', NULL::text); pgv_get -------------------------- before transaction block

Если вы создадите транзакционную переменную после команд BEGIN или SAVEPOINT и затем произойдёт откат к предыдущему состоянию, эта переменная будет удалена:

BEGIN; SAVEPOINT sp1; SAVEPOINT sp2; SELECT pgv_set('pack', 'var_int', 122, true); RELEASE SAVEPOINT sp2; SELECT pgv_get('pack', 'var_int', NULL::int); pgv_get --------- 122 ROLLBACK TO sp1; SELECT pgv_get('pack','var_int', NULL::int); ERROR: unrecognized variable "var_int" COMMIT;

Просмотреть имеющиеся пакеты и переменные:

SELECT * FROM pgv_list() ORDER BY package, name; package | name | is_transactional ---------+----------+------------------ pack | var_text | t vars | int1 | f vars | int2 | f vars | r1 | f vars | text1 | f

Получение объёма памяти, занятой переменными, в байтах:

SELECT * FROM pgv_stats() ORDER BY package; package | allocated_memory ---------+------------------ pack | 16384 vars | 32768

Удаление избранных переменных или пакетов:

SELECT pgv_remove('vars', 'int1'); SELECT pgv_remove('vars');

Удаление всех пакетов и переменных:

SELECT pgv_free();

F.44.5. Авторы

Postgres Professional, Москва, Россия

close