postgres和php:控制对表的更改

时间:2013-10-21 01:29:43

标签: php sql postgresql

我会尽力用英语解释我的问题。 我创建了一个名为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”

1 个答案:

答案 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是不够的。 pidbackend_start的组合会更好,因为这种组合在任何时间段都是独一无二的。