我正在尝试在Postgres中创建一个函数,如下所示:
Create function Samplefunc()
returns resultdata( Tested int, Score int,
Growth int) as
$BODY$
Select
Count(distinct student_id) Tested,
Cast(Avg(R.raw_score) as Int) Score,
Avg(R.growth) as Growth
from results R
where R.id=1 and test_id='ME04';
$BODY$
LANGUAGE sql;
但是我收到以下错误:
ERROR: syntax error at or near "int"
LINE 2: returns resultdata( NTested int, RawScore int,
^
********** Error **********
ERROR: syntax error at or near "int"
SQL state: 42601
Character: 59
我哪里错了?
答案 0 :(得分:2)
CREATE FUNCTION samplefunc()
RETURNS TABLE(ntested int, rawscore int, growth int) AS
$func$
SELECT count(DISTINCT r.student_id) -- AS NTested
,avg(r.raw_score)::int -- AS RawScore
,avg(r.growth)::int -- AS Growth
FROM reports_results r
WHERE r.test_type_id = 1
AND r.test_id = '201403MAME04'
$func$ LANGUAGE sql;
返回表格的子句是RETURNS TABLE
。
小心避免OUT
参数和列名之间的冲突。 (我的初稿中有这样的冲突)。表限定列以消除歧义。
RETURNS TABLE
中的所有字段名称都是有效的OUT
参数,并且在函数内部(几乎)无处可见。
此外:
avg(growth)
会导致类型与声明的返回类型int
不匹配。你也需要施展它。使用短Postgres-specific syntax ::type
,顺便说一句
更好的是:返回numeric
or a floating point number以保留平均数中的小数位数。
列别名仅在函数内可见。如果你不打算在里面引用它们这个函数,它们只是文档。
大写是什么? Unquoted identifiers are cast to lower case in Postgres automatically.
如果保证查询返回单个行,您可能希望将OUT
参数与RETURNS record
合并:
CREATE FUNCTION samplefunc(OUT ntested int, OUT rawscore int, OUT growth int)
RETURNS record AS ...
微妙的区别:这样,如果找不到任何内容,您将获得一个NULL
个值的行,其中第一个表单不会返回任何行/没有行。
CREATE FUNCTION samplefunc(_test_type_id int, _test_id text)
RETURNS TABLE(ntested int, rawscore int, growth int) AS
$func$
SELECT count(DISTINCT r.student_id)
,avg(r.raw_score)::int
,avg(r.growth)::int
FROM reports_results r
WHERE r.test_type_id = $1 -- or: = _test_type_id in Postgres 9.2+
AND r.test_id = $2 -- or: = _test_id
$func$ LANGUAGE sql;
这里的许多相关答案都有更多的代码示例。像:
答案 1 :(得分:1)
尽量不指定复合返回类型的详细信息。但是,我认为返回结构必须首先存在。
Create table resultdata (NTested int, RawScore int, Growth int);
Create function Samplefunc() returns resultdata as
$BODY$
Select
Count(distinct student_id) as NTested,
Cast(Avg(R.raw_score) as Int) as RawScore,
Avg(R.growth) as Growth
from reports_results R
where R.test_type_id=1 and test_id='201403MAME04';
$BODY$
LANGUAGE sql;
或尝试显式返回表格:
Create function Samplefunc()
returns Table (NTested int, RawScore int, Growth int) as
$BODY$
Select
Count(distinct student_id) as NTested,
Cast(Avg(R.raw_score) as Int) as RawScore,
Avg(R.growth) as Growth
from reports_results R
where R.test_type_id=1 and test_id='201403MAME04';
$BODY$
LANGUAGE sql;
我认为您还可以使用输出参数返回一组记录:
Create function Samplefunc(OUT NTested int, OUT RawScore int, OUT Growth int)
returns SetOf Record as
$BODY$
Select
Count(distinct student_id) as NTested,
Cast(Avg(R.raw_score) as Int) as RawScore,
Avg(R.growth) as Growth
from reports_results R
where R.test_type_id=1 and test_id='201403MAME04';
$BODY$
LANGUAGE sql;
答案 2 :(得分:1)
您正在尝试返回包含多个输出参数的记录。你应该这样做:
Create function Samplefunc(out NTested int, out RawScore int, out Growth int) as
$BODY$
Select
Count(distinct student_id) NTested,
Cast(Avg(R.raw_score) as Int) RawScore,
Avg(R.growth) as Growth
from reports_results R
where R.test_type_id=1 and test_id='201403MAME04';
$BODY$
LANGUAGE sql;
您可以使用明确命名的复合类型更详细地执行相同的操作;像
CREATE TYPE resultdata AS (NTested int, RawScore int, Growth int);
CREATE FUNCTION Samplefunc() RETURNS resultdata
AS .......
或使用像{/ p>这样的TABLE
函数
CREATE FUNCTION Samplefunc() RETURNS TABLE(NTested int, RawScore int, Growth int)
AS
......
有关相同
的更多信息,请参阅PostgreSQL Documentation答案 3 :(得分:0)
如果你没有像Luke那样定义一个“结果集”类型,那么请尝试返回一个表。
Create function Samplefunc()
returns table( NTested int, RawScore int,
Growth int) as
$BODY$
Select
Count(distinct student_id) NTested,
Cast(Avg(R.raw_score) as Int) RawScore,
Avg(R.growth) as Growth
from reports_results R
where R.test_type_id=1 and test_id='201403MAME04';
$BODY$
LANGUAGE sql;