3

この記事を見つけました:

http://wiki.postgresql.org/wiki/Return_more_than_one_row_of_data_from_PL/pgSQL_functions

私はそれを私の機能の例として使用しようとしています。さまざまなテーブルからさまざまな列を選択し、一連のレコードを返そうとしています。

これが私のコードです:

CREATE OR REPLACE FUNCTION get_details_for_widget(widgetid integer)
  RETURNS SETOF widgetdetails AS
$BODY$
DECLARE
    rec widgetdetails %rowtype;

BEGIN

    FOR rec IN (

        SELECT widget_details.id, widget_details.contact_id, widget_details.priority, widget_owner.contact
        FROM widget_details, widget_owner
        WHERE widget_details.rid=widgetid 
        AND widget_details.active_yn = 't'
        AND widget_owner.id=widget_details.contact_id
        Order by widget_details.priority ASC)
    LOOP
       RETURN NEXT rec;
    END LOOP;
END;

$BODY$
  LANGUAGE plpgsql;

このコードをコンパイルしようとすると、タイプ「widgetdetails」が存在しないというエラーが表示されます。wiki の例に沿って、ロジックを次のように変更しました。

CREATE OR REPLACE FUNCTION get_details_for_widget(widgetid integer)
  RETURNS SETOF widgetdetails AS
            'SELECT widget_details.id, widget_details.contact_id,      
            widget_details.priority, widget_owner.contact
        FROM widget_details, widget_owner
        WHERE widget_details.rid=widgetid 
        AND widget_details.active_yn = "t"
        AND widget_owner.id=widget_details.contact_id
        Order by widget_details.priority ASC'
$BODY$
DECLARE
    rec widgetdetails %rowtype;

BEGIN

    FOR rec IN (

        SELECT widget_details.id, widget_details.contact_id, widget_details.priority, widget_owner.contact
        FROM widget_details, widget_owner
        WHERE widget_details.rid=widgetid 
        AND widget_details.active_yn = 't'
        AND widget_owner.id=widget_details.contact_id
        Order by widget_details.priority ASC)
    LOOP
       RETURN NEXT rec;
    END LOOP;
END;

$BODY$
  LANGUAGE plpgsql;

次のようなエラーが表示されます。

ERROR: syntax error at or near "$BODY$

しかし、私は問題を見たり見つけたりすることができないようです。

4

2 に答える 2

3

使用しようとしている構文は、Postgres とは無関係です。

あなたのコードは必要以上に複雑です。単純な SQL 関数を使用します。

CREATE OR REPLACE FUNCTION get_details_for_widget(widgetid integer)
  RETURNS TABLE (id int, contact_id int, priority int, contact text)
$func$
   SELECT d.id, d.contact_id, d.priority, o.contact
   FROM   widget_details d
   JOIN   widget_owner   o ON o.id = d.contact_id
   WHERE  d.rid = widgetid   -- where does widgetid come from?
   AND    d.active_yn = 't'
   ORDER  BY d.priority
$func$ LANGUAGE sql

このような単純な関数には、plpgsql はまったく必要ありません。代わりにプレーンなSQL 関数を使用してください。

でアドホック行タイプを定義しますRETURNS TABLE ()。テーブル定義を提供しなかったため、列の型を即興で作成しました。これは plpgsql 関数でも同様に機能します。

また:

ブール値

コメントで明確にされているように、それはすでにブール列です。データ入力に文字列リテラル 't' / 'f' の代わりにTRUE/を使用することをお勧めします -ブール型に関するマニュアルを引用します:FALSE

キーワードTRUEandFALSEは、推奨される (SQL 準拠の) 使用法です。

WHERE句では、すべての式が結果に評価されますbooleanTRUE資格があるFALSEか、資格NULLがないか。したがって、booleanタイプの場合、次のように単純化できます。

   AND    d.active_yn = TRUE

ただ:

   AND    d.active_yn
于 2013-07-08T16:29:04.623 に答える
2

カスタム複合タイプを使用するには、最初に で作成する必要がありますCREATE TYPE

クエリに大まかに基づいた例(実際のデータ型を使用して変更する):

CREATE TYPE widgetdetails AS (
  id INT,
  contact_id INT,
  widget_details INT,
  contact TEXT
);

この型を作成した後でのみ、この宣言が受け入れられます。

DECLARE
    rec widgetdetails;
...

の構文についてもCREATE FUNCTION、最初のバージョンに固執してください。2 回目の試行には深刻な問題があり、役に立ちません。

于 2013-07-08T15:53:01.673 に答える