我正在使用 postgres。假设我要创建以下触发器:
CREATE OR REPLACE FUNCTION auditlogfunc() RETURNS TRIGGER AS $example_table$
BEGIN
INSERT INTO AUDIT(EMP_ID, ENTRY_DATE) VALUES (new.ID, current_timestamp);
RETURN NEW;
END;
$example_table$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
我想对许多表使用这个触发器,并不是每个表都有名为“id”的主键(表可以根本没有“id”列)。所以我需要以某种方式找出如何在我的触发器函数中使用主键,无论它有哪个列名。我怎样才能做到这一点?
What's your PostgreSQL version? You must query PostgreSQL catalog to achieve what you want. See script below:
I'm assuming that your PostgreSQL has JSONB support (9.4+).
CREATE TABLE public.test_table
(
id BIGINT NOT NULL,
a_column TEXT NOT NULL,
CONSTRAINT test_tablepkey PRIMARY KEY (id)
);
CREATE OR REPLACE FUNCTION auditlogfunc() RETURNS TRIGGER AS $example_table$
DECLARE
reg_id JSONB;
affected_row JSON;
BEGIN
IF TG_OP IN('INSERT', 'UPDATE') THEN
affected_row := row_to_json(NEW);
ELSE
affected_row := row_to_json(OLD);
END IF;
--Get PK columns
--You may want to extract this to a SQL function
WITH pk_columns (attname) AS (
SELECT
CAST(a.attname AS TEXT)
FROM
pg_index i
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
WHERE
i.indrelid = TG_RELID
AND i.indisprimary
)
SELECT
json_object_agg(key, value) INTO reg_id
FROM
json_each_text(affected_row)
WHERE
key IN(SELECT attname FROM pk_columns);
--Raise collected PK
RAISE INFO 'PK: %', reg_id;
--TODO: your insert into audit table goes here
RETURN NEW;
END;
$example_table$ LANGUAGE plpgsql;
CREATE TRIGGER tg_audit_cadprodu_row AFTER INSERT OR UPDATE OR DELETE
ON public.test_table FOR EACH ROW EXECUTE PROCEDURE public.auditlogfunc();
--A simple test
INSERT INTO test_table VALUES (CAST((random() * 10000) AS INTEGER), 'Test');
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2184 次 |
| 最近记录: |