Интерпретация TG_TABLE_NAME как значения для обновления строки в другой таблице - PullRequest
0 голосов
/ 18 октября 2018

Я хочу обновить строку в таблице master_table_info с последней отметкой времени при каждом обновлении некоторых других таблиц.Каждая строка в таблице соответствует другой таблице.Я создал эту функцию, но не могу интерпретировать TG_TABLE_NAME как значение переменной, а не как новый столбец.Я, таким образом, получаю ошибку column some_table does not exist.Как мне интерпретировать его как значение?

CREATE OR REPLACE FUNCTION master_table_timestamp()
RETURNS TRIGGER AS
$$
BEGIN
    EXECUTE format('
    UPDATE master_table_info
    SET updated_at = NOW()
    WHERE table_name = %I', TG_TABLE_NAME);
    RETURN NULL;
END;
$$
language plpgsql;

CREATE TRIGGER master_table_timestamp
BEFORE UPDATE ON some_table
EXECUTE PROCEDURE master_table_timestamp();

РЕДАКТИРОВАТЬ

Основываясь на ответах / комментариях и чтении документации по триггеру, японял, что я должен использовать TG_TABLE_NAME и перейти на триггер AFTER.Однако изменение таблицы с помощью триггера не приводит к изменениям master_table_info.Что может быть не так?

CREATE OR REPLACE FUNCTION master_table_timestamp()
RETURNS TRIGGER AS
$$
BEGIN
    UPDATE master_table_info
    SET updated_at = NOW()
    WHERE table_name = TG_TABLE_NAME;
    RETURN new;
END;
$$
language plpgsql;

CREATE TRIGGER master_table_timestamp
AFTER UPDATE ON some_table
EXECUTE PROCEDURE master_table_timestamp();

2-е редактирование

Этот код в моем редактировании выше (основан на помощи из ответов) является правильным.Мне просто нужно было принудительно обновить таблицу вручную, чтобы она правильно отображалась.

1 Ответ

0 голосов
/ 18 октября 2018

%I заменяет заполнитель в качестве идентификатора.Таким образом, сгенерированный SQL будет

UPDATE master_table_info
SET updated_at = NOW()
WHERE table_name = some_table;

. Чтобы заменить буквенное значение, вам потребуется %L в качестве заполнителя в строке.Заполнитель %L заботится о правильном заключении в кавычки значений, поэтому, если вы используете это, сгенерированная строка будет выглядеть так:

UPDATE master_table_info
SET updated_at = NOW()
WHERE table_name = 'some_table';

, что вы и ожидали.


Однако естьДля начала не нужно динамического SQL.Поскольку вы используете эту функцию в триггере before, важно, чтобы вы возвращали из него ненулевое значение, иначе оператор UPDATE будет отменен.

CREATE OR REPLACE FUNCTION master_table_timestamp()
RETURNS TRIGGER AS
$$
BEGIN
    UPDATE master_table_info
      SET updated_at = NOW()
    WHERE table_name = TG_TABLE_NAME;

    RETURN new; --<< return a NON-NULL value here!
END;
$$
language plpgsql;
...