3

テーブルを返すストアド プロシージャを作成しようとしています。プロシージャは構文的に正しく、psql はそれを受け入れますが、実行時エラーをスローします。

私がこれまでに持っているもの:

CREATE OR REPLACE FUNCTION get_todays_appointments()
RETURNS TABLE 
(
    fname VARCHAR(32),
    lname VARCHAR(32),
    phoneno CHAR(10),
    datetime TIMESTAMP WITHOUT TIME ZONE,
    duration INTERVAL,
    caseid INTEGER
) AS $$
BEGIN
    RETURN QUERY
        SELECT
        (
            client.fname, 
            client.lname, 
            client.phoneno, 
            appointment.datetime, 
            appointment.duration, 
            photocase.caseid
        )
            FROM  (appointment NATURAL JOIN photocase NATURAL JOIN client)
            WHERE 
            (
                appointment.datetime >= current_date 
                AND appointment.datetime < current_date + 1
            );
END;
$$
LANGUAGE plpgsql;

クエリを手動で実行すると、意図したとおりに機能しますが、SP を使用すると、常に次のエラーが発生します。

エラー: クエリの構造が関数の結果の型と一致しません 詳細: 返された型のレコードが期待される型の文字と一致せず、列 1 が異なります。 コンテキスト: PL/pgSQL 関数 "get_todays_appointments" 行 3 の RETURN QUERY

テーブル スキーマを約 15 回再確認しましたが、間違いなく正しいです。

奇妙な部分は、属性をプルーニングすると関数が正常に機能するため、一度に 1 つしか返されないことです。複数の属性を返そうとするとすぐに、エラーがスローされます。

私はグーグルでいくつかの例を見つけましたが、実際には何も機能しません。SETOF の使用も見ましたが、このシグネチャを持つテーブルがないため、あまり役に立ちません。

postgresql v9.1.7 を使用しています。

4

1 に答える 1

3

現在、これをテストする便利な方法はありませんが、いくつかの括弧を失う必要があると思います.

CREATE OR REPLACE FUNCTION get_todays_appointments()
RETURNS TABLE 
(
    fname VARCHAR(32),
    lname VARCHAR(32),
    phoneno CHAR(10),
    datetime TIMESTAMP WITHOUT TIME ZONE,
    duration INTERVAL,
    caseid INTEGER
) AS $$
BEGIN
    RETURN QUERY
        SELECT
            client.fname, 
            client.lname, 
            client.phoneno, 
            appointment.datetime, 
            appointment.duration, 
            photocase.caseid
            FROM  (appointment NATURAL JOIN photocase NATURAL JOIN client)
            WHERE 
            (
                appointment.datetime >= current_date 
                AND appointment.datetime < current_date + 1
            );
END;
$$
LANGUAGE plpgsql;

通常、PostgreSQL のエラー メッセージは非常に適切です。これは文字通り真実です。

エラー: クエリの構造が関数の結果の型と一致しません 詳細: 返された型のレコードが期待される型の文字と一致せず、列 1 が異なります。

この場合、RETURN QUERY は「レコード」型の値を返します。これは、行コンストラクターが次のように見えるためSELECT ROW(value1, column1, column2)です。また、SELECT ステートメントでは、キーワード "ROW" はオプションであるため、行コンストラクターは次のようになりますSELECT (value1, column1, column2)

したがって、このスケルトン構文

select (column1, column2) from whatever 

はこれに相当します。

select row(column1, column2) from whatever

しかし、あなたはそれを望んでいません。thisと同等のものが必要です。

select column1, column2 from whatever

したがって、列リストを囲む括弧を失います。

于 2013-01-27T01:24:49.780 に答える