PL / pgSQL中的“格式不正确的数组文字”错误

时间:2019-11-22 12:26:47

标签: sql postgresql plpgsql

我在PL/pgSQL中遇到了一个错误:

  

“错误:格式不正确的数组文字:” 2019-11-22 09:18:07.248537“详细信息:   数组值必须以“ {”或维度信息开头。内容:   PL / pgSQL函数Chargelengtth()第11行位于SELECT行上方的“”

CREATE OR REPLACE FUNCTION chargelengtth() RETURNS text AS
$$
DECLARE chargetime integer;
DECLARE othertime integer;
DECLARE total integer;
DECLARE charge_length text[];
DECLARE chargestatus text;
DECLARE otherstatus text;
BEGIN
    total := 0;
    chargetime := 0;
FOR charge_length IN
    SELECT * FROM table_name
LOOP
    RAISE NOTICE 'Stuff: %', charge_length;
    IF(charge_length[diagnostic] = 'Charging' AND chargetime = 0) THEN
        chargetime := extract(epoch from charge_length[time]);
    END IF;

    IF(charge_length[diagnostic] != 'Charging') THEN
        othertime := extract(epoch from charge_length[time]);
        total := total + (othertime - chargetime);
        chargetime := 0;
    END IF;

END LOOP;
RETURN to_char(total * interval '1 sec','HH24h MIm');
END$$ LANGUAGE plpgsql;
SELECT * FROM chargelengtth()`

能否请您分享您的知识来解决此问题。

1 个答案:

答案 0 :(得分:1)

As documented in the manual,当您要遍历SELECT语句时,需要使用一个记录变量:

CREATE OR REPLACE FUNCTION chargelengtth() 
  RETURNS text AS
$$
DECLARE 
  chargetime integer;
  othertime integer;
  total integer;
  chargestatus text;
  otherstatus text;
  l_row record; --<< here
BEGIN
  total := 0;
  chargetime := 0;
  FOR l_row IN SELECT * FROM table_name
  LOOP
      RAISE NOTICE 'Stuff: %', l_row;
      IF (l_row.diagnostic = 'Charging' AND chargetime = 0) THEN
          chargetime := extract(epoch from l_row.time);
      END IF;

      IF (l_row.diagnostic != 'Charging') THEN
          othertime := extract(epoch from l_row.time);
          total := total + (othertime - chargetime);
          chargetime := 0;
      END IF;

  END LOOP;
  RETURN to_char(total * interval '1 sec','HH24h MIm');
END$$ LANGUAGE plpgsql;

SELECT chargelengtth()

据我所知,您可以用一个SELECT语句替换它。假设time列为timestamp,我认为,以下内容与您的工作相同(末尾interval的格式除外) :

with ct (chargetime) as (
  select time 
  from table_name
  where diagnostic = 'Charging'
  limit 1
)
select sum(t.time - ct.chargetime) 
from the_table t
  cross join ct
where t.diagnostic <> 'Charging'

chargetime的检索有些混乱,因为您似乎依赖于某些行的顺序,但是查询没有order by。没有limit 1的{​​{1}}基本上是一样的,但是如果您想获得可重复的结果,则应该指定一个order by(也用于FOR循环语句)