7

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?

また、返される行タイプがわからない場合は、どうすればよいのでしょうか?

4

2 に答える 2

6

Q1

あなたの「小さなテスト」はプレーンな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、 /を実行します。ほとんどのクライアントは、lat コマンドの結果のみを表示します。ROLLBACK

詳しくは、マニュアルのReturning Cursorsの章を参照してください。

Q2

また、返される行タイプがわからない場合は、どうすればよいのでしょうか?

結果のみを調べたいので、レコード全体を にキャスト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

于 2013-03-28T05:45:52.577 に答える
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 $$
于 2013-03-28T01:30:32.950 に答える