Postgres创建函数时出错

时间:2014-08-14 17:20:10

标签: sql postgresql user-defined-functions

我正在尝试在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

我哪里错了?

4 个答案:

答案 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参数,并且在函数内部(几乎)无处可见。

此外:

如果保证查询返回单个行,您可能希望将OUT参数与RETURNS record合并:

CREATE FUNCTION samplefunc(OUT ntested int, OUT rawscore int, OUT growth int) 
  RETURNS record  AS ...

微妙的区别:这样,如果找不到任何内容,您将获得一个NULL个值的行,其中第一个表单不会返回任何行/没有行。

添加IN参数(评论中的请求)

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;

这里的许多相关答案都有更多的代码示例。像:

Try a search.

答案 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;