PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Postgresql:Jak uciec od pojedynczych cudzysłowów w wyzwalaczu bazy danych?

Ogólnie rzecz biorąc, pojedyncze cytaty są unikane przez ich podwojenie.

Aby połączyć zmienne w ciągu SQL, powinieneś użyć quote_literal() - ta funkcja dba o prawidłowe uniknięcie pojedynczego cudzysłowu, np.:

quote_literal(temp_row.row_data)

Powiedziawszy to:lepszym (i bezpieczniejszym) rozwiązaniem jest użycie parametrów w połączeniu z 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 zwykle dba o prawidłowe ucieczkę identyfikatora, choć w tym przypadku nie zadziała. Jeśli chcesz mieć 100% pewność, że nawet niestandardowe nazwy tabel działają poprawnie, musisz najpierw umieścić nazwę tabeli docelowej w zmiennej i użyć jej dla format() funkcja:

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

Ta część:

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

upadnie również po pierwszym rzędzie. execute .. into ... oczekuje, że zapytanie zwróci pojedynczy . Wyciąg, którego używasz, zwróci wszystkie wiersze z tabeli historii.

Nie rozumiem też, dlaczego w ogóle to robisz.

W ogóle nie musisz wybierać z tabeli historii.

Coś takiego powinno wystarczyć (nietestowane! ):

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;

Wreszcie:wyzwalacze audytu zostały napisane wcześniej i istnieje wiele gotowych rozwiązań na to:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wyłączyć DELETE w tabeli w PostgreSQL?

  2. Uzyskaj identyfikator ostatniej wkładki po przygotowanej wkładce z PDO

  3. lista postgresql i tabele kolejności według rozmiaru

  4. Wykonaj aktualizację alembika w wielu schematach

  5. Najlepszy sposób na poznanie procedur składowanych PostgreSQL?