Explicación detallada del acceso plsql por año y mes

Directorio de artículos

1. Información general

  • Escenarios de uso: cuando una parte del tiempo de consulta SQL es demasiado larga, puede dividir la consulta del período de tiempo , como: consultas anuales, consultas por mes

2 código fuente

-- *****************************************
-- 功能:按年取数(或 按月取数)
-- 说明:若想 "按月取数": add_months(v_start_date, 1)
-- *****************************************
DECLARE
  v_start_date DATE := DATE '2017-01-01'; -- 统计开始时间(依次变化)
  v_end_date   DATE := DATE '2020-09-30'; -- 统计结束时间(恒定不变)
  v_temp_date  DATE; -- 临时统计时间(用于记录时间的变换)
  v_cycles     PLS_INTEGER; -- 循环次数
BEGIN
  -- 若为小数,向上取整
  v_cycles := ceil(months_between(v_end_date, v_start_date) / 12);

  -- 默认赋值,方便下面判断
  v_temp_date := v_start_date;

  -- 主要逻辑:循环获取 "时间段"
  FOR each_year IN 1 .. v_cycles LOOP
    -- 大前提 
    IF v_end_date >= v_start_date THEN
      -- 当累加时间 不超过 '结束时间' 时,'统计结束时间' 为 v_temp_date
      IF v_end_date >= v_temp_date THEN
        -- 临时统计时间
        v_temp_date := add_months(v_start_date, 12); -- 按年取数 12 个月(1 年)
      
        -- 时间段
        dbms_output.put_line('循环次数:' || each_year);
        dbms_output.put_line('开始时间:' ||
                             to_char(v_start_date, 'YYYY-MM-DD HH24:MI:SS'));
        dbms_output.put_line('结束时间:' ||
                             to_char(v_temp_date, 'YYYY-MM-DD HH24:MI:SS'));
      
        -- 开始时间 和 结束时间变化
        v_start_date := v_temp_date;
        v_temp_date  := add_months(v_temp_date, 12);
      ELSE
        -- 当 时间累加超过 '结束时间' 时,'统计结束时间' 为 v_end_date
        dbms_output.put_line('循环次数:' || each_year);
        dbms_output.put_line('开始时间:' ||
                             to_char(v_start_date, 'YYYY-MM-DD HH24:MI:SS'));
        dbms_output.put_line('结束时间:' ||
                             to_char(v_end_date, 'YYYY-MM-DD HH24:MI:SS'));
      END IF;
    END IF;
  
    -- 增加空行,方便观察
    -- !!! 此处调用存储过程 !!!
    dbms_output.put_line('');
  END LOOP;
EXCEPTION
  WHEN OTHERS THEN
    dbms_output.put_line(dbms_utility.format_error_backtrace);
    dbms_output.put_line(SQLERRM);
END;

Supongo que te gusta

Origin blog.csdn.net/qq_34745941/article/details/108662596
Recomendado
Clasificación