如何在postgresql中为触发器插入自动增量值?
how to insert auto increment value for trigger in postgresql?
这是来自 plpgsql -
的触发器
CREATE TABLE emp (
empname text NOT NULL,
salary integer
);
CREATE TABLE emp_audit(
operation char(1) NOT NULL,
stamp timestamp NOT NULL,
userid text NOT NULL,
empname text NOT NULL,
salary integer
);
CREATE OR REPLACE FUNCTION process_emp_audit() RETURNS TRIGGER AS $emp_audit$
BEGIN
--
-- Create a row in emp_audit to reflect the operation performed on emp,
-- make use of the special variable TG_OP to work out the operation.
--
IF (TG_OP = 'DELETE') THEN
INSERT INTO emp_audit SELECT 'D', now(), user, OLD.*;
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
INSERT INTO emp_audit SELECT 'U', now(), user, NEW.*;
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
INSERT INTO emp_audit SELECT 'I', now(), user, NEW.*;
RETURN NEW;
END IF;
RETURN NULL; -- result is ignored since this is an AFTER trigger
END;
$emp_audit$ LANGUAGE plpgsql;
CREATE TRIGGER emp_audit
AFTER INSERT OR UPDATE OR DELETE ON emp
FOR EACH ROW EXECUTE PROCEDURE process_emp_audit();
现在我想在 emp_audit
table 中再添加一列,这是一个主键,比如 emp_audit_id
-
所以现在上面的 SELECT 查询中应该出现什么,以便它也可以处理 PRIMARY KEY emp_audit_id
。
由于你不想在INSERT
语句中写出字段列表(其他读者:见下面的评论),你需要使用常规integer
作为PRIMARY KEY
和一个手动创建的序列。
首先修改emp_audit
table定义:
ALTER TABLE emp_audit ADD COLUMN emp_audit_id integer PRIMARY KEY
创建序列:
CREATE SEQUENCE seq_empaudit_pk;
在 INSERT
语句中,添加序列中的下一个值:
IF (TG_OP = 'DELETE') THEN
INSERT INTO emp_audit SELECT 'D', now(), user, OLD.*, nextval(seq_empaudit_pk);
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
INSERT INTO emp_audit SELECT 'U', now(), user, NEW.*, nextval(seq_empaudit_pk);
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
INSERT INTO emp_audit SELECT 'I', now(), user, NEW.*, nextval(seq_empaudit_pk);
RETURN NEW;
END IF;
确保在更改 table 后验证字段的顺序,并严格按照该顺序在 SELECT
查询中列出字段。
这是来自 plpgsql -
的触发器CREATE TABLE emp (
empname text NOT NULL,
salary integer
);
CREATE TABLE emp_audit(
operation char(1) NOT NULL,
stamp timestamp NOT NULL,
userid text NOT NULL,
empname text NOT NULL,
salary integer
);
CREATE OR REPLACE FUNCTION process_emp_audit() RETURNS TRIGGER AS $emp_audit$
BEGIN
--
-- Create a row in emp_audit to reflect the operation performed on emp,
-- make use of the special variable TG_OP to work out the operation.
--
IF (TG_OP = 'DELETE') THEN
INSERT INTO emp_audit SELECT 'D', now(), user, OLD.*;
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
INSERT INTO emp_audit SELECT 'U', now(), user, NEW.*;
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
INSERT INTO emp_audit SELECT 'I', now(), user, NEW.*;
RETURN NEW;
END IF;
RETURN NULL; -- result is ignored since this is an AFTER trigger
END;
$emp_audit$ LANGUAGE plpgsql;
CREATE TRIGGER emp_audit
AFTER INSERT OR UPDATE OR DELETE ON emp
FOR EACH ROW EXECUTE PROCEDURE process_emp_audit();
现在我想在 emp_audit
table 中再添加一列,这是一个主键,比如 emp_audit_id
-
所以现在上面的 SELECT 查询中应该出现什么,以便它也可以处理 PRIMARY KEY emp_audit_id
。
由于你不想在INSERT
语句中写出字段列表(其他读者:见下面的评论),你需要使用常规integer
作为PRIMARY KEY
和一个手动创建的序列。
首先修改emp_audit
table定义:
ALTER TABLE emp_audit ADD COLUMN emp_audit_id integer PRIMARY KEY
创建序列:
CREATE SEQUENCE seq_empaudit_pk;
在 INSERT
语句中,添加序列中的下一个值:
IF (TG_OP = 'DELETE') THEN
INSERT INTO emp_audit SELECT 'D', now(), user, OLD.*, nextval(seq_empaudit_pk);
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
INSERT INTO emp_audit SELECT 'U', now(), user, NEW.*, nextval(seq_empaudit_pk);
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
INSERT INTO emp_audit SELECT 'I', now(), user, NEW.*, nextval(seq_empaudit_pk);
RETURN NEW;
END IF;
确保在更改 table 后验证字段的顺序,并严格按照该顺序在 SELECT
查询中列出字段。