-1

我是 postgres 函数的新手,我尝试使用函数在工作时间工作,当我结合这两个函数时出现以下错误。

我只想要一个超过 2 个日期范围并在几分钟内返回结果的函数。

第一个功能:获取日期范围内的时间。
运行:SELECT f_work('2013-09-13 06:00','2013-09-13 07:00')
结果:01:00

CREATE OR REPLACE FUNCTION public.f_work (
  t_start timestamp,
  t_end timestamp
)
RETURNS interval AS
$body$
SELECT (count(*) - 1) * interval '1 min'
FROM   (
   SELECT $1 + generate_series(0, (extract(epoch FROM $2 - $1)/60)::integer)
             * interval '1 min' AS t
   ) sub
WHERE  extract(ISODOW from t) > 0
AND    t::time >= '06:00'::time
AND    t::time <  '19:00'::time
$body$
LANGUAGE 'sql'

第二个功能:以分钟为单位转换时间。
运行:选择 to_min('01:00')
结果:60

CREATE OR REPLACE FUNCTION to_min(t text)
  RETURNS integer AS
$BODY$ 
DECLARE 
    hs INTEGER;
    ms INTEGER;
BEGIN
    SELECT (EXTRACT(HOUR FROM  t::time) * 60) INTO hs; 
    SELECT (EXTRACT(MINUTES FROM t::time)) INTO ms;
    SELECT (hs + ms) INTO ms;
    RETURN ms;
END;
$BODY$
LANGUAGE 'plpgsql';

加入我得到的两个函数和错误:
错误:查询没有结果数据的目的地提示:如果要丢弃 SELECT 的结果,请改用 PERFORM。上下文:SQL 语句中的 PL/pgSQL 函数“f_bizwork”第 6 行

CREATE OR REPLACE FUNCTION f_bizwork(t_start timestamp,t_end timestamp)
  RETURNS integer AS
$BODY$
DECLARE 
    hs INTEGER;
    ms INTEGER;
BEGIN
SELECT (count(*) - 1) * interval '1 min'
FROM   (
   SELECT $1 + generate_series(0, (extract(epoch FROM $2 - $1)/60)::integer)
             * interval '1 min' AS t
   ) sub
WHERE extract(ISODOW from t) >0 
AND    t::time >= '06:00'::time
AND    t::time <  '19:01'::time;

SELECT (EXTRACT(HOUR FROM  sub::time) * 60) INTO hs; 
SELECT (EXTRACT(MINUTES FROM sub::time)) INTO ms;
 SELECT (hs + ms) INTO ms;
RETURN ms;
END;
$BODY$
LANGUAGE 'plpgsql';
4

1 回答 1

1

您必须将第一个查询的结果存储在某处。否则 PostgreSQL 不知道如何处理查询结果并报告“查询没有目的地”。

这将做到:

CREATE OR REPLACE FUNCTION f_bizwork(t_start timestamp,t_end timestamp)
  RETURNS integer AS
$BODY$
DECLARE 
    hs INTEGER;
    ms INTEGER;
    sub time;
BEGIN
SELECT into sub (count(*) - 1) * interval '1 min'
FROM   (
   sELECT $1 + generate_series(0, (extract(epoch FROM $2 - $1)/60)::integer)
             * interval '1 min' AS t
   ) sub
WHERE extract(ISODOW from t) >0 
AND    t::time >= '06:00'::time
AND    t::time <  '19:01'::time;

SELECT (EXTRACT(HOUR FROM  sub::time) * 60) INTO hs; 
SELECT (EXTRACT(MINUTES FROM sub::time)) INTO ms;
 SELECT (hs + ms) INTO ms;
RETURN ms;
END;
$BODY$
LANGUAGE 'plpgsql';

select f_bizwork('2013-09-13 06:00','2013-09-13 07:00')

重要的行以 开头SELECT into sub。这会将查询结果存储到变量sub中,该变量在第二个查询中被引用。

于 2013-09-14T11:20:39.643 回答