测试使用和返回 refcursor 的 PostgreSQL 函数
Posted
技术标签:
【中文标题】测试使用和返回 refcursor 的 PostgreSQL 函数【英文标题】:Testing PostgreSQL functions that consume and return refcursor 【发布时间】:2013-03-27 23:41:41 【问题描述】:我想测试一个 Postgres 函数的结果(改变函数是不可能的)。
该函数接收 REFCURSOR 和其他几个东西作为参数,并返回相同的 RECURSOR。
get_function_that_returns_cursor(ret, 4100, 'SOMETHING', 123465)
现在我想在 Postgres 中创建一个小测试来获得这个 FUNCTION 的结果。 类似于下面的代码(这是我的方法,但它不起作用):
DO $$ DECLARE
ret REFCURSOR;
row_to_read table_it_will_return%ROWTYPE ;
BEGIN
PERFORM get_function_that_returns_cursor(ret, 4100, 'SOMETHING', 123465);
-- OR SELECT get_function_that_returns_cursor(ret, 4100, 'SOMETHING', 123465) INTO ret
FOR row_to_read IN SELECT * FROM ret LOOP
-- (...)
RAISE NOTICE 'Row read...';
END LOOP;
CLOSE ret;
END $$;
关于如何使它工作的任何建议?可用于测试此类函数的通用解决方案(获取 Cursor 并返回 Cursor?
如果我们不知道返回的行类型怎么办?
【问题讨论】:
在 PL/PgSQL 中使用动态行集很困难。这对他们来说真的不是很好。我建议在 pl/python、pl/perl 等函数中使用 refcursor 并在那里进行测试和评估。 【参考方案1】:第一季度
您的“小测试”可以是纯 SQL:
BEGIN;
SELECT get_function_that_returns_cursor('ret', 4100, 'foo', 123); -- note: 'ret'
FETCH ALL IN ret; -- works for any rowtype
COMMIT; -- or ROLLBACK;
在检查结果之后执行COMMIT
/ ROLLBACK
。大多数客户端只显示 lat 命令的结果。
更多内容见手册Returning Cursors一章。
第二季度
如果我们不知道返回的行类型怎么办?
由于您只想检查结果,您可以将整个记录投射到text
。
这样就可以完全避免函数的动态返回类型问题。
考虑这个演示:
CREATE TABLE a (a_id int PRIMARY KEY, a text);
INSERT INTO a VALUES (1, 'foo'), (2, 'bar');
CREATE OR REPLACE FUNCTION reffunc(INOUT ret refcursor) AS -- INOUT param :)
$func$
BEGIN
OPEN ret FOR SELECT * FROM a;
END
$func$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION ctest()
RETURNS SETOF text AS
$func$
DECLARE
curs1 refcursor;
rec record;
BEGIN
curs1 := reffunc('ret'); -- simple assignment
LOOP
FETCH curs1 INTO rec;
EXIT WHEN NOT FOUND; -- note the placement!
RETURN NEXT rec::text;
END LOOP;
END
$func$ LANGUAGE plpgsql;
-> SQLfiddle
【讨论】:
【参考方案2】:这符合我的要求:
DO $$ DECLARE
mycursor REFCURSOR;
rec RECORD;
BEGIN
SELECT 'ret' INTO mycursor FROM get_function_that_returns_cursor('ret'::REFCURSOR, 4100, 'SOMETHING', 123465);
WHILE (FOUND) LOOP
FETCH mycursor INTO rec;
RAISE NOTICE 'Row read. Data: % ', rec.collumn_name;
END LOOP;
END $$
【讨论】:
以上是关于测试使用和返回 refcursor 的 PostgreSQL 函数的主要内容,如果未能解决你的问题,请参考以下文章
测试在 DataGrip 中返回 sys-refcursor 的 Oracle 函数