Trouble with single trigger using UUID as key, should I use twotriggers?

Поиск
Список
Период
Сортировка
От Jason Aleski
Тема Trouble with single trigger using UUID as key, should I use twotriggers?
Дата
Msg-id 456d6fa7-0ade-4ceb-195b-77c37818c02f@gmail.com
обсуждение исходный текст
Список pgsql-sql

I'm running into a foreign key constraint when running a BEFORE trigger for audit purposes.  My initial goal was to do this in one BEFORE trigger, but I'm leaning towards executing using two different triggers.  I'm seeking a second opinion!  My initial thought was creating a trigger that runs before the data is written to the primary table; specifically on updates, as I want to increment the version_count before the data is written to the primary table.  Because the audit_id (UUID generated) has not been written to the primary table, I get a foreign key constraint problem when it tries to first write to the audit table.  I understand the error is because audit_id doesn't exist in the primary table.  If I were using a SERIAL/SEQUENCE, I could use the NEXTVAL function; but I need to use UUID the key and audit_id.

Knowing that, I think my only option is to create an AFTER trigger for the INSERT.  Then create a BEFORE trigger when doing UPDATES and DELETES.  Before I go this path, I through I'd see if anyone has any additional options I should consider; or would this be the suggested path?  Thoughts?

-JA-


--Example INSERT
INSERT INTO departments (department_
legacyid, department_name) VALUES ('ACT', 'Accounting');
INSERT INTO departments (department_
legacyid, department_name) VALUES ('HRM', 'Human Resources');
INSERT INTO departments (department_
legacyid, department_name) VALUES ('CSR', 'Customer Service');

--ERROR
ERROR: insert or update on table "departments_audit" violates foreign key constraint "departments_audit_audit_id_fkey" DETAIL: Key (audit_id)=(241451bd-796e-5add-95b0-18f6098bc08f) is not present in table "departments". CONTEXT: SQL statement "INSERT INTO departments_audit (audit_id, audit_lastaction, department_legacyid, department_name ) VALUES (NEW.audit_id, 'INSERT', NEW.department_legacyid, NEW.department_name )" PL/pgSQL function process_departments_audit() line 10 at SQL statement SQL state: 23503--Primary Table
CREATE TABLE IF NOT EXISTS departments (

  row_id                UUID NOT NULL DEFAULT uuid_generate_v5(uuid_ns_dns(), 'location1.local'),

  row_created           TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,

  audit_id              UUID NOT NULL DEFAULT uuid_generate_v5(uuid_ns_dns(), 'location1.local'),
  version_count         INTEGER NOT NULL DEFAULT 1,
  version_timestamp    
TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
  department_legacyid   VARCHAR(255) NOT NULL,

  department_name       VARCHAR(255) NOT NULL,

  PRIMARY KEY (row_id)

);

--Creating index on audit_ID to ensure there is only one unique record in primary table
CREATE UNIQUE INDEX departments_ref_idx ON departments(audit_id);

--Audit Table
CREATE TABLE IF NOT EXISTS departments_audit (

  row_id                UUID NOT NULL DEFAULT uuid_generate_v5(uuid_ns_dns(), 'location1.local'),
  row_created           TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
  audit_id              UUID NOT NULL DEFAULT
uuid_generate_v5(uuid_ns_dns(), 'location1.local'),
  audit_lastaction      CHARACTER VARYING DEFAULT 'NOT DEFINED',
  
  version_count         INTEGER NOT NULL DEFAULT 1,

 
version_timestamp     TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
  department_legacyid   VARCHAR(255) NOT NULL,
  department_name       VARCHAR(255) NOT NULL,
  PRIMARY KEY (row_id),
  FOREIGN KEY (audit_id) REFERENCES departments(audit_id)
);

-- Creating audit trigger for departments
CREATE OR REPLACE FUNCTION process_departments_audit() RETURNS TRIGGER AS $departments_audit$
  BEGIN
    IF (TG_OP = 'DELETE') THEN
      --Nothing yet
    ELSEIF (TG_OP = 'UPDATE') THEN
      --Nothing yet
      NEW.version_count = OLD.version_count + 1;
    ELSEIF (TG_OP = 'INSERT') THEN     
      INSERT INTO departments_audit (audit_id,
                                     audit_lastaction,
                                     department_legacyid,
                                     department_name
                                    )
                             VALUES (NEW.audit_id,
                                     'INSERT',
                                     NEW.department_legacyid,
                                     NEW.department_name
                                    );
    END IF;   
    RETURN NULL;
  END;
$departments_audit$ LANGUAGE plpgsql;

--Applying trigger BEFORE data is written to primary table
CREATE TRIGGER department_audit
  BEFORE INSERT OR UPDATE OR DELETE ON departments
    FOR EACH ROW EXECUTE PROCEDURE process_departments_audit();



В списке pgsql-sql по дате отправления:

Предыдущее
От: Stanton Schmidt
Дата:
Сообщение: Re: Query question
Следующее
От: abctevez
Дата:
Сообщение: does the notification of postgres appear in transaction completedorder