fra*_*enz 8 sql postgresql stored-procedures left-join lateral
我正在尝试调用存储过程在左外连接中传递参数,如下所示:
select i.name,sp.*
from items i
left join compute_prices(i.id,current_date) as sp(price numeric(15,2),
discount numeric(5,2), taxes numeric(5,2)) on 1=1
where i.type = 404;
Run Code Online (Sandbox Code Playgroud)
compute_prices()返回一组记录.
这是postgres显示的消息:
错误:对表"i"的FROM子句条目的无效引用
...左连接compute_prices(i.id,current_date)...
提示:表"i"有一个条目,但不能从查询的这一部分引用它.
这种查询适用于Firebird.有没有办法可以通过使用查询使其工作?我不想创建另一个循环遍历项目并进行单独调用的存储过程compute_prices().
通常,您可以使用提供的简单语法@Daniel扩展众所周知的行类型(也称为记录类型,复杂类型,复合类型):
SELECT i.name, (compute_prices(i.id, current_date)).*
FROM items i
WHERE i.type = 404;
Run Code Online (Sandbox Code Playgroud)
但是,如果您的描述准确无误......
compute_prices sp返回一组记录.
......我们正在处理匿名记录.Postgres不知道如何扩展匿名记录并在绝望中抛出一个EXCEPTION:
ERROR: a column definition list is required for functions returning "record"
Run Code Online (Sandbox Code Playgroud)
Postgres 9.3中有一个解决方案.LATERAL,如@a_horse在评论中提到的:
SELECT i.name, sp.*
FROM items i
LEFT JOIN LATERAL compute_prices(i.id,current_date) AS sp (
price numeric(15,2)
,discount numeric(5,2)
,taxes numeric(5,2)
) ON TRUE
WHERE i.type = 404;
Run Code Online (Sandbox Code Playgroud)
手册中的详细信息.
事情变得多毛了.这是一个解决方法:编写一个包装函数,将您的匿名记录转换为众所周知的类型:
CREATE OR REPLACE FUNCTION compute_prices_wrapper(int, date)
RETURNS TABLE (
price numeric(15,2)
,discount numeric(5,2)
,taxes numeric(5,2)
) AS
$func$
SELECT * FROM compute_prices($1, $2)
AS t(price numeric(15,2)
,discount numeric(5,2)
,taxes numeric(5,2));
$func$ LANGUAGE sql;
Run Code Online (Sandbox Code Playgroud)
然后你可以使用@Daniel的简单解决方案,只需输入包装函数:
SELECT i.name, (compute_prices_wrapper(i.id, current_date)).*
FROM items i
WHERE i.type = 404;
Run Code Online (Sandbox Code Playgroud)
PostgreSQL 8.3刚刚达到EOL,截至目前(2013年2月)尚未得到支持.
因此,如果可能的话,你最好升级.但如果你不能:
CREATE OR REPLACE FUNCTION compute_prices_wrapper(int, date
,OUT price numeric(15,2)
,OUT discount numeric(5,2)
,OUT taxes numeric(5,2))
RETURNS SETOF record AS
$func$
SELECT * FROM compute_prices($1, $2)
AS t(price numeric(15,2)
,discount numeric(5,2)
,taxes numeric(5,2));
$func$ LANGUAGE sql;
Run Code Online (Sandbox Code Playgroud)
也适用于更高版本.
将妥善解决将解决您的函数compute_prices()返回一个众所周知的类型开始.返回SETOF record的函数通常是PITA.我只戳那些五米高的杆子.
| 归档时间: |
|
| 查看次数: |
3037 次 |
| 最近记录: |