sql >> Databáze >  >> RDS >> PostgreSQL

Postgresql:Jak uniknout jednoduchým uvozovkám ve spouštěči databáze?

Obecně singl, uvozovky jsou uniknuty jejich zdvojením.

Chcete-li zřetězit své proměnné do řetězce SQL, měli byste použít quote_literal() - tato funkce se stará o správné escapování jednoduchých uvozovek, např.:

quote_literal(temp_row.row_data)

Nicméně:lepší (a bezpečnější) řešení je použít parametry kombinované s 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; 

%I placeholder se obvykle stará o správné escapování identifikátoru, i když v tomto případě by to nefungovalo. Pokud si chcete být 100% jisti, že i nestandardní názvy tabulek fungují správně, musíte nejprve vložit název cílové tabulky do proměnné a použít ji pro format() funkce:

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

Tato část:

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

selže i po první řadě. execute .. into ... očekává, že dotaz vrátí jeden . Příkaz, který používáte, vrátí vše řádků z tabulky historie.

Taky nechápu, proč to vůbec děláš.

Nemusíte vůbec vybírat z tabulky historie.

Něco takového by mělo stačit (netestováno! ):

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;

Konečně:spouštěče auditu byly napsány již dříve a existuje pro to mnoho hotových řešení:




  1. Importujte soubor výpisu MySQL do MSSQL

  2. Jak vybrat příspěvky vytvořené mnou nebo mými přáteli v informačním kanálu?

  3. Jak zvýšit vyrovnávací paměť dbms_output?

  4. Nejlepší typ indexování, pokud existuje klauzule LIKE