2017-06-18 11 views
0

私はsetofレコードを返す関数を作成しようとしています。私は次のように機能を使用したい:関数からsetofレコードを返す方法は?

SELECT city_name FROM set_city(1, 1, 'ExampleName'); 

My機能:

CREATE OR REPLACE FUNCTION set_city(_city_id integer, _country_id integer, _city_name varchar) 
RETURNS SETOF RECORD 
LANGUAGE plpgsql 
as $$ 

DECLARE 
     result record; 

BEGIN 
     IF EXISTS (SELECT 1 FROM geo_cities gc WHERE gc.id = _city_id) 
     THEN 
       UPDATE geo_cities 
       SET country_id = _country_id, city_name = _city_name 
       WHERE id = _city_id 
       RETURNING * INTO result; 
     ELSE 
       INSERT INTO geo_cities(id, country_id, city_name) 
       VALUES (_city_id, _country_id, _city_name) 
       RETURNING * INTO result; 
     END IF; 
     -- It's wrong 
     RETURN QUERY SELECT result; 
END; 
$$ 

私は何を変更する必要がありますか?

答えて

1

あなたがreturn文を変更することができます:

... 
     -- It's wrong 
     -- RETURN QUERY SELECT result; 
     RETURN NEXT result; -- that's good 
... 

しかし、列定義リストは、「記録」を返す関数に必要ですので、あなたは、すべてのクエリでそれを追加する必要があります:

SELECT city_name FROM set_city(1, 1, 'ExampleName') 
    AS (id int, country_id int, city_name text); 

実際、この関数はタイプgeo_citiesの単一の行を返します。setof

DROP FUNCTION set_city(_city_id integer, _country_id integer, _city_name varchar); 

CREATE OR REPLACE FUNCTION set_city(_city_id integer, _country_id integer, _city_name varchar) 
RETURNS geo_cities 
LANGUAGE plpgsql 
as $$ 
DECLARE 
     result geo_cities; 
BEGIN 
     IF EXISTS (SELECT 1 FROM geo_cities gc WHERE gc.id = _city_id) 
     THEN 
       UPDATE geo_cities 
       SET country_id = _country_id, city_name = _city_name 
       WHERE id = _city_id 
       RETURNING * INTO result; 
     ELSE 
       INSERT INTO geo_cities(id, country_id, city_name) 
       VALUES (_city_id, _country_id, _city_name) 
       RETURNING * INTO result; 
     END IF; 
     RETURN result; 
END; 
$$; 

SELECT city_name FROM set_city(1, 1, 'ExampleName'); 

単一のSQL文で同じ機能を利用できます。

INSERT INTO geo_cities(id, country_id, city_name) 
VALUES (1, 1, 'ExampleName') 
ON CONFLICT (id) DO UPDATE SET 
    country_id = excluded.country_id, 
    city_name = excluded.city_name 
RETURNING *; 
関連する問題