PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Postgresql:Как да избягам от единичните кавички в тригера на базата данни?

Като цяло единични, кавичките се избягват чрез удвояването им.

За да свържете вашите променливи в SQL низ, трябва да използвате quote_literal() - тази функция се грижи за правилното избягване на единични кавички, напр.:

quote_literal(temp_row.row_data)

Като каза това:по-доброто (и по-безопасно) решение е да се използват параметри, комбинирани с 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 обикновено се грижи за правилното екраниране на идентификатор, въпреки че в този случай няма да работи. Ако искате да сте 100% сигурни, че дори нестандартните имена на таблици работят правилно, трябва първо да поставите името на целевата таблица в променлива и да го използвате за format() функция:

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

Тази част:

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

ще се провали и след първия ред. execute .. into ... очаква заявката да върне единичен . Изявлението, което използвате, ще върне всички редове от таблицата с история.

Също така не разбирам защо го правиш на първо място.

Изобщо не е необходимо да избирате от таблицата с хронологията.

Нещо подобно би трябвало да е достатъчно (нетествано! ):

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;

И накрая:тригерите за одит са писани преди и има много готови решения за това:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как работят изгледите на PostgreSQL security_barrier?

  2. Намерете името на хоста в postgresql

  3. Динамично разделяне на таблици в postgres

  4. Извикване на функция за връщане на набор с аргумент на масив няколко пъти

  5. Как да форматирате пари в PostgreSQL