2008-11-20 109 views
19

我在Postgresql中有这个触发器,我不能只是开始工作(什么都不做)。为了理解,我是这样定义它的:调试postgresql触发器

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中的调试器,该调试器在Windows上默认启用;您只需要执行... \ 8.3 \ share \ contrib \ pldbgapi.sql中发现的代码,然后重新启动pgAdmin3,右键单击您的触发器函数,点击'Set Breakpoint',然后执行一个会导致触发器触发的语句,例如上面的UPDATE语句。

3

您可以在触发器函数内使用'raise notice'语句来调试它。调试没有被调用的触发器是另一回事。

如果您在触发器功能中添加“异常提升”,您还可以插入/更新吗?另外,如果您的更新测试发生在与插入测试相同的事务中,则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

您可能想完全限定(在模式名称前面)各种对象的名称,只是为了安全起见。 此外,您可能会忽略触发器定义中的“INSERT”部分,默认值会处理这种情况。 – 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 

然后有一两件事我不知道之前:更新他们定义确切的表时,只触发了火灾。如果你使用继承,你也必须在子表上定义它们!