F.59. pg_variables#
F.59. pg_variables #
F.59.2. Введение #
Модуль pg_variables предоставляет функции для работы с переменными различных типов. Созданные переменные существуют только в текущей пользовательской сессии. По умолчанию, созданные переменные не являются транзакционными (т.е. они не затрагиваются операторами BEGIN, COMMIT или ROLLBACK). Однако это можно настроить с помощью аргумента is_transactional функции pgv_set():
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
Вы можете агрегировать переменные в пакеты. Это делается для того, чтобы иметь переменные с разными именами или быстро удалить весь пакет переменных. Если пакет становится пустым, он автоматически удаляется.
F.59.4. Функции модуля #
Функции, предоставляемые модулем pg_variables, показаны в таблицах ниже.
Чтобы использовать функцию pgv_get(), необходимый пакет и переменная должны существовать. Необходимо установить переменную с помощью функции pgv_set(), чтобы использовать функцию pgv_get().
Если пакет не существует, вы получите следующую ошибку:
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.59.5. Функции скалярных переменных #
| Функция | Возвращает |
|---|---|
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
|
F.59.6. Функции массивов переменных #
| Функция | Возвращает |
|---|---|
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
|
pgv_set аргументы:
package- имя пакета, он будет создан, если не существует.name- имя переменной, она будет создана, если не существует.pgv_setзавершится с ошибкой, если переменная уже существует и её транзакционность не соответствует аргументуis_transactional.value- новое значение для переменной.pgv_setзавершится с ошибкой, если переменная уже существует и её тип не соответствует типу нового значения.is_transactional- транзакционность вновь созданной переменной, по умолчанию false.
pgv_get аргументы:
package- имя существующего пакета. Если пакет не существует, результат зависит от аргументаstrict: если он ложный, тоpgv_getвозвращает NULL, в противном случае происходит ошибка.name- имя существующей переменной. Если переменная не существует, результат зависит от аргументаstrict: если он ложный, тоpgv_getвозвращает NULL, в противном случае происходит ошибка.var_type- тип существующей переменной. Это необходимо для получения правильного возвращаемого типа.strict- передайте false, еслиpgv_getне должен вызывать ошибку, если переменная или пакет не были созданы ранее, по умолчанию это true.
F.59.7. Устаревшие функции скалярных переменных #
F.59.7.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.59.7.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)
|
текст
|
F.59.7.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)
|
числовой
|
F.59.7.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)
|
метка времени
|
F.59.7.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.59.7.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)
|
дата
|
F.59.7.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.59.8. Функции переменных записи #
Следующие функции предоставляются модулем для работы с коллекциями типов записей.
Чтобы использовать функции pgv_update(), pgv_delete() и pgv_select(), необходимы существующие пакет и переменная. В противном случае будет вызвана ошибка. Необходимо установить переменную с помощью функции pgv_insert() для использования этих функций.
pgv_update(), pgv_delete() и pgv_select() функции проверяют тип переменной. Если тип переменной не record, будет вызвана ошибка.
Таблица F.29. Функции переменных записей
|
Функция |
Возвращает |
Описание |
|---|---|---|
|
pgv_insert(package text, name text, r record, is_transactional bool default false) |
пусто |
Вставляет запись в коллекцию переменных. Если пакет и переменная не существуют, они будут созданы. Первый столбец r будет первичным ключом. Если существует запись с таким же первичным ключом, будет вызвана ошибка. Если эта коллекция переменных имеет другую структуру, будет вызвана ошибка. |
|
pgv_update(package text, name text, r record) |
логическое значение |
Обновляет запись с соответствующим первичным ключом (первый столбец r является первичным ключом). Возвращает true, если запись была найдена. Если эта коллекция переменных имеет другую структуру, будет вызвана ошибка. |
|
pgv_delete(package text, name text, value anynonarray) |
логическое значение |
Удаляет запись с соответствующим первичным ключом (первый столбец r является первичным ключом). Возвращает true, если запись была найдена. |
|
pgv_select(package text, name text) |
set of record |
Возвращает записи коллекции переменных. |
|
pgv_select(package text, name text, value anynonarray) |
запись |
Возвращает запись с соответствующим первичным ключом (первая колонка r является первичным ключом). |
|
pgv_select(package text, name text, value anyarray) |
set of record |
Возвращает записи коллекции переменных с соответствующими первичными ключами (первый столбец r является первичным ключом). |
F.59.8.1. Различные функции #
Таблица F.30. Различные функции
|
Функция |
Возвращает |
Описание |
|---|---|---|
|
pgv_exists(package text, name text) |
bool |
Возвращает true, если пакет и переменная существуют. |
|
pgv_exists(package text) |
bool |
Возвращает true, если пакет существует. |
|
pgv_remove(package text, name text) |
пусто |
Удаляет переменную с соответствующим именем. Требуется наличие пакета и переменной, в противном случае будет вызвана ошибка. |
|
pgv_remove(package text) |
пусто |
Удаляет пакет и все переменные пакета с соответствующим именем. Требуемый пакет должен существовать, в противном случае будет вызвана ошибка. |
|
pgv_free() |
пусто |
Удаляет все пакеты и переменные. |
|
pgv_list() |
таблица (package text, name text, is_transactional bool) |
Возвращает набор записей назначенных пакетов и переменных. |
|
pgv_stats() |
таблица (package text, allocated_memory bigint) |
Возвращает список назначенных пакетов и используемую память в байтах. |
F.59.9. Примеры #
Использование функций для работы с скалярными и массивными переменными очень просто:
SELECT pgv_set('vars', 'int1', 101);
SELECT pgv_set('vars', 'text1', 'text variable'::text);
SELECT pgv_get('vars', 'int1', NULL::int);
pgv_get_int
-------------
101
SELECT SELECT pgv_get('vars', 'text1', NULL::text);
pgv_get
---------------
text variable
SELECT pgv_set('vars', 'arr1', '{101,102}'::int[]);
SELECT pgv_get('vars', 'arr1', NULL::int[]);
pgv_get
-----------
{101,102}
Предположим, у нас есть таблица 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)
Вы можете перечислить пакеты и переменные:
SELECT * FROM pgv_list() order by package, name; package | name | is_transactional ---------+-------+------------------ vars | arr1 | f vars | int1 | f vars | r1 | f vars | text1 | f
И получить использованную память в байтах:
SELECT * FROM pgv_stats() order by package; package | allocated_memory ---------+------------------ vars | 49152
Вы можете удалить переменные или целые пакеты:
SELECT pgv_remove('vars', 'int1');
SELECT pgv_remove('vars');
Вы можете удалить все пакеты и переменные:
SELECT pgv_free();
Если вы хотите использовать переменные с поддержкой транзакций и точек сохранения,
вы должны добавить флаг is_transactional = true в качестве
последнего аргумента в функции pgv_set() или
pgv_insert(). Следующие случаи использования описывают
поведение транзакционных переменных:
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;
Вы можете отменить удаление транзакционной переменной с помощью
ROLLBACK, но если вы удалите весь пакет,
все обычные переменные будут удалены навсегда:
SELECT pgv_set('pack', 'var_reg', 123);
SELECT pgv_set('pack', 'var_trans', 456, true);
BEGIN;
SELECT pgv_free();
SELECT * FROM pgv_list();
package | name | is_transactional
---------+------+------------------
(0 rows)
-- Memory is allocated yet
SELECT * FROM pgv_stats();
package | allocated_memory
---------+------------------
pack | 24576
ROLLBACK;
SELECT * FROM pgv_list();
package | name | is_transactional
---------+-----------+------------------
pack | var_trans | t
Если вы создали транзакционную переменную один раз, вы должны использовать флаг
is_transactional каждый раз, когда хотите
изменить значение переменной с помощью функций pgv_set(),
pgv_insert() и устаревших установщиков
(например, pgv_set_int()). Если вы попытаетесь изменить эту
опцию, вы получите ошибку:
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
Функции pgv_update() и
pgv_delete() не требуют этого флага.