当没有找到记录时,是否可以使存储过程的行为与常规选择查询完全相同,或者这是否是驱动程序问题。
例如,使用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。
答案 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)如果您只需要返回查询,则可以使用SETOF
和RETURN QUERY
1b)或者只使用语言SQL
作为@ClodoaldoNeto,它使用sql' s SELECT
stmt
2)如果您需要在流程中处理结果,则必须使用SETOF
和RETURN 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可以做到这一点