jla*_*rcy 11 postgresql datatypes functions
我TYPE
在 PostgreSQL 中发现。我有一个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[]
);
Run Code Online (Sandbox Code Playgroud)
我可以使用此模板创建表:
CREATE TABLE test OF dataset;
Run Code Online (Sandbox Code Playgroud)
我在API 中看到了很多选项,但我有点迷茫。我想知道是否可以将此类型分配给函数INPUT/OUTPUT
参数。
假设我有一个FUNCTION
调用process
,它从数据集中接收记录样本TABLE
source
,处理它们,然后返回TABLE
sink
具有相同TYPE
.
那就是我想知道是否有可能创建一个TYPE
这样的行为:
CREATE FUNCTION process(
input dataset
) RETURNS dataset
AS ...
Run Code Online (Sandbox Code Playgroud)
可以这样调用:
SELECT
*
FROM
source, process(input := source) AS sink;
Run Code Online (Sandbox Code Playgroud)
我想知道 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);
Run Code Online (Sandbox Code Playgroud)
但它没有成功,就像 source 被视为一列而不是SETOF RECORDS
具有数据集类型的列。
Erw*_*ter 15
_source
MWE(最小工作示例)中的参数未在任何地方引用。source
函数体中的标识符没有前导下划线,独立解释为常量表名。
但无论如何它不会像这样工作。SQL 只允许参数化DML 语句中的值。看:
您仍然可以EXECUTE
在 plpgsql 函数中使用动态 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
Run Code Online (Sandbox Code Playgroud)
看:
或在网站上搜索相关问题和答案。
要使其适用于任何给定的表:
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!!
Run Code Online (Sandbox Code Playgroud)
详细解释:
小智 10
这将做你想做的事,而不需要任何动态 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
)
);
Run Code Online (Sandbox Code Playgroud)
据我所知(在广泛搜索之后,因为我遇到了同样的问题)你不能将表直接传递给函数。
但是,如图所示,您可以将表转换为由[]
多个基本类型组成的自定义类型的数组(类似于表定义)。
然后,您可以传递该数组,并在进入函数后将其取消嵌套回表中。
归档时间: |
|
查看次数: |
36686 次 |
最近记录: |