sql >> Database >  >> RDS >> PostgreSQL

Postgresql:Hoe ontsnappen aan enkele aanhalingstekens in Database-trigger?

Over het algemeen worden enkele aanhalingstekens ontsnapt door ze te verdubbelen.

Om uw variabelen samen te voegen in een SQL-tekenreeks, moet u quote_literal() gebruiken - die functie zorgt voor het correct ontsnappen van enkele aanhalingstekens, bijvoorbeeld:

quote_literal(temp_row.row_data)

Dat gezegd hebbende:de betere (en veiligere) oplossing is om parameters te gebruiken in combinatie met 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; 

De %I placeholder zorgt er meestal voor dat een identifier correct ontsnapt, hoewel het in dit geval niet zou werken. Als je er 100% zeker van wilt zijn dat zelfs niet-standaard tabelnamen goed werken, moet je eerst de doeltabelnaam in een variabele zetten en die gebruiken voor het format() functie:

l_tablename := TG_TABLE_NAME || '_history';
EXECUTE 
   format('INSERT INTO audit.%I_history values ($1, $2, $3)', l_tablename)
   using ....

Dit deel:

v_sql = 'select * from ' || TG_TABLE_NAME::regclass || '_history';
execute v_sql into temp_row;

gaat ook mis na de eerste rij. execute .. into ... verwacht dat de zoekopdracht een enkele . retourneert . De instructie die u gebruikt, retourneert alles rijen uit de geschiedenistabel.

Ik begrijp ook niet waarom je dat in de eerste plaats doet.

U hoeft helemaal niet te selecteren uit de geschiedenistabel.

Zoiets zou voldoende moeten zijn (niet getest! ):

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;

Tot slot:er zijn al eerder audit triggers geschreven en daar zijn veel kant-en-klare oplossingen voor:




  1. Virtuele machine verwijderen uit VirtualBox

  2. Hoe voer ik een samengevoegde query uit in de ZF-tabelleninterface?

  3. Fout 1062 - Dubbele invoer '127' voor sleutel 'PRIMARY' - kan de reden niet vinden

  4. Hoe voeg ik AUTO_INCREMENT toe aan een bestaande kolom?