3

@Erwin Brandstetter と @Craig Ringer によって支援された以前のケースから継続して、次のようになるようにコードを修正しました。私の関数はテーブルではなくmyresult()now を出力することに注意してください(実際、前のケースで指摘されたように、テーブル オブジェクトを出力する意味はありません。全体の目的):text

CREATE OR REPLACE FUNCTION myresult(mytable text, myprefix text)
RETURNS text AS 
$func$
DECLARE
   myoneliner text;
BEGIN
   SELECT INTO myoneliner  
          'SELECT '
        || string_agg(quote_ident(column_name::text), ',' ORDER BY column_name)
        || ' FROM ' || quote_ident(mytable)
   FROM   information_schema.columns
   WHERE  table_name = mytable
   AND    column_name LIKE myprefix||'%'
   AND    table_schema = 'public';  -- schema name; might be another param

   RAISE NOTICE 'My additional text: %', myoneliner;
   RETURN myoneliner;
END
$func$ LANGUAGE plpgsql;

電話:

select myresult('dkj_p_k27ac','enri');   

上記の手順を実行すると、基本的にクエリであるテキスト文字列が得られます。簡単にするために、次に「oneliner-output」と呼びます。
「oneline-output」は次のようになります (ここにある 1 つの出力セルからコピー/貼り付けするだけです)。

"SELECT enrich_d_dkj_p_k27ac,enrich_lr_dkj_p_k27ac,enrich_r_dkj_p_k27ac FROM dkj_p_k27ac"
  • ステートメントの両側の二重引用符がmyresult()出力の一部であることに注意してください。私はそれらを追加しませんでした。

「oneliner-output」を作成し、それを実行する単一の関数を構築することを考えるという問題のある考えを、今でははるかによく理解しています。「oneliner-output」を新しい Postgres クエリ ウィンドウにコピー/貼り付けして、通常のクエリとして実行し、データ出力ウィンドウで目的の列と行を受け取ることができます。
ただし、この手順を自動化して、コピー/貼り付けの手順を回避したいと考えています。Postgres で、関数textから受け取った出力 (「oneliner-output」) を使用しmyresult()て実行する方法はありますか? myresult()の出力を受け取り、それをクエリの実行に使用する2 つ目の関数を作成できますか?

これらの行に沿って、次のスクリプト (以下) が機能し、実際に目的の列と行を正確に出力することを知っています。

-- DEALLOCATE stmt1; -- use this line after the first time 'stmt1' was created
prepare stmt1 as SELECT enrich_d_dkj_p_k27ac,enrich_lr_dkj_p_k27ac,enrich_r_dkj_p_k27ac FROM dkj_p_k27ac;
execute stmt1;
  • 正しい微調整を行った後、次のスクリプトのようなものが機能する可能性があるのではないかと考えていました。方法はわかりません。

    prepare stmt1 as THE_OUTPUT_OF_myresult();
    execute stmt1;
    

refcursor を使ってみる

CREATE OR REPLACE FUNCTION show_mytable(ref refcursor) RETURNS refcursor AS $$
BEGIN
   OPEN ref FOR SELECT enrich_d_dkj_p_k27ac,enrich_lr_dkj_p_k27ac,enrich_r_dkj_p_k27ac FROM dkj_p_k27ac;   -- Open a cursor 
   RETURN ref;    -- Return the cursor to the caller
END;
$$ LANGUAGE plpgsql;

電話:

BEGIN;
SELECT show_mytable('roy');
FETCH ALL IN "roy"; 

この手順は実際に機能し、目的の列と行を吐き出しますが、ここでも正確な SELECT ステートメントを提供する必要があります。

私は基本的に、関数の出力として代わりに提供できるようにしたいと考えていmyresult()ます。このようなもの:

CREATE OR REPLACE FUNCTION show_mytable(ref refcursor) RETURNS refcursor AS $$
BEGIN
   OPEN ref FOR myresult();   -- Open a cursor 
   RETURN ref;    -- Return the cursor to the caller
END;
$$ LANGUAGE plpgsql;

電話:

BEGIN;
SELECT show_mytable('roy');
FETCH ALL IN "roy"; 
4

2 に答える 2

1

refcursorを使用して、解決策も見つけたと思います。
それを調べて、「コーシャ」だと思うかどうかを確認して教えていただければ幸いです. 率直に言って、私は構文にあまり詳しくないので、ここで何を思いついたのかよくわかりません。しかし、ウェブで見つけたさまざまな例を使用して、これを合成することができました. それは私のために働くようです。私や他のユーザーのために、この解決策を明確に説明していただければ幸いです。

SELECTまず、動的ステートメントを構築する関数を作成します。

CREATE OR REPLACE FUNCTION myresult2()
  RETURNS text AS 
$func$
DECLARE
   myoneliner text;
   mytable    text := 'dkj_p_k27ac';
   myprefix   text := 'enri';
BEGIN
   SELECT INTO myoneliner  
          'SELECT '
        || string_agg(quote_ident(column_name::text), ',' ORDER BY column_name)
        || ' FROM ' || quote_ident(mytable)
   FROM   information_schema.columns
   WHERE  table_name = mytable
   AND    column_name LIKE myprefix||'%'
   AND    table_schema = 'public';  -- schema name; might be another param

   -- RAISE NOTICE 'My additional text: %', myoneliner; -- for debugging
   RETURN myoneliner;
END
$func$ LANGUAGE plpgsql;

次に、最初の関数の文字列 TEXT 出力を実行できる 2 番目の関数を作成しますmyresult2()

CREATE OR REPLACE FUNCTION show_mytable(ref refcursor)
  RETURNS refcursor AS
$func$
DECLARE
   mydynamicstatment text := myresult2();
BEGIN       
   OPEN ref FOR EXECUTE mydynamicstatment;
   RETURN ref;  -- return cursor to the caller
END;
$func$ LANGUAGE plpgsql;

電話:

BEGIN;
SELECT show_mytable('roy');
FETCH ALL IN "roy";
于 2015-01-08T00:15:28.563 に答える