我会尽力用英语解释我的问题。 我创建了一个名为Laboratory的数据库,我想控制用户何时插入,删除或更新表。我将此表称为“tablaLog”。
基本上tablaLog由触发器更新。它保存有关谁更改了确定的表,旧数据,新数据,日期,用户和pid的信息。 这就是我遇到问题的地方。 pid就是问题所在。我们的老师说,当我们说插入时(使用php格式),我们应该在表“detalle_sesion”上查找它的pid,这样我们现在可以进行更改。这是我为此写的函数:
CREATE OR REPLACE FUNCTION escuchar_cliente()
RETURNS trigger AS
$BODY$
DECLARE
res integer;
p int;
BEGIN
p = pg_backend_pid();
SELECT pid
INTO res
FROM detalle_sesion
WHERE pid = p;
IF res IS NOT NULL THEN
DECLARE
cod int;
nombre character varying(20);
BEGIN
SELECT cod_usuario
INTO cod
FROM detalle_sesion
WHERE pid = p;
SELECT login
INTO nombre
FROM usuarios
WHERE cod = cod_usuario;
IF (TG_OP = 'DELETE') THEN
INSERT INTO tablaLog (fecha, datoviejo, datonuevo, operacion, usuario, tabla, cod_tabla, cod_usuario)
VALUES(now(), OLD.*, null, 'eliminar', nombre, 'Cliente', default, cod);
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
INSERT INTO tablaLog (fecha, datoviejo, datonuevo, operacion, usuario, tabla, cod_tabla, cod_usuario)
VALUES(now(), OLD.*, NEW.*, 'actualizar', nombre, 'Cliente', default, cod);
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
INSERT INTO tablaLog (fecha, datoviejo, datonuevo, operacion, usuario, tabla, cod_tabla, cod_usuario)
VALUES(now(), null, NEW.*, 'insertar', nombre, 'Cliente', default, cod);
RETURN NEW;
END IF;
RETURN NULL;
END;
END IF;
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql
我可以说这个函数不能正常工作......我在tablaLog上没有任何阻碍。有些同学有同样的问题,他们说是由于pid,每次查询时都会生成一个新的pid,并且它与“detalle_sesion”中保存的pid不同。
每次用户登录时,名为“detalle_sesion”的表都会更新[cod_usuario,cod_sesion,ingreso,salida,pid]以下是表格的更新方式。
CREATE OR REPLACE FUNCTION detallesesion(logi character varying, pass character varying)
RETURNS boolean AS
$BODY$
DECLARE
res character varying (20);
pid int;
cod int;
BEGIN
SELECT cod_usuario
INTO res
FROM usuarios
WHERE login = logi AND password = pass;
IF res IS NOT NULL THEN
DECLARE
cod int;
pid int;
bs timestamp with time zone;
qs timestamp with time zone;
BEGIN
cod := CAST(res AS integer);
pid = pg_backend_pid();
SELECT backend_start, query_start
INTO bs, qs
FROM pg_stat_activity
WHERE procpid = pid;
INSERT INTO detalle_sesion(cod_usuario, cod_sesion, ingreso, salida, pid)
VALUES (cod, default, bs, qs, pid);
RETURN(TRUE);
END;
ELSE
RETURN(FALSE);
END IF;
END;
$BODY$
LANGUAGE plpgsql
关于php,我有下一个: conexion.php
<?php
$conexion = pg_connect("host=localhost
port=5432
user=postgres
password=postgres
dbname=labo") or
die ("no se pudo conectar".pg_last_error());
?>
manejadorDB.php所有带查询的函数都在这里。
<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
require_once "../funciones/conexion.php";
class manejadorDB
{
所以我问是否有办法在用户登录后保留相同的pid。或者可能采用不同的方式来更新“tablaLog”
答案 0 :(得分:0)
pg_backend_pid()
返回的值对于通过pg_connect()
进行的任何新连接都会有所不同,假设中间没有连接池。
同样在某些时候,这个值将会循环,Unix下的进程ID(实际上它是一个进程ID)也是如此,这意味着新会话将具有相同的pid
无关的断开旧会话。
因此,这个pid
单独作为来自Web客户端的持久会话标识符并不合适。如果有一个要登录的页面和其他页面,那么每个页面的pid
都会有所不同。
您仍然可以使用触发器中的pid
来查找会话,但您需要先建立一个在页面之间保留的session in php。当用户登录时,应将唯一会话ID插入detalle_sesion
。然后,在每次pg_connect
调用后,detalle_sesion
中唯一对应的行应使用新pid
进行更新这样触发器就可以找到它。
此外,由于pid
被重复使用,仅pid
是不够的。 pid
和backend_start
的组合会更好,因为这种组合在任何时间段都是独一无二的。