【问题标题】:Replace the execute$$ with plpgsql format将 execute$$ 替换为 plpgsql 格式
【发布时间】:2021-02-04 17:23:39
【问题描述】:

我使用 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')

【问题讨论】:

  • 你确定你和@biwia不是同一个人?这看起来与this code 太相似了,不可能是巧合。
  • 没有@LaurenzAlbe,但我会阅读他发布的内容。
  • 没有 plpgsql,你的 INSERT-SELECT-statement 应该是什么样子?当该部分工作时,只需将 WHERE 条件替换为动态项目。帮自己一个忙,开始使用 EXECUTE ... USING() 语句。 postgresql.org/docs/13/…
  • 为什么要为每个新问题注册一个新用户?

标签: postgresql dynamic-sql


【解决方案1】:

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

代替

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

剩下的留给读者作为练习。

【讨论】:

  • 好的,谢谢,现在更清楚了。我的问题是如何在插入中使用选择?你明白我的意思吗?能否请您添加一个我能理解的空白案例。好心
  • 日期的比较用execute format( ... where $1 = $2') using date_construction, date '2012-01-01'可能会更好
  • dsp,我试着充实一下这个例子。在 SQL 语句中包含 SELECT 和其他构造不会有什么不同。 @FrankHeikens 对您的问题的评论是黄金建议:首先尝试通过将占位符替换为值来让该怪物运行,一旦您确定它可以按照您的意愿工作,将其转换为带有占位符的动态 SQL。
  • @a_horse_with_no_name 如果这些日期是可变的,是的。如果它们是常量,将它们作为字符串文字的一部分会更有意义。
猜你喜欢
  • 1970-01-01
  • 2021-12-02
  • 2012-05-15
  • 2021-11-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-10
  • 2022-12-19
  • 2015-05-25
相关资源
最近更新 更多