在上下文中调用的集值函数,不能接受集合

时间:2016-12-13 01:43:00

标签: postgresql plpgsql set-returning-functions

我收到错误:

  

在上下文中调用的set-valued函数,不能接受集合

c=(c-100) % 256行执行此功能时:

RETURN QUERY EXECUTE

这是来自psql的输出:

PLSQL $ cat lookup_email.pl 
CREATE OR REPLACE FUNCTION app.lookup_email(ident_id bigint,sess bigint,company_id bigint,email varchar)
RETURNS SETOF RECORD as $$
DECLARE
    rec RECORD;
    comp_id bigint;
    server_session bigint;
    schema_name varchar;
    query varchar;
BEGIN
    schema_name:='comp' || company_id;
    select app.session.session into server_session from app.session where app.session.identity_id=ident_id and app.session.session=sess;
    IF FOUND
    THEN
        BEGIN
            query:='SELECT i.email,u.user_id FROM app.identity as i,' || schema_name || '.uzer as u WHERE i.email like ''%' || email || '%'' and i.identity_id=u.identity_id';
            RAISE NOTICE 'executing: %',query;
            RETURN QUERY EXECUTE query;
            RETURN;
        EXCEPTION
            WHEN OTHERS THEN
                RAISE NOTICE ' query error (%)',SQLERRM;

        END;
    END IF;
END;
$$ LANGUAGE plpgsql;

我知道查询不包含任何错误,因为它适用于另一个psql会话:

dev=> select app.lookup_email(4,730035455897450,6,'u');
NOTICE:  executing: SELECT i.email,u.user_id FROM app.identity as i,comp6.uzer as u WHERE i.email like '%u%' and i.identity_id=u.identity_id
NOTICE:   query error (set-valued function called in context that cannot accept a set)
 lookup_email 
--------------
(0 rows)

那么,如果我宣布我的函数为dev=> SELECT i.email,u.user_id FROM app.identity as i,comp6.uzer as u WHERE i.email like '%u%' and i.identity_id=u.identity_id; email | user_id ----------------+--------- hola@mundo.com | 1 (1 row) ,为什么Postgres会抱怨?我的错误在哪里?

2 个答案:

答案 0 :(得分:2)

  

那么,为什么Postgres抱怨我是否宣布我的函数是一个记录集?我的错误在哪里?

  1. 在FROM子句中调用Set Returning Function。
  2. 始终指定您的类型。
  3. 它被称为设置返回功能,但您想指定复合类型

    这完全有效,

    RETURNS SETOF RECORD $$
    

    但是,您可能需要使用

    进行调用
    SELECT app.lookup_email(4,730035455897450,6,'u')
    AS t(col1 type, col2 type)
    

    您无法调用无类型SRF的上下文是没有表定义的上下文。这种语法可能会变得令人讨厌,所以只需将RETURNS SETOF RECORD更改为

    就更容易了
    RETURNS TABLE(col1 type, col2 type) AS $$
    

    因为每个表的类型名称相同,所以也可以

    RETURNS SETOF myTable AS $$
    

    the docs

    中查找更多信息

答案 1 :(得分:-1)

在函数中查找输出列名称 像下面一样

CREATE OR REPLACE FUNCTION app.lookup_email(ident_id bigint,sess bigint,company_id bigint,email varchar, OUT <column_name> <data type>, OUT ...)