2015-12-14 31 views
0

我正在使用PostgreSQL 8.1,并且我为表创建了一个触发器,所以如果有事情被更新或插入,它也会在日志表中注册,但我遇到了问题与NULL值:PostgreSQL触发器不会插入审计值

如果我更新一个NULL值的列,那么它不会插入任何值的日志,但与字符char将罚款,所以也许我失去了一些东西。

CREATE FUNCTION "public"."log_test_trigger"() RETURNS "trigger" AS 'BEGIN 
... 
    IF (TG_OP = ''UPDATE'') THEN 
      IF (NEW.name <> OLD.name) THEN 
        INSERT INTO log_test (type, table, field, old_val, new_val, user, event) VALUES (NEW.type, TG_RELNAME, ''name'', OLD.name, NEW.name, NEW.user, ''UPDATE''); 
      END IF; 
... 
END;' LANGUAGE "plpgsql" 
VOLATILE 
CALLED ON NULL INPUT 
SECURITY INVOKER 

任何帮助:

CREATE TABLE log_test(

    id_test   integer NOT NULL DEFAULT nextval('id_test_seq'), 
    type   char(3), 
    product   char(10), 
    table    char(15), 
    field   char(10), 
    old_val   char(10), 
    new_val   char(10), 
    user   char(10), 
    event   char(10), 
    date   timestamp with time zone  NOT NULL DEFAULT now(), 
CONSTRAINT "log_test_prim" PRIMARY KEY ("id_test") 
); 

触发当时想创建:

该表是这样产生的?

回答

1

您无法将NULL与某个值进行比较,即NULL = 2NULL <> 2均为NULL。添加ISNULL

... 
IF (TG_OP = ''UPDATE'') THEN 
    IF (NEW.name <> OLD.name OR NEW.name ISNULL) THEN 
     INSERT INTO log_test (type, table, field, old_val, new_val, user, event) VALUES (NEW.type, TG_RELNAME, ''name'', OLD.name, NEW.name, NEW.user, ''UPDATE''); 
    END IF; 
... 

或(可能更好)coalesce()两个NEWOLD记录:

... 
IF (TG_OP = ''UPDATE'') THEN 
    IF (coalesce(NEW.name, '') <> coalesce(OLD.name, '')) THEN 
     INSERT INTO log_test (type, table, field, old_val, new_val, user, event) VALUES (NEW.type, TG_RELNAME, ''name'', OLD.name, NEW.name, NEW.user, ''UPDATE''); 
    END IF; 
... 
+0

你是完全正确的。我想到了COALESCE的功能,但错过了比较。 – Motheus

+0

哦......整数和日期值呢? – Motheus

+0

你可以使用'coalesce()'作为任何简单的类型。只选择适当的默认值(函数的最后一个参数)。 – klin