Im Allgemeinen werden einzelne Anführungszeichen durch Verdoppelung maskiert.
Um Ihre Variablen in einen SQL-String zu verketten, sollten Sie quote_literal()
verwenden - Diese Funktion kümmert sich um das richtige Escapezeichen für einfache Anführungszeichen, z. B.:
quote_literal(temp_row.row_data)
Allerdings:Die bessere (und sicherere) Lösung ist die Verwendung von Parametern in Kombination mit format()
:
EXECUTE
format('INSERT INTO audit.%I_history values ($1, $2, $3)', tg_table_name)
using temp_row.action_tstamp_tx, temp_row.action, temp_row.row_data;
Der %I
Platzhalter sorgt normalerweise dafür, dass ein Bezeichner ordnungsgemäß maskiert wird, obwohl dies in diesem Fall nicht funktionieren würde. Wenn Sie 100 % sicher sein wollen, dass auch nicht standardmäßige Tabellennamen richtig funktionieren, müssen Sie zuerst den Zieltabellennamen in eine Variable einfügen und diese für das format()
verwenden Funktion:
l_tablename := TG_TABLE_NAME || '_history';
EXECUTE
format('INSERT INTO audit.%I_history values ($1, $2, $3)', l_tablename)
using ....
Dieser Teil:
v_sql = 'select * from ' || TG_TABLE_NAME::regclass || '_history';
execute v_sql into temp_row;
wird auch nach der ersten Reihe versagen. execute .. into ...
erwartet, dass die Abfrage eine Single zurückgibt . Die von Ihnen verwendete Anweisung gibt all zurück Zeilen aus der Verlaufstabelle.
Ich verstehe auch nicht, warum du das überhaupt machst.
Sie müssen überhaupt nicht aus der Verlaufstabelle auswählen.
So etwas sollte ausreichen (ungetestet! ):
IF (TG_OP = 'UPDATE' AND TG_LEVEL = 'ROW') THEN
temp_row := OLD;
ELSIF (TG_OP = 'DELETE' AND TG_LEVEL = 'ROW') THEN
temp_row := OLD;
ELSIF (TG_OP = 'INSERT' AND TG_LEVEL = 'ROW') THEN
temp_row := NEW;
ELSE
RAISE EXCEPTION '[audit.if_modified] - Trigger func added as trigger for unhandled case: %, %',TG_OP, TG_LEVEL;
RETURN NULL;
END IF;
execute format ('insert ... values ($1, $2, $3')
using now(), SUBSTRING(TG_OP,1,1), temp_row;
Abschließend:Audit-Trigger wurden bereits geschrieben, und es gibt viele fertige Lösungen dafür: