从游标返回一个表

时间:2013-07-10 04:21:22

标签: postgresql types cursor postgresql-9.1 plpgsql

我有一个函数,它根据客户ID返回一个计算值表。我需要为所有客户获得价值;我做了一个光标,但是我不能让它返回集合。

客户表:

id    name
----  ----
CN102 Dude
CN103 Guy
CN104 Mate

功能:

SELECT * FROM get_custom_fields('CN104');

name  field_value
----  -----
POP    9
Z44   blue
POP    19

请注意,可能有多个具有相同名称的行。 这是我的光标:

CREATE OR REPLACE FUNCTION my_cursor () 
RETURNS SETOF RECORD AS $$
DECLARE
    v_customer_rec RECORD;
    v_pop RECORD;
BEGIN
    FOR v_customer_rec IN SELECT ucn FROM customer LOOP
        SELECT INTO v_pop field_value from get_custom_fields(v_customer_rec.ucn) where custom_field='POP';
        RAISE NOTICE 'Customer % Value %', v_customer_rec.ucn,v_pop;
        --   RETURN QUERY select field_value from get_custom_fields(v_customer_rec.ucn) where custom_field='POP';
    END LOOP;
    RETURN;
END;
$$ LANGUAGE plpgsql;

返回:

db=# select my_cursor();
NOTICE:  Customer CN102 Value (5)
NOTICE:  Customer CN103 Value (12)
NOTICE:  Customer CN104 Value (9)
NOTICE:  Customer CN104 Value (19)
 my_cursor 
-------------
(0 rows)

所以我知道应该工作。但是如果使用RETURN QUERY(在代码中注释),我会收到以下错误:

ERROR:  set-valued function called in context that cannot accept a set
CONTEXT:  PL/pgSQL function "my_cursor" line 9 at RETURN QUERY

如何让它返回表格中的值或设置?

我想要:

ucn   field_value
----- -----------
CN102 5
CN103 12
CN104 9
CN104 19

1 个答案:

答案 0 :(得分:0)

您的(简化)功能可能如下所示:

CREATE OR REPLACE FUNCTION my_cursor() 
  RETURNS SETOF RECORD AS
$func$
DECLARE
   _ucn text;
BEGIN

FOR _ucn IN
    SELECT ucn FROM customer
LOOP
    RETURN QUERY
    SELECT *
    FROM   get_custom_fields(_ucn)
    WHERE  name = 'POP';
END LOOP;

RETURN;

END
$func$ LANGUAGE plpgsql;

我假设text的数据类型为ucn

但实际上,您应定义RETURN类型,以避免在每次调用时都提供列定义列表。如果您只想要列field_value,并且类型为text

CREATE OR REPLACE FUNCTION my_cursor() 
  RETURNS SETOF text AS
$func$
DECLARE
   _ucn text;
BEGIN

FOR _ucn IN
    SELECT ucn FROM customer
LOOP
    RETURN QUERY
    SELECT field_value
    FROM   get_custom_fields(_ucn)
    WHERE  name = 'POP';
END LOOP;

RETURN;

END
$func$ LANGUAGE plpgsql;

或者每行使用RETURNS TABLE()多个列:

CREATE OR REPLACE FUNCTION my_cursor() 
  RETURNS TABLE(ucn text, field_value text) AS
$func$
DECLARE
   _ucn text;
BEGIN

FOR _ucn IN
    SELECT c.ucn FROM customer c
LOOP
    RETURN QUERY
    SELECT g.ucn, g.field_value
    FROM   get_custom_fields(_ucn) g
    WHERE  g.name = 'POP';
END LOOP;

RETURN;

END
$func$ LANGUAGE plpgsql;

请注意,函数体中可以看到RETURN类型的列。表限定相同名称的列以避免命名冲突。