カスタムコンテンツを含む仮想テーブル(Oracleなど)を返すには、Postgres関数が必要です。テーブルには3つの列と不明な行数があります。
インターネット上で正しい構文が見つかりませんでした。
これを想像してください:
CREATE OR REPLACE FUNCTION "public"."storeopeninghours_tostring" (numeric)
RETURNS setof record AS
DECLARE
open_id ALIAS FOR $1;
returnrecords setof record;
BEGIN
insert into returnrecords('1', '2', '3');
insert into returnrecords('3', '4', '5');
insert into returnrecords('3', '4', '5');
RETURN returnrecords;
END;
これはどのように正しく書かれていますか?
(これはすべてpostgresql 8.3.7でテストされています-以前のバージョンはありますか?「$ 1のエイリアス」の使用を見てください)
CREATE OR REPLACE FUNCTION storeopeninghours_tostring(numeric)
RETURNS SETOF RECORD AS $$
DECLARE
open_id ALIAS FOR $1;
result RECORD;
BEGIN
RETURN QUERY SELECT '1', '2', '3';
RETURN QUERY SELECT '3', '4', '5';
RETURN QUERY SELECT '3', '4', '5';
END
$$;
(クエリ結果の代わりに)返すレコードまたは行変数がある場合は、「RETURN QUERY」ではなく「RETURN NEXT」を使用します。
関数を呼び出すには、次のようなことをする必要があります。
select * from storeopeninghours_tostring(1) f(a text, b text, c text);
そのため、関数の出力行スキーマがクエリに含まれることを定義する必要があります。これを避けるために、関数定義で出力変数を指定できます。
CREATE OR REPLACE FUNCTION storeopeninghours_tostring(open_id numeric, a OUT text, b OUT text, c OUT text)
RETURNS SETOF RECORD LANGUAGE 'plpgsql' STABLE STRICT AS $$
BEGIN
RETURN QUERY SELECT '1'::text, '2'::text, '3'::text;
RETURN QUERY SELECT '3'::text, '4'::text, '5'::text;
RETURN QUERY SELECT '3'::text, '4'::text, '5'::text;
END
$$;
(余分な:: textキャストが必要な理由はよくわかりません...「1」はデフォルトでvarcharです?)
以前の既存の回答はすべて時代遅れであるか、最初は非効率的でした。
3つのinteger
列を返したいと仮定します。
最新のPL/pgSQL(PostgreSQL 8.4以降)でこれを行う方法は次のとおりです。
CREATE OR REPLACE FUNCTION f_foo() -- (open_id numeric) -- parameter not used
RETURNS TABLE (a int, b int, c int) AS
$func$
BEGIN
RETURN QUERY VALUES
(1,2,3)
, (3,4,5)
, (3,4,5)
;
END
$func$ LANGUAGE plpgsql IMMUTABLE ROWS 3;
Postgres 9.6以降では、 PARALLEL SAFE
。
コール:
SELECT * FROM f_foo();
つかいます - RETURNS TABLE
は、返すアドホック行タイプを定義します。
またはRETURNS SETOF mytbl
事前定義された行タイプを使用します。
つかいます - RETURN QUERY
は、1つのコマンドで複数の行を返します。
VALUES
式を使用して、複数の行を手動で入力します。これは標準のSQLであり、これまでずっとでした。
パラメータが実際に必要な場合、パラメータ名(open_id numeric)
の代わりに ALIAS
、推奨されません 。この例では、パラメーターは使用されず、ノイズのみが...
完全に正当な識別子を二重引用符で囲む必要はありません。二重引用符は、それ以外の場合は違法な名前(大文字と小文字の混在、違法な文字または予約語)を強制するためにのみ必要です。
関数のボラティリティはIMMUTABLE
にすることができます 、結果は変わらないため。
ROWS 3
はオプションですが、返される行の数はknowなので、Postgresに宣言することもできます。クエリプランナーが最適なプランを選択するのに役立ちます。
このような単純なケースでは、代わりにプレーンなSQLステートメントを使用できます。
VALUES (1,2,3), (3,4,5), (3,4,5)
または、特定の列名とタイプを定義する(または持っている)場合:
SELECT *
FROM (
VALUES (1::int, 2::int, 3::int)
, (3, 4, 5)
, (3, 4, 5)
) AS t(a, b, c);
代わりに、単純な SQL関数 にラップできます。
CREATE OR REPLACE FUNCTION f_foo()
RETURNS TABLE (a int, b int, c int) AS
$func$
VALUES (1, 2, 3)
, (3, 4, 5)
, (3, 4, 5);
$func$ LANGUAGE sql IMMUTABLE ROWS 3;
私は自分の関数で一時テーブルをかなり使います。データベースに戻り値の型を作成してから、その型の変数を作成して返す必要があります。以下は、まさにそれを行うサンプルコードです。
CREATE TYPE storeopeninghours_tostring_rs AS
(colone text,
coltwo text,
colthree text
);
CREATE OR REPLACE FUNCTION "public"."storeopeninghours_tostring" () RETURNS setof storeopeninghours_tostring_rs AS
$BODY$
DECLARE
returnrec storeopeninghours_tostring_rs;
BEGIN
BEGIN
CREATE TEMPORARY TABLE tmpopeninghours (
colone text,
coltwo text,
colthree text
);
EXCEPTION WHEN OTHERS THEN
TRUNCATE TABLE tmpopeninghours; -- TRUNCATE if the table already exists within the session.
END;
insert into tmpopeninghours VALUES ('1', '2', '3');
insert into tmpopeninghours VALUES ('3', '4', '5');
insert into tmpopeninghours VALUES ('3', '4', '5');
FOR returnrec IN SELECT * FROM tmpopeninghours LOOP
RETURN NEXT returnrec;
END LOOP;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
select * from storeopeninghours_tostring()
一時テーブルを作成し、戻り値としてレコードをダンプすることに相当するMSSQLを探してここに上陸した人に... PostgreSQLには存在しません:(-戻り値の型を定義する必要があります。2つの方法があります。これは、関数の作成時またはクエリの作成時に。
こちらをご覧ください: http://wiki.postgresql.org/wiki/Return_more_than_one_row_of_data_from_PL/pgSQL_functions
CREATE OR REPLACE FUNCTION foo(open_id numeric, OUT p1 varchar, OUT p2 varchar, OUT p3 varchar) RETURNS SETOF RECORD AS $$
BEGIN
p1 := '1'; p2 := '2'; p3 := '3';
RETURN NEXT;
p1 := '3'; p2 := '4'; p3 := '5';
RETURN NEXT;
p1 := '3'; p2 := '4'; p3 := '5';
RETURN NEXT;
RETURN;
END;
$$ LANGUAGE plpgsql;