正确的方法在Postgresql 9.2中调用查询中的函数

时间:2014-03-13 18:08:05

标签: postgresql postgresql-9.2

我今天发现了一些奇怪的日志文件。我看到“通知”一遍又一遍地记录下来。而且我认为我已经找到了原因,但不要忍受它或修复。

查询是:

select (get_account_details(account.id)).* from account where id in (113126123254, 116261470380);

get_account_details将在某些情况下记录消息 - 一种情况是帐户具有daily_spend_limit。在我的日志中,我看到了:

NOTICE:  Account 116261470380 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 116261470380 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 116261470380 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 116261470380 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 116261470380 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 116261470380 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 116261470380 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 116261470380 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 116261470380 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 116261470380 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 116261470380 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 116261470380 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 116261470380 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 116261470380 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 116261470380 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 116261470380 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 116261470380 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 113126123254 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 113126123254 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 113126123254 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 113126123254 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 113126123254 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 113126123254 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 113126123254 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 113126123254 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 113126123254 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 113126123254 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 113126123254 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 113126123254 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 113126123254 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 113126123254 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 113126123254 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 113126123254 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00
NOTICE:  Account 113126123254 has a daily_spend_limit of 10.00.  Remaining balance as been calculated as 10.00

莫名其妙,但我终于注意到它被称为17次帐号。这是帐户表中的确切列数。

如果我跑:

select * from get_account_details(113126123254);

我只记录了1次通知。

这里发生了什么以及如何“正确”编写此查询?

1 个答案:

答案 0 :(得分:0)

我不知道为什么更简单的构造为每列调用一次函数,但这是抑制它的一种方法:

select (get_account_details).* from 
(
    select get_account_details(account.id) from account 
         where id in (113126123254, 116261470380)
) foo

由于您无法重现这一点,并且因为我没有方便您的架构,所以让我从头开始创建架构:

create table foo (id integer, a text, b text, c text, d text, e text);
insert into foo (id) select * from generate_series(1,4);
create function get_foo(int) returns setof foo as $$ BEGIN 
    RAISE NOTICE 'dfjkl'; 
    return query select * from foo where id=$1; 
END $$ language plpgsql;

现在执行这些,第一个给出12 NOTICE,第二个给出2。

select (get_foo(id)).* from foo where id in (1,2);
select (get_foo).* from (select get_foo(id) from foo where id in (1,2)) ssss;