2008-11-20 11 views
19

У меня есть Trigger в Postgresql, что я не могу просто работать (ничего не делает). Для понимания, есть, как я определил его:отладка postgresql trigger

CREATE TABLE documents (
    ... 
    modification_time timestamp with time zone DEFAULT now() 
); 

CREATE FUNCTION documents_update_mod_time() RETURNS trigger 
AS $$ 
    begin 
    new.modification_time := now(); 
    return new; 
    end 
$$ 
    LANGUAGE plpgsql; 

CREATE TRIGGER documents_modification_time 
    BEFORE INSERT OR UPDATE ON documents 
    FOR EACH ROW 
    EXECUTE PROCEDURE documents_update_mod_time(); 

Теперь, чтобы сделать его немного более интересно .. Как вы отладки триггеров?

+0

Это не строго связаны, но вы могли бы найти его полезным в ваших приключениях PGSQL все равно: http://stackoverflow.com/questions/430123/how-do-i-enable-the-postgresql-function -profiler – Kev 2009-01-09 23:34:18

ответ

41
  1. Используйте следующий код в функции запуска, а затем посмотреть на вкладку «Сообщения» в pgadmin3 или выход в PSQL:

    RAISE NOTICE 'myplpgsqlval is currently %', myplpgsqlval;  -- either this 
    RAISE EXCEPTION 'failed'; -- or that 
    
  2. Чтобы увидеть, какие триггеры на самом деле получить под названием сколько раз и т.п., следующее утверждение является спасителем выбора:

    EXPLAIN ANALYZE UPDATE table SET foo='bar'; -- shows the called triggers 
    

    Обратите внимание, что если ваш триггер не вызывался и использовать наследование, это может быть го у вас определен только триггер в родительской таблице, тогда как триггеры не наследуются дочерними таблицами автоматически.

  3. Чтобы выполнить эту функцию, вы можете использовать отладчик, встроенный в pgAdmin3, который по умолчанию включен по умолчанию; все, что вам нужно сделать, это выполнить код, найденный в ... \ 8.3 \ share \ contrib \ pldbgapi.sql против базы данных, которую вы отлаживаете, перезапустите pgAdmin3, щелкните правой кнопкой мыши по вашей функции запуска, нажмите «Установить точку останова», а затем выполните инструкцию, которая приведет к срабатыванию триггера, например, над выражением UPDATE.

3

Вы можете использовать операторы «raise notice» внутри вашей триггерной функции для ее отладки. Отлаживать триггер, который не называется вообще, - это еще одна история.

Если вы добавите «исключение для повышения» внутри своей функции триггера, можете ли вы по-прежнему вставлять/обновлять?

Кроме того, если ваш тест обновления выполняется в той же транзакции, что и ваш тест insert, now() будет таким же (поскольку он рассчитан только один раз за транзакцию), и поэтому обновление не будет ничего делать. Если это так, либо делайте их в отдельных транзакциях, либо если это единичный тест, и вы не можете этого сделать, используйте clock_timestamp().

У меня есть модульный тест, который зависит от некоторого времени происходит путем между транзакциями, так что в начале модульного тестирования у меня есть что-то вроде:

ALTER TABLE documents 
    ALTER COLUMN modification_time SET DEFAULT clock_timestamp(); 

Тогда в триггере, используют «набор MODIFICATION_TIME = по умолчанию ».

Как правило, он не выполняет дополнительный расчет, но во время модульного теста это позволяет мне делать вставки с pg_sleep между ними, чтобы имитировать прохождение времени и фактически отражать их в данных.

+0

Хороший намек ... так кажется, функция не вызвана .. любая идея почему? – 2008-11-20 19:28:05

+0

У вас есть разрешения на выполнение функции триггера? – Kev 2008-11-20 19:45:49

+0

Возможно, вы захотите полностью квалифицировать (добавить имя схемы) имена различных объектов, чтобы быть в безопасности. Также вы, возможно, можете оставить часть «ВСТАВИТЬ» вашего определения триггера, значение по умолчанию позаботится об этом случае. – 2008-11-20 20:02:38

2

Оказывается, я использовал наследование в вышеупомянутой проблеме и забыл упомянуть об этом. Теперь для всех, кто мог бы работать в этом, а, вот некоторые отладочные намеки:

Используйте следующий код для отладки, что делает триггер:

RAISE NOTICE 'test';  -- either this 
RAISE EXCEPTION 'failed'; -- or that 

Чтобы узнать, какие триггеры действительно дозвонились, сколько раз и т.д., следующее утверждение является спасителем выбора:

EXPLAIN ANALYZE UPDATE table SET foo='bar'; -- shows the called triggers 

Тогда есть одна вещь, которую я не знал раньше: вызывает только огонь при обновлении точной таблицы они определены на. Если вы используете наследование, вы также должны определить их на дочерних таблицах!

Смежные вопросы