Mic*_*elF 2 postgresql plpgsql composite-types postgresql-9.2
我正在编写一个PL / pgSQL存储过程,该过程将返回一组记录。每个记录都包含现有表的所有字段(将其称为Retailer,该字段具有两个字段:retailer_key和retailer_name)。这当然有效:
CREATE FUNCTION proc_Find_retailers
(IN p_Store_key INT)
RETURNS SETOF Retailer
AS $$ ...`
Run Code Online (Sandbox Code Playgroud)
现在,我想更新sp,以便它在每个返回的记录的'end'处返回另外两个字段。我可以做一些事情,例如:
CREATE FUNCTION proc_Find_store
(IN p_Store_key INT)
RETURNS TABLE (
retailer_key int,
retailer_name varchar(50),
addl_field_1 int,
addl_field_2 double precision)
AS $$ ...
Run Code Online (Sandbox Code Playgroud)
在现实世界中,我的Retailer表具有50个字段(在我的示例中没有这两个字段),因此枚举RETURNS TABLE子句中的所有这些字段很繁琐。有没有捷径可走,所以我可以这样说:(我意识到我在这里编造的东西在语法上是非法的,但我这样做是为了让您有我所寻找的味道):
CREATE FUNCTION proc_Find_store
(IN p_Store_key INT)
RETURNS (SETOF Store,
addl_field_1 int,
addl_field_2 double precision)
AS $$ ...
Run Code Online (Sandbox Code Playgroud)
您可以返回整行作为复合类型并添加更多内容:
CREATE OR REPLACE FUNCTION f_rowplus()
RETURNS TABLE (rec demo, add_int int, add_txt text) AS
$func$
SELECT d, 5, 'baz'::text FROM demo d;
$func$ LANGUAGE sql;
Run Code Online (Sandbox Code Playgroud)
但是,当您使用简单调用时:
SELECT * FROM f_rowplus();
Run Code Online (Sandbox Code Playgroud)
您从表中获得该行demo
作为单独的复合类型。您必须致电:
SELECT (rec).*, add_int, add_txt FROM f_rowplus();
Run Code Online (Sandbox Code Playgroud)
获取所有单独的列。需要括号。
另外:这仍然只对函数求值一次 -像这样的直接调用将对返回类型中的每一列求值一次:
SELECT (f_rowplus()).*;
Run Code Online (Sandbox Code Playgroud)
细节:
Postgres在这里有点不一致。如果您使用创建函数
CREATE OR REPLACE FUNCTION f_row2()
RETURNS TABLE (rec demo) AS
...
Run Code Online (Sandbox Code Playgroud)
然后将其默默转换为单独的列(分解)。仍然没有链接到原始复合类型。您根本无法引用声明的输出列rec
,因为该列已被分解类型的列替换。该调用将导致错误消息:
SELECT rec FROM f_row2();
Run Code Online (Sandbox Code Playgroud)
同样在这里:
CREATE OR REPLACE FUNCTION f_row3(OUT rec demo)
RETURNS SETOF demo AS
...
Run Code Online (Sandbox Code Playgroud)
然而,一旦你添加任何更多的OUT
列,复合型被保留作为申报(不分解),您可以:
SELECT rec FROM f_rowplus();
Run Code Online (Sandbox Code Playgroud)
具有第一个功能。
我创建了一个SQL Fiddle,演示了这些变体。
除了
当使用功能在返回多个列FROM
列表(表函数),并在分解SELECT
列表是这样的:
SELECT (rec).* FROM f_rowplus();
Run Code Online (Sandbox Code Playgroud)
...该函数仍仅被评估一次 - 像这样直接在列表中进行调用和分解SELECT
:
SELECT (f_rowplus()).*; -- also: different result
Run Code Online (Sandbox Code Playgroud)
...将对返回类型中的每一列求值一次。细节:
归档时间: |
|
查看次数: |
2007 次 |
最近记录: |