如何返回从存储过程中找不到的记录

时间:2014-10-23 10:02:41

标签: postgresql go plpgsql

当没有找到记录时,是否可以使存储过程的行为与常规选择查询完全相同,或者这是否是驱动程序问题。

例如,使用go,不返回任何行的查询将返回sql.ErrNoRows错误。但是,这不会:

create table emptytable(id int);

create function selectany() returns emptytable as $$
DECLARE
  _out emptytable;
BEGIN
  SELECT * INTO emptytable FROM emptytable limit 1;
  RETURN _out;
END;
$$ LANGUAGE PLPGSQL;

我已经尝试过SELECT INTO STRICT,虽然这引发了一个"查询没有返回任何行"错误,它与非存储过程查询不同。也没有提出NO_DATA_FOUND。

3 个答案:

答案 0 :(得分:3)

如果我理解你的要求:

从函数返回一行或不行,并允许对返回的行(如果有的话)执行更多操作。

测试表:

CREATE TABLE emptytable(id int, txt text);  -- multiple columns

要返回一个或没有完整的表格行

CREATE OR REPLACE FUNCTION selectany_all()
  RETURNS SETOF emptytable AS
$func$
DECLARE
   _out  emptytable;
BEGIN
   FOR _out IN
      SELECT * FROM emptytable LIMIT 1
   LOOP
     -- do something with _out before returning
     RAISE NOTICE 'before: %', _out;
     RETURN NEXT _out;
     -- or do something with _out after returning row
     RAISE NOTICE 'after: %', _out;
   END LOOP;
END
$func$ LANGUAGE plpgsql;

要获得更灵活的方法:返回任意列

CREATE OR REPLACE FUNCTION selectany_any()
  RETURNS TABLE (id int, txt text) AS
$func$
BEGIN
   FOR id, txt IN
      SELECT e.id, e.txt FROM emptytable e LIMIT 1
   LOOP  
     -- do something with id and text before returning
     RAISE NOTICE 'before: %, %', id, txt;
     RETURN NEXT;
     -- or do something with id and text after returning row
     RAISE NOTICE 'after: %, %', id, txt;
   END LOOP;
END
$func$ LANGUAGE plpgsql;

注意,如果没有行,LOOP 从未输入。因此,我的测试代码中没有NOTICE

这两个函数同时适用于 n LIMIT 1仅适用于此特定请求。

密切相关,有更多解释:

答案 1 :(得分:1)

2.5选项:

1a)如果您只需要返回查询,则可以使用SETOFRETURN QUERY

1b)或者只使用语言SQL作为@ClodoaldoNeto,它使用sql' s SELECT stmt

本机返回查询

2)如果您需要在流程中处理结果,则必须使用SETOFRETURN NEXT,确保检查IF FOUND THEN RETURN;(注意缺少NEXT,如果给出将作为单个空行返回)

理想情况下,我不想将SETOF用于已知的返回完全无或1行的过程,但似乎需要SETOF来获取查询过程,如sql语句从应用程序中让司机识别NO ROWS RETURNED

以下示例:

create table emptytable(id int);

create function selectany() returns setof emptytable as $$
DECLARE
  _out emptytable;
BEGIN
  SELECT * INTO _out FROM emptytable limit 1;
  IF FOUND THEN
    RETURN _out;
  END IF;
  RETURN;
END;
$$ LANGUAGE PLPGSQL;

create function selectany_rq() returns setof emptytable as $$
BEGIN
  RETURN QUERY SELECT * INTO _out FROM emptytable limit 1;
END;
$$ LANGUAGE PLPGSQL;    

答案 2 :(得分:0)

根据评论中的建议,请返回setof emptytable

create function selectany()
returns setof emptytable as $$
    select *
    from emptytable 
    limit 1
    ;
$$ language sql;

普通的SQL可以做到这一点