首页 > 解决方案 > 将 execute$$ 替换为 plpgsql 格式

问题描述

我使用 pl pgsql 创建函数,我无法将我的插入查询转换为如下所述以格式化动态 sql,我尝试了两天并没有得到它。这是我在这里的第一家酒吧 有人可以帮忙吗?

谢谢,

** 我的代码是**

execute $$
  INSERT INTO $$result_table$$
  (Id, ts.date_, flo_nbr, duration)
  SELECT * from (
     select
     Id, ts.date_,
    (case
     When TRIM(set) ~ '^H[0-9]{1}/FLO0R0/$'
     Then 'FLO0R0'
     When TRIM(set) ~ '^H[0-9]{1}/FLOOR1/$'
     Then 'FLOOR1'
     end) as flo_nbr,
     sum(extract(epoch from (least(s.end, ts.date_+time_) -
           greatest(s.beg, ts.date_)
          )
    )) as duration
   from source s cross join lateral
   generate_series(date_trunc('day', s.beg), date_trunc('day',
     least(s.end,
     CASE WHEN $$||quote_literal(date_construction)||$$ = '2012-01-01'
     THEN (current_date)
     ELSE $$||quote_literal(date_construction)||$$
     END)
    ), interval '1 day') ts(date_)
    where ( (beg, end) overlaps ($$||quote_literal(date_construction)||$$'00:00:00',      $$||quote_literal(date_construction)||$$'23:59:59'))
    group by id, ts.date_, flo_nbr
    ) as temp
where ($$||quote_literal(date_construction)||$$ = temp.date_  and 
$$||quote_literal(date_construction)||$$ != '2012-01-01')
OR  ($$||quote_literal(date_construction)||$$ ='2012-01-01')

标签: postgresqldynamic-sql

解决方案


我不会为你翻译这段难以理解的,呃,代码,但我会告诉你其中的诀窍。

代替

EXECUTE $$INSERT INTO $$ || result_table || $$ (...)
          SELECT ... FROM ...
          WHERE $$ || quote_literal(date_construction) || $$ = '2012-01-01'$$;

你会写

EXECUTE
   format(
      $$INSERT INTO %I (...)
        SELECT ... FROM ...
        WHERE %L = '2012-01-01'$$,
      result_table,
      date_construction
   );

%I将参数格式化为 SQL 标识符,即在必要时用双引号将其括起来,并将%L参数格式化为字符串文字,即用单引号正确引用。

更好的是使用USING子句作为参数,如下所示:

EXECUTE
   format(
      $$INSERT INTO %I (...)
        SELECT ... FROM ...
        WHERE $1 = '2012-01-01'$$,
      result_table,
   )
   USING date_construction;

请注意,您不能将参数用于标识符,因此您必须坚持format使用这些参数。

其余的留给读者作为练习。


推荐阅读