PostgreSQLでTYPE
を発見しました。一部のテーブルが遵守しなければならないTABLE TYPE
があります(インターフェース)。例えば:
CREATE TYPE dataset AS(
ChannelId INTEGER
,GranulityIdIn INTEGER
,GranulityId INTEGER
,TimeValue TIMESTAMP
,FloatValue FLOAT
,Status BIGINT
,QualityCodeId INTEGER
,DataArray FLOAT[]
,DataCount BIGINT
,Performance FLOAT
,StepCount INTEGER
,TableRegClass regclass
,Tags TEXT[]
,WeightedMean FLOAT
,MeanData FLOAT
,StdData FLOAT
,MinData FLOAT
,MaxData FLOAT
,MedianData FLOAT
,Percentiles FLOAT[]
);
このテンプレートを使用してテーブルを作成できます:
CREATE TABLE test OF dataset;
[〜#〜] api [〜#〜] に多くのオプションを見てきましたが、少し迷っています。このタイプを関数INPUT/OUTPUT
パラメータに割り当てることができるかどうか知りたいのですが。
データセットFUNCTION
process
からレコードのサンプルを受け取り、それらを処理して、同じTABLE
でsource
TABLE
を返すsink
というTYPE
があるとします。
つまり、次のように動作するTYPE
を作成できるかどうかを知りたいです。
CREATE FUNCTION process(
input dataset
) RETURNS dataset
AS ...
そしてそれは次のように呼び出すことができます:
SELECT
*
FROM
source, process(input := source) AS sink;
PostgreSQLでも可能だと思いますので、その方法についてお聞きします。誰か知っていますか?
ここに私がやろうとしていることのMWEがあります:
DROP TABLE IF EXISTS source;
DROP FUNCTION IF EXISTS process(dataset);
DROP TYPE dataset;
CREATE TYPE dataset AS (
id INTEGER
,t TIMESTAMP
,x FLOAT
);
CREATE TABLE source OF dataset;
ALTER TABLE source ADD PRIMARY KEY(Id);
INSERT INTO source VALUES
(1, '2016-01-01 00:00:00', 10.0)
,(2, '2016-01-01 00:30:00', 11.0)
,(3, '2016-01-01 01:00:00', 12.0)
,(4, '2016-01-01 01:30:00', 9.0)
;
CREATE OR REPLACE FUNCTION process(
_source dataset
)
RETURNS SETOF dataset
AS
$BODY$
SELECT * FROM source;
$BODY$
LANGUAGE SQL;
SELECT * FROM process(source);
しかし、それは成功しません。ソースが、データセットのタイプを持つSETOF RECORDS
ではなく、列として認識されるようです。
追加されたMWEのパラメーター_source
はどこからも参照されません。関数本体の識別子source
には先頭に下線がなく、独立して定数テーブル名として解釈されます。
さらに重要なことに、それはとにかくこのように機能しません。 SQLは、DMLステートメントでvaluesのパラメーター化のみを許可します。この関連する回答の詳細:
それでも、plpgsql関数でEXECUTE
を使用した動的SQLを使用して機能させることができます。詳細:
または関連する質問と回答については、この検索を試してください
CREATE TYPE dataset AS (id integer, t timestamp, x float);
CREATE TABLE source OF dataset (PRIMARY KEY(Id)); -- add constraints in same command
INSERT INTO source VALUES
(1, '2016-01-01 00:00:00', 10.0)
,(2, '2016-01-01 00:30:00', 11.0);
CREATE OR REPLACE FUNCTION process(_tbl regclass)
RETURNS SETOF dataset AS
$func$
BEGIN
RETURN QUERY EXECUTE 'SELECT * FROM ' || _tbl;
END
$func$ LANGUAGE plpgsql;
SELECT * FROM process('source'); -- table name as string literal
これをanyの特定のテーブルに対して機能させることもできます。
CREATE OR REPLACE FUNCTION process2(_tbl anyelement)
RETURNS SETOF anyelement AS
$func$
BEGIN
RETURN QUERY EXECUTE 'SELECT * FROM ' || pg_typeof(_tbl);
END
$func$ LANGUAGE plpgsql;
SELECT * FROM process2(NULL::source); -- note the call syntax!!
詳細な説明:
これはあなたが望むことを行いますなし必要動的SQL:
drop table if exists source cascade;
drop function if exists process(dataset) cascade;
drop type if exists dataset cascade;
create type dataset as (
id integer
,t timestamp
,x float
);
create table source of dataset;
alter table source add primary key(id);
insert into source values
(1, '2016-01-01 00:00:00', 10.0)
, (2, '2016-01-01 00:30:00', 11.0)
;
create or replace function process(
x_source dataset[]
)
returns setof dataset
as
$body$
select * from unnest(x_source);
$body$
language sql;
select *
from
process(
array(
select
row(id, t, x)::dataset
from source
)
);
(私が同じ問題を抱えていたためにグーゲル化した後)私が知る限り、テーブルを関数に直接渡すことはできません。
ただし、図に示すように、テーブルをいくつかの基本的なタイプ(テーブル定義と同様)で構成されるカスタムタイプの配列[]
に変換できます。
次に、関数に入ったら、その配列を渡して、ネストを解除してテーブルに戻すことができます。