PostgreSQL:无法为函数中的变量分配“SELECT”查询

时间:2014-04-02 09:10:40

标签: postgresql plpgsql

我正在尝试将“SELECT”查询分配给特定变量以供进一步使用,但会收到错误。详细信息如下图所示。

示例:使用两个参数columnname和relationname创建函数,并希望相应地检索行。

- 功能

create or replace function function1(columnname varchar,relationname varchar)
returns setof record as
$body$

declare
    --Declaration of variables used ahead
    str varchar;
    additionalcolumn varchar;
    grp varchar;
    selectquery varchar;
begin
    --IF condition to check "columnname" for first condition.
    if columnname='PhoneNo2' then
         str:='PhoneNo2';
         additionalcolumn:='Tower'||','||'State'||','||'Country';
         grp:='PhoneNo1'||','||columnname; 

          .
          . -- Other conditions 
          .

        end if;

       selectquery := 'select "PhoneNo1",'||str||', count(*) AS "Total-Calls"
        , sum("Duration") AS "Total-Duration"
        , count("TypeOfCall" = 'CALL-IN'  OR NULL) AS "Call-In"
        , count("TypeOfCall" = 'CALL-OUT' OR NULL) AS "Call-Out"
        , count("TypeOfCall" = 'SMS-IN'   OR NULL) AS "SMS-In"
        , count("TypeOfCall" = 'SMS-OUT'  OR NULL) AS "SMS-Out"
        , min("CallDate") AS "First-Call-Date"
        , max("CallDate") AS "Last-Call-Date"
        , (max("CallDate")-min("CallDate")) AS "Days"
        ,'||additionalcolumn|| 
           ' from '||relationname
        group by grp;

--Query "selectquery" execution
return query execute selectquery;

end;
$body$
language plpgsql;

- 调用函数

select * from function1("PhoneNo2","table1") 
as ("PhoneNo1" varchar(20),"PhoneNo2" varchar(20), "Total-Calls" bigint,
"Total-Duration" bigint,"Call-In" bigint,"Call-Out" bigint, "SMS-In" bigint,
"SMS-Out" bigint,"First-Call-Date" date,"Last-Call-Date" date, "Days" bigint,
"Tower" varchar,"State" varchar,"Country" varchar);

- 发生错误

ERROR:  syntax error at or near "-"
LINE 46:    ', "count("TypeOfCall" = 'CALL-IN'  OR NULL) AS "Call-In"... 

1 个答案:

答案 0 :(得分:1)

这些方面的东西可行:

CREATE OR REPLACE FUNCTION function1(columnname text, relationname regclass)
  RETURNS SETOF record AS
$func$
DECLARE
    str text;
    additionalcolumn text;
    grp text;
    selectquery text;
BEGIN
   --IF condition to check "columnname" for first condition.
   IF columnname = 'PhoneNo2' then
         str := ', "PhoneNo2"';                 -- double-quote
         additionalcolumn := 
               ', max("Tower") AS t, max("State") AS s, max("Country2") AS c';
         grp :='1, 2';              -- simpler with positional parameters
   ELSE                                         -- can't have NULL values 
         str := '';
         additionalcolumn := '';
         grp :='1'; 
   END IF;

RETURN QUERY EXECUTE         -- use dollar quoting to allow single quotes
   'select "PhoneNo1"' || str || $$, count(*) AS "Total-Calls"
    , sum("Duration") AS "Total-Duration"
    , count("TypeOfCall" = 'CALL-IN'  OR NULL) AS "Call-In"
    , count("TypeOfCall" = 'CALL-OUT' OR NULL) AS "Call-Out"
    , count("TypeOfCall" = 'SMS-IN'   OR NULL) AS "SMS-In"
    , count("TypeOfCall" = 'SMS-OUT'  OR NULL) AS "SMS-Out"
    , min("CallDate") AS "First-Call-Date"
    , max("CallDate") AS "Last-Call-Date"
    , max("CallDate") - min("CallDate") AS "Days" 
  $$ || additionalcolumn || '
   from ' || relationname || '
   group by ' || grp;

END
$func$  LANGUAGE plpgsql;

有太多错误和问题需要解释。与您的原始相比,看看我改变了什么。使用标记搜索相关答案。此处的每个问题的详细说明已在相关答案中公布。

使用legal, lower-case identifiers可以让您的生活更轻松。