Определение идентификатора соединения в Postgres - PullRequest
6 голосов
/ 21 февраля 2011

У меня есть база данных Postgres (9), для которой я пишу триггер.Я хочу, чтобы триггер установил время модификации и идентификатор пользователя для записи.В Firebird у вас есть CONNECTIONID, который вы можете использовать в триггере, чтобы вы могли добавить значение в таблицу при подключении к базе данных (это приложение для настольного компьютера, поэтому соединения сохраняются на протяжении всего срока службы приложения), что-то вродеэто:

UserId | ConnectionId
---------------------
544    | 3775

, а затем найдите в триггере, что connectionid 3775 принадлежит идентификатору пользователя 544 и используйте 544 в качестве пользователя, который изменил запись.

Есть ли что-нибудь подобное, что я могу использовать вPostgres?

Ответы [ 4 ]

8 голосов
/ 21 февраля 2011

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

pg_backend_pid()

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

Или лучше. Просто создайте серийный номер и извлеките из него одно значение для каждого соединения:

CREATE SEQUENCE 'connectionids';

А потом:

SELECT next_val('connectionids');

в каждом соединении, чтобы получить уникальный идентификатор соединения.

5 голосов
/ 22 февраля 2011

Одним из способов является использование опции конфигурации custom_variable_classes.Похоже, что он предназначен для конфигурации дополнительных модулей, но также может использоваться для хранения произвольных значений в текущем сеансе базы данных.

Что-то вроде следующего необходимо добавить к postgresql.conf:

custom_variable_classes = 'local'

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

SET local.userid = 'foobar';

И позже вы можете получить этозначение с помощью функции current_setting():

SELECT current_setting('local.userid');

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

INSERT INTO audit_log VALUES (now(), current_setting('local.userid'), ...)
1 голос
/ 22 февраля 2011

Несмотря на то, что это может работать в вашем случае использования на настольном компьютере, обратите внимание, что номера идентификаторов процессов имеют ролловер (32768 - это общий верхний предел), поэтому использование их в качестве уникального ключа для идентификации пользователя может привести к проблемам.Если вам когда-нибудь понадобятся оставшиеся данные из предыдущего сеанса в таблице, которая отслеживает сопоставление пользователя-> процесса, это может привести к конфликту с более новыми соединениями, которым назначен тот же идентификатор процесса после его пролонгации.Для вашего приложения может быть достаточно просто убедиться, что вы агрессивно удаляете старые записи сопоставления, возможно, во время запуска, учитывая то, как вы описали его работу.

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

SELECT procpid,backend_start FROM pg_stat_activity WHERE procpid=pg_backend_pid();

. Он должен перебирать все соединения, активные в данный момент для вычисления, поэтому он добавляет немного накладных расходов.,Можно выполнить это несколько эффективнее, начиная с PostgreSQL 8.4:

SELECT procpid,backend_start FROM pg_stat_get_activity(pg_backend_pid());

Но это действительно имеет значение, только если у вас одновременно активно большое количество соединений.

0 голосов
/ 22 февраля 2011

Используйте current_user, если вам нужен пользователь базы данных (я не уверен, что вы этого хотите, прочитав ваш вопрос).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...