Я создал триггер базы данных для хранения данных строки в таблице аудита. Во время операции обновления этот триггер принимает данные из основной таблицы и вставляет их в таблицу предыстории. (таблица истории имеет столбцы: дата, тип операции говорят об обновлении/удалении, фактические данные строки) Но триггер в некоторых случаях не работает из-за цитируемого текста во входных данных.Postgresql: Как избежать одиночных кавычек в триггере базы данных?
Как я могу избежать цитируемого текста в моем триггере?
--My trigger
CREATE OR REPLACE FUNCTION audit.if_modified() RETURNS TRIGGER AS $function$
DECLARE
temp_row RECORD; -- a temporary variable used on updates/deletes
v_sql text;
BEGIN
IF TG_WHEN <> 'AFTER' THEN
RAISE EXCEPTION 'audit.if_modified() may only run as an AFTER trigger';
END IF;
v_sql = 'select * from ' || TG_TABLE_NAME::regclass || '_history';
execute v_sql into temp_row;
select now() into temp_row.action_tstamp_tx;
temp_row.action = SUBSTRING(TG_OP,1,1);
IF (TG_OP = 'UPDATE' AND TG_LEVEL = 'ROW') THEN
temp_row.row_data = OLD;
ELSIF (TG_OP = 'DELETE' AND TG_LEVEL = 'ROW') THEN
temp_row.row_data = OLD;
ELSIF (TG_OP = 'INSERT' AND TG_LEVEL = 'ROW') THEN
temp_row.row_data = NEW;
ELSE
RAISE EXCEPTION '[audit.if_modified] - Trigger func added as trigger for unhandled case: %, %',TG_OP, TG_LEVEL;
RETURN NULL;
END IF;
EXECUTE 'INSERT INTO audit.' || TG_TABLE_NAME::regclass || '_history VALUES (''' ||
temp_row.action_tstamp_tx || ''',''' ||
temp_row.action || ''',''' ||
temp_row.row_data || ''')';
RETURN NULL;
END;
$function$
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = audit,public,pg_catalog;
Это отлично работает для обычных случаев использования, но если данные VARCHAR имеет единственный цитируемый текст, то он не может загрузить данные в таблицу истории.
ERROR: syntax error at or near "s"
LINE 1: ...VALUES ('2016-02-22 11:44:43.994295-06','U','(6,Tom's,"2016-02...
^
QUERY: INSERT INTO audit.test_history VALUES ('2016-02-22 11:44:43.994295-06','U','(6,Tom's,"2016-02-22 09:49:32.315543")')
CONTEXT: PL/pgSQL function if_modified() line 30 at EXECUTE
Я новичок в Postgresql. Я попытался с опциями, как
regexp_replace() API
и
SELECT into temp_row.row_data unnest(('{' || trim((temp_row.row_data)::text, '()') || '}')::text[]);
и т.д., но я не мог понять, как проходные данные ROWTYPE и создать правильную запись вставки.
Пожалуйста, поделитесь своими мыслями о том, как я могу изменить свой триггер, чтобы вставить текст с одинарными кавычками.
Спасибо,