Du kan bruge format()
for at gøre oprettelsen af en dynamisk SQL-forespørgsel meget nemmere, da den automatisk vil håndtere identifikatorer og bogstaver korrekt. En ting, som folk normalt overser, er, at du kan udvide et enkelt postudtryk til alle dets kolonner ved hjælp af (...).*
- dette virker også for NEW
og OLD
registrere variable i en trigger, f.eks. select (new).*
Du kan også sende variabler til en dynamisk SQL med using
nøgleordet for execute
udmelding. Det er ikke nødvendigt at konvertere posten frem og tilbage mellem en post og en tekstrepræsentation.
Ved at bruge denne mulighed kan din triggerfunktion forenkles til:
DECLARE
l_sql text;
BEGIN
IF TG_TABLE_SCHEMA = 'public' THEN
newtable := TG_TABLE_NAME || '_actividad';
ELSE
newtable := TG_TABLE_SCHEMA || '_' || TG_TABLE_NAME || '_actividad';
END IF;
PERFORM creartablaactividad(TG_TABLE_SCHEMA, TG_TABLE_NAME);
l_sql := 'INSERT INTO actividad.%I SELECT current_user, current_timestamp, %L, ($1).*';
IF TG_OP = 'DELETE' THEN
execute format(l_sql, newtable, 'D') using OLD;
RETURN OLD;
ELSE
-- covers UPDATE and INSERT
execute format(l_sql, newtable, 'U') using NEW;
RETURN NEW;
END IF;
RETURN NULL; -- result is ignored since this is an AFTER trigger
END;
Brug af pladsholdere som %I
og %L
gør det også muligt kun at definere den faktiske SQL én gang og genbruge den. Disse "parametre" erstattes af format()
funktion (som bevarer $1
)
Bemærk brugen af ($1).*
inde i SQL-strengen. Det vil få execute
sætning udvide postparameteren $1
til alle dens kolonner. Selve posten videregives "native" med USING
søgeord.
Brugen af INSERT
uden en målkolonneliste (insert into some_table ...
i stedet for insert into some_table (col1, col2, ...) ...
) er en ret skrøbelig ting at gøre. Hvis kilden og målet ikke stemmer overens, kan indsatsen fejle ganske let. .
Hvis du ikke kører massiv rapportering på revisionstabellerne (hvor det ville være meget mere effektivt at have eksplicitte kolonnenavne), vil du måske tænke på en mere generisk revisionstrigger ved hjælp af en JSON
eller HSTORE
kolonne for at gemme hele posten. Der er flere færdige revisionstriggere tilgængelige:
- http://okbob.blogspot. de/2015/01/most-simply-implementation-of-history.html
- https://github.com/wingspan/wingspan-auditing
- https://www.cybertec-postgresql.com /da/tracking-changes-in-postgresql/
- https://wiki.postgresql.org/wiki/Audit_trigger_91plus