循环不是从generate_series循环

时间:2019-01-01 22:20:38

标签: postgresql plpgsql

我正在创建一个plpgsql函数来填充查找表以获取日期信息。我的循环语句仅执行第一个日期,没有循环其他几天。

  DECLARE
startDate ALIAS FOR $1;
endDate ALIAS FOR $2;
currentDate date;
dateDate integer;
yearDate integer;
monthDate integer;
dayDate integer;
weekDate integer;
dayofWeekDate integer;
weekofYearDate integer;
quarterDate integer;

BEGIN
DELETE FROM date_data;

FOR currentDate IN (SELECT * FROM generate_series(startDate::date,endDate::date,'1 day') s(currentDate)) LOOP
    yearDate := (SELECT date_part('year', currentDate));
    monthDate := (SELECT date_part('month', currentDate));
    dayDate := (SELECT date_part('day', currentDate));
    weekDate := (SELECT date_part('week', currentDate));
    dayofWeekDate := (SELECT date_part('dow', currentDate));
    quarterDate := (SELECT date_part('quarter', currentDate));
    weekofYearDate := (SELECT date_part('week', currentDate));
    dateDate := to_char(currentDate,'YYYYMMDD');

    INSERT INTO date_data VALUES ( dateDate, yearDate, monthDate, dayDate, FALSE, dayofWeekDate, FALSE, NULL, FALSE, NULL, weekofYearDate, quarterDate);

    RETURN dateDate;
END LOOP;
END;

我希望它会在时间序列中循环插入期望值,但是它只是插入第一个日期而不会继续。

我正在使用SELECT add_date_data2('2018-01-01','2019-01-01');

谢谢。

1 个答案:

答案 0 :(得分:0)

您的代码使用了很多会大大降低性能的反模式

  1. 循环查询而不是int循环

    FOR IN SELECT * FROM generate_series ..
    
  2. 分配中无用的查询

    var := (SELECT expr)
    

因此您的代码可以重写为一个SQL INSERT

INSERT INTO date_data
   SELECT to_char(d::date,'YYYYMMDD'),
          date_part('year', d::date),
          ...
     FROM generate_series(startdate::date, enddate::date, '1day') g(d);               

或非常经典:

WHILE d < enddate
LOOP
  yearDate := date_part('year', currentDate);
  monthDate := date_part('month', currentDate);
  dayDate := date_part('day', currentDate);

  INSERT INTO date_data VALUES ( dateDate, yearDate, monthDate, dayDate, FALSE ...
  d := d + interval '1day';
END LOOP;

表达式的计算速度比功能相同的查询快10倍-因此仅在必要时使用查询-而且,您的代码将更具可读性和简洁性。