大佬教程收集整理的这篇文章主要介绍了postgresql:在 pl pgsql 中使用时间戳变量,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我是使用 pl pgsql 的新手。我想连接两个变量,但我总是遇到相同的错误:time_ 变量未知
假设 date_ 是日期类型,而 time_ 是时间类型。错误来自这一行:
@H_404_4@sum(extract(epoch from (least(s.end,gs.date_+time_) - greatest(s.beg,gs.date_))) / 60) as Timing
我的代码在下面
@H_404_4@delcare
time_ time;
Begin
execute $$SELECT CURRENT_TIMESTAMP::time FROM $$||result_table INTO time_;
execute $$SELECT MAX(date_) FROM $$||result_table INTO max_date;
IF max_date is not NulL THEN
execute $$DELETE FROM $$||result_table||$$ WHERE date_ >= $$||quote_literal(max_date);
ELSE
max_date := 'XXXXXXX';
end if;
execute $$
INSERT INTO $$result_table$$
(ID,gs.date_,TIME,timing)
SELECT * from (
select
ID,(case
When TRIM(set) ~ '^OPT[0-9]{3}/MINUTE/$'
Then 'minute'
When TRIM(set) ~ '^OPT[0-9]{3}/SECOND/$'
Then 'second' as TIME,sum(extract(epoch from (least(s.end,gs.date_+time_) -
greatest(s.beg,gs.date_)
)
) / 60) as Timing
from source s cross join lateral
generate_serIEs(date_trunc('day',s.beg),date_trunc('day',least(s.end,CASE WHEN $$||quote_literal(max_date)||$$ = 'XXXXXXX'
THEN (current_date)
ELSE $$||quote_literal(max_date)||$$
END)
),interval '1 day') gs(date_)
where ( (beg,end) overlaps ($$||quote_literal(max_date)||$$'00:00:00',$$||quote_literal(max_date)||$$'23:59:59'))
group by ID,TIME
) as X
where ($$||quote_literal(max_date)||$$ = X.date_ and $$||quote_literal(max_date)||$$ != 'XXXXXXX')
OR ($$||quote_literal(max_date)||$$ ='XXXXXXX')
动态 SQL 应通过 format()
生成,并且参数不应作为字符串文字传递,而应通过占位符和 using
传递。
你的代码真的很难阅读,不完整,并且有一些实质性的语法错误源于例如CASE 缺少 END
且括号未正确配对。所以下面的代码可能仍然包含一些错误,因为我显然没有办法测试它。
但是由于您的主要 SELECT 似乎根本没有使用动态 SQL,所有 quote_literal()
和字符串连接都是不必要的,直接使用变量即可。
由于 max_date 应该是一个 date
值,您可以将字符串 'XXXXX'
分配给它,但是如果您直接使用 max_date,就我所知,您可以摆脱该检查.
declare
time_ time;
max_date date;
result_table text := 'contract_frequency';
table_schema text := 'public';
Begin
time_ := localtime;
execute format('SELECT MAX(date_) FROM %I.%I',table_schema,result_table) into INTO max_date;
IF max_date is not NULL THEN
execute format('DELETE FROM %I.%I WHERE date_ >= $1',result_table) using max_date;
ELSE
-- you replace XXXX with current_date in the CASE expression
-- later on,so using current_date here seems the right thing to do
max_date := current_date;
end if;
SELECT *
from (
select
Id,gs.date_,case
When TRIM(set) ~ '^OPT[0-9]{3}/MINUTE/$' Then 'minute'
When TRIM(set) ~ '^OPT[0-9]{3}/SECOND/$' Then 'second' as TIME,end
sum(extract(epoch from (least(s.end,gs.date_+time_) - greatest(s.beg,gs.date_) ) ) / 60) as Timing
from source s
cross join lateral
generate_series(date_trunc('day',s.beg),date_trunc('day',least(s.end,max_date)),interval '1 day') gs(date_)
where (beg,end) overlaps (max_date::timestamp,max_date + time '23:59:59')
group by id,TIME
) as X
where (max_date = X.date_ and max_date <> current_date)
OR (max_date = current_date)
end;
以上是大佬教程为你收集整理的postgresql:在 pl pgsql 中使用时间戳变量全部内容,希望文章能够帮你解决postgresql:在 pl pgsql 中使用时间戳变量所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。