2011-08-23 56 views
3

在PostgreSQL,我有只需要调用dctUpdate功能没有做一个整体的SQL语句的表的更新规则,因为SQL语句在实际进行功能。我知道调用函数的唯一方法是通过SELECT dctUpdate(windowId)PSQL:沉默函数调用的输出,或称它没有SELECT

create or replace function infoUpdate(windowId in numeric) returns void as $$ 
begin 
    if windowId is null then 
     update info_timestamp set timestamp = now(); 
    else 
     update info_timestamp set timestamp = now() where window_id = windowId; 
    end if; 
end; 
$$ LANGUAGE plpgsql; 


create or replace rule info_update_rule as on update to some_table do also select infoUpdate(NEW.window_id); 

然而,在命令行中,当规则被触发,因为我在some_table更新一排,我从一个调用SELECT条款无用输出功能:

db=# update some_table set name = 'foobar' where window_id = 1; 
infoupdate 
----------- 

(1 row) 

UPDATE 1 

有没有办法有info_update_rule调用infoUpdate功能,没有它显示虚输出?

+0

你真的要设置** **所有在整个表中的时间戳'NOW()'如果只是新的'window_id'是NULL?你需要支持哪些版本的PostgreSQL? –

+0

@mu:是的,我的意思是设置NULL时的所有时间戳,并且我支持PostgreSQL 9.0和更高 – Fred

回答

1

我发现没有选项来实现这一点使用规则,但实现这个usign触发器的另一种方式。

所以,你定义触发功能如下:

CREATE OR REPLACE FUNCTION ur_wrapper_trg() 
    RETURNS trigger AS 
$BODY$ 
begin 
    perform infoUpdate(NEW.window_id); 
    RETURN NEW; 
end; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 
ALTER FUNCTION ur_wrapper_trg() OWNER TO postgres; 

注意PERFORM语法。该语法与SELECT语法相同,除了它抑制所有输出。

超过了定义触发

CREATE TRIGGER some_table_utrg 
    BEFORE UPDATE 
    ON some_table 
    FOR EACH ROW 
    EXECUTE PROCEDURE ur_wrapper_trg(); 

最后,你remve您的规则。

未用null进行测试,但实际的windos_id按预期工作,没有任何不需要的输出。

咨询与TriggersRules vs triggers为详细的说明。

+0

由于性能原因,我无法使用触发器。这条规则适用于更新任务关键型系统上数千行的查询,并且为每一行调用触发器将会非常昂贵,这就是为什么我必须使用规则来执行此操作。我仍然希望获得垃圾输出以获得更好的性能。 – Fred

0

解决方案,这是我的家乡是select function()前和后马上打电话给\t \a的关闭。唯一剩下的就是每个呼叫的新行。