F.37. pg_variables
Модуль pg_variables
содержит функции для работы с переменными различных типов. Созданные переменные существуют в течение текущей пользовательской сессии.
F.37.1. Установка
Расширение pg_variables
включено в состав Postgres Pro. Установив Postgres Pro, вы должны выполнить команду CREATE EXTENSION, чтобы подготовить pg_variables
к работе, следующим образом:
CREATE EXTENSION pg_variables;
F.37.2. Использование
Модуль pg_variables
содержит функции, позволяющие создавать переменные скалярных типов, переменные-записи и переменные-массивы, читать их и управлять ими. Синтаксис и описания функций представлены в следующих разделах:
В Подразделе F.37.3.1 описываются функции для скалярных переменных.
В Подразделе F.37.3.2 описываются функции для переменных-записей.
В Подразделе F.37.3.3 описываются функции для переменных-массивов.
В Подразделе F.37.3.4 перечисляются функции, позволяющие управлять всеми переменными в текущем сеансе.
Разобранные примеры использования вы можете найти в Подразделе F.37.4.
F.37.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.37.3. Функции
F.37.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.37.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()
and pgv_select()
вы должны сначала создать пакет и переменную, воспользовавшись функцией pgv_insert()
. Тип переменной и тип записи должны быть одинаковыми, иначе выдаётся ошибка.
F.37.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.37.3.1 для скалярных переменных.
F.37.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.37.3.5. Устаревшие функции
F.37.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.37.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.37.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.37.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.37.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.37.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.37.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.37.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.37.5. Авторы
Postgres Professional, Москва, Россия