Dynamic SQL should be generated through format()
and parameters should not be passed as string literals, but through placeholders and using
.
Your code is really hard to read, incomplete and there are some substantial syntax errors which stem from e.g. a missing END
for the CASE and parentheses not properly paired. So the following code might still contain some errors as I apparently have no way of testing it.
But as your main SELECT does not seem to use dynamic SQL at all, all the quote_literal()
and string concatenation is unnecessary, just use the variables directly.
As max_date is supposed to be a date
value you can assign the string 'XXXXX'
to it, but if you use the max_date directly, you can get rid of that check as far as I can tell.
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', table_schema, 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, gs.date_, TIME
) as X
where (max_date = X.date_ and max_date <> current_date)
OR (max_date = current_date)
end;
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…