PostgreSQL函数:查询包含时间分区字段的表,并更新dt分区为最新分区

一、需求

1、背景

提出新需求后,需要在www环境下进行验收。故需要将www环境脚本每天正常调度

但由于客户库无法连接,ods数据无法每日取,且连不上客户库任务直接报错,不会跑ods之后的任务

故需要让调度正常运行,且能在事实表中看到最新的分区,有的脚本从ods中取数据时取的是where dt=(select max(dt) from ods.xxx)

但有的脚本取的是where dt = to_char(now(),'yyyymmdd'),故运行时,事实表获取不到当日数据

故需要本函数用于更新dt字段

2、需求

找包含dt字段的表,并将这些表的dt值更新为最近的dt

二、函数内容

1、函数内容

CREATE OR REPLACE FUNCTION "ods"."upd_dt_newly_to_now"()
  RETURNS "pg_catalog"."void" AS $BODY$
  DECLARE arrat_t varchar[];
	DECLARE tb_each VARCHAR;
  BEGIN
        select array(SELECT DISTINCT
        C.relname
        FROM
        pg_class AS C,
        pg_attribute AS A,
        pg_tables AS B
        WHERE A.attrelid = C.oid
        and C.relname = B.tablename
        AND A.attnum > 0
        AND B.schemaname = 'ods'
        AND B.tablename NOT SIMILAR TO '[a-z,_]+_2022[0-9]+'
        AND A.attname = 'dt') into arrat_t;
		foreach tb_each in array arrat_t
        loop
            -- 删除表
            raise  notice '更新表 %',tb_each;
            EXECUTE format('update ods.%s set dt=to_char(now(),''yyyymmdd'') where dt = (select max(dt) from ods.%s)', tb_each,tb_each);
        end loop;
  END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100

2、调用方式

select "ods"."upd_dt_newly_to_now"();

3、任务编排

连不上客户库时执行,实现同一个脚本可以同时在公司环境和线上同时执行

三、实现过程

-- 一、需求
-- 找到ods层包含dt字段的表
-- 找dt字段,更新dt为今天
-- 二、查询表名
-- 1、查询ods的所有表
select tablename,*
from pg_tables
where schemaname = 'ods';

-- 2、查询ods下包含dt的表名
SELECT DISTINCT
	C.relname
FROM
	pg_class AS C,
	pg_attribute AS A,
	pg_tables AS B
WHERE A.attrelid = C.oid
  and C.relname = B.tablename
  AND A.attnum > 0
  AND B.schemaname = 'ods'
  AND B.tablename NOT SIMILAR TO '[a-z,_]+_2022[0-9]+'
  AND A.attname = 'dt';

-- 二、更新日期
-- 1、更新语句
update ods.icsaleentry set dt=to_char(now(),'yyyymmdd') where dt = (select max(dt) from ods.icsaleentry);

-- 三、思路
-- 1、查询所有表名到数组

-- 2、更新表的日期

-- 四、函数编写
CREATE OR REPLACE FUNCTION "ods"."upd_dt_newly_to_now"()
  RETURNS "pg_catalog"."void" AS $BODY$
  DECLARE arrat_t varchar[];
	DECLARE tb_each VARCHAR;
  BEGIN
        select array(SELECT DISTINCT
        C.relname
        FROM
        pg_class AS C,
        pg_attribute AS A,
        pg_tables AS B
        WHERE A.attrelid = C.oid
        and C.relname = B.tablename
        AND A.attnum > 0
        AND B.schemaname = 'ods'
        AND B.tablename NOT SIMILAR TO '[a-z,_]+_2022[0-9]+'
        AND A.attname = 'dt') into arrat_t;
		foreach tb_each in array arrat_t
        loop
            -- 删除表
            raise  notice '更新表 %',tb_each;
            EXECUTE format('update ods.%s set dt=to_char(now(),''yyyymmdd'') where dt = (select max(dt) from ods.%s)', tb_each,tb_each);
        end loop;
  END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

-- 五、调用
select ods.upd_dt_newly_to_now();

 

posted @ 2022-11-12 14:29  哥们要飞  阅读(299)  评论(0编辑  收藏  举报