2017-06-30 1 views
0

Ich benutze Postgres. Sagen wir, ich werde folgende Trigger erstellen:Wie erhalten Sie den Primärschlüsselwert in der Triggerfunktion, wenn der Primärschlüsselspaltenname nicht bekannt ist?

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; 

ich mit vielen Tabellen diesen Trigger verwenden möchten, und nicht jede Tabelle Primärschlüssel mit dem Namen ‚id‘ hat (Tabelle keine ‚id‘ Spalte haben kann alle). Also muss ich in irgendeiner Weise herausfinden, wie ich den Primärschlüssel in meiner Triggerfunktion verwenden kann, egal welchen Spaltennamen er hat. Wie kann ich das erreichen?

+0

Ich glaube, Sie würden es für jede Tabelle dynamisch generieren information_schema.columns mit den Tasten zu identifizieren .. – JeffUK

+1

See [hier] (http://8kb.co.uk/blog/2015/01/19/Kopieren-Pavel-Stehules-Simple-Geschichte-Tabelle-aber-mit-der-Jsonb-Typ /) oder [hier] (http://okbob.blogspot.co.uk/2015/01/most-simply -implementation-of-history.html) für zwei Lösungen für einen generischen Audit-Trigger –

Antwort

0

Wie lautet Ihre PostgreSQL-Version? Sie müssen den PostgreSQL-Katalog abfragen, um zu erreichen, was Sie wollen. Siehe Skript unten:

Ich nehme an, dass Ihr PostgreSQL JSONB Unterstützung (9.4 +) hat.

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'); 
Verwandte Themen