Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 在Postgres中标识连接ID_Delphi_Postgresql_Database Connection - Fatal编程技术网

Delphi 在Postgres中标识连接ID

Delphi 在Postgres中标识连接ID,delphi,postgresql,database-connection,Delphi,Postgresql,Database Connection,我有一个Postgres数据库(9),我正在为它编写触发器。我希望触发器为记录设置修改时间和用户id。在Firebird中,您有一个可以在触发器中使用的CONNECTIONID,因此您可以在连接到数据库时向表中添加一个值(这是一个桌面应用程序,因此连接在应用程序的整个生命周期内都是持久的),如下所示: UserId | ConnectionId --------------------- 544 | 3775 INSERT INTO audit_log VALUES (now(), cur

我有一个Postgres数据库(9),我正在为它编写触发器。我希望触发器为记录设置修改时间和用户id。在Firebird中,您有一个可以在触发器中使用的CONNECTIONID,因此您可以在连接到数据库时向表中添加一个值(这是一个桌面应用程序,因此连接在应用程序的整个生命周期内都是持久的),如下所示:

UserId | ConnectionId --------------------- 544 | 3775
INSERT INTO audit_log VALUES (now(), current_setting('local.userid'), ...)
用户ID |连接ID --------------------- 544 | 3775 然后在触发器中查找connectionid 3775属于用户ID 544,并使用544作为修改记录的用户


我可以在Postgres中使用类似的东西吗?

您可以使用进程id。它可以通过以下方式检索:

pg_backend_pid()
有了这个pid,您还可以使用表pg_stat_活动来获取关于当前后端的更多信息,尽管您应该已经知道了一切,因为您正在使用这个后端

或者更好。只需创建一个串行,并从中为每个连接检索一个值:

CREATE SEQUENCE 'connectionids';
然后:

SELECT next_val('connectionids');

在每个连接中,检索一个唯一的连接id。

如果需要数据库用户,请使用它(通过阅读您的问题,我不确定这是否是您想要的)。

虽然它可能适用于您的桌面用例,但请注意进程id号会进行滚动(32768是一个常见的上限),因此,使用它们作为识别用户的唯一密钥可能会遇到问题。如果您在跟踪用户->进程映射的表中使用了上一个会话的剩余数据,那么一旦回滚,它可能会与分配了相同进程id的新连接发生冲突。您的应用程序只需确保您积极清除旧映射条目就足够了,考虑到您对其操作的描述,可能在启动时就可以了

一般来说,要避免此问题,您需要创建一个包含额外信息的连接密钥,例如会话启动时:

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

但是,只有当一次有大量连接处于活动状态时,这才真正重要。

一种方法是使用
自定义变量\u类
配置选项。它的设计似乎允许配置附加模块,但也可用于在当前数据库会话中存储任意值

需要将以下内容添加到
postgresql.conf

custom_variable_classes = 'local'
首次连接到数据库时,可以在自定义类中存储所需的任何信息,如下所示:

SET local.userid = 'foobar';
稍后,您可以使用
current\u setting()
函数检索此值:

SELECT current_setting('local.userid');
将条目添加到日志表可能如下所示:

UserId | ConnectionId --------------------- 544 | 3775
INSERT INTO audit_log VALUES (now(), current_setting('local.userid'), ...)

谢谢Daniel,但是我检查了这个,并且在连接到数据库的生命周期中,它发生了变化。我需要一些不变的东西,这不变!如果是这样,你就不会真正使用相同的连接。检查,如果您有一个连接池,并且正在意外地从中检索连接!谢谢Daniel,我使用EMS Studio进行Postgres,我在那里查看了这个,每次打开一个新的查询窗口,我都会得到一个新的结果。我假设每笔交易都会发生变化。也许EMS会为每个查询窗口打开一个新连接?我将建立一个测试应用程序与连接我控制,并检查出来,让你知道它是否工作。你的顺序想法行不通,我需要像pid一样的东西,我可以读取每个连接。我可以创建一个序列,但如何在触发器中关联它。希望PID交易能起作用,我会尽快让你知道。pg_backend_PID()(不确定pg_get_PID()来自哪里?)肯定能识别连接。每个查询窗口使用一个连接听起来很有道理-mssql enterprise manager、toad等可以这样工作(默认情况下),感谢您的建议,但我对所有连接都使用同一个用户,并且在数据库中有一个内部定义的用户表,因此这不起作用。不再需要自定义变量类。看见