0

I want to run this code but got this error

HINT: No function matches the given name and argument types. You might need to add explicit type casts.

execute $$SELECT MAX(date) FROM $$||table_name INTO datum;
IF datum is not NULL THEN

      execute $$DELETE FROM $$||table_name||$$ WHERE date >= $$||quote_literal(datum);
ELSE
      datum := $$2001-01-01$$;
end if;
execute $$
INSERT INTO $$||table_name||$$
(number, date, departement, minutes)
 select
     number, gs.date,

where (beg, enddate) overlaps (concat($$||quote_literal(datum)||$$, '00:00:00'), concat($$||quote_literal(datum)||$$, '23:59:59'))

Let's notice also that where (beg, enddate) overlaps (concat($$||quote_literal(datum)||$$, '00:00:00'), concat($$||quote_literal(datum)||$$, '23:59:59')) want to do it only when datum != $$2001-01-01$$; (not for the first iteration).

Thank you,

6
  • || is enough. Commented Sep 24, 2020 at 13:00
  • what do you mean please.? @ceving Commented Sep 24, 2020 at 13:01
  • || is already a concatenation operator, which concatenates. So, you won't need to use concat additionally. Read more here postgresql.org/docs/9.1/functions-string.html Commented Sep 24, 2020 at 13:05
  • What data type is datum? Commented Sep 24, 2020 at 13:09
  • i see i did this before $$||quote_literal(datum)||$$ '00:00:00' and got error also:::::::: psycopg2.ProgrammingError: syntax error at or near ""00:00:00"" Commented Sep 24, 2020 at 13:09

1 Answer 1

1

When using dynamic SQL, it's better to use format() to construct the SQL and use placeholders for parameters so that you don't need to cast values back and forth:

execute format('SELECT MAX(date) FROM %I', table_name) 
   INTO datum;

IF datum is not NULL THEN
      execute format('DELETE FROM %I WHERE date >= $1', table_name)
          using datum;
ELSE
   datum := date '2001-01-01'; 
end if;

execute format('
INSERT INTO %I
(number, date, departement, minutes)
select
     number, gs.date,
      (case
            when trim(string) ~ '^ADM[0-9]$'
              or TRIM(string) ~ '^ADM[0-9]$'
       then 'ADMINISTRATION'
      end) as departement,
sum(extract(epoch from (least(s.enddate, gs.date + interval '1 day' -
                           greatest(s.beg, gs.date)
                          )
              ) / 60) as minutes
from smp s 
  cross join lateral generate_series(date_trunc('day', s.beg), date_trunc('day', least(s.enddate, current_date)), interval '1 day') gs(date)
where (beg, enddate) overlaps ($1 + time '00:00:00', $1 + time '23:59:59'))', table_name)
using datum; -- pass the parameter as a proper date
Sign up to request clarification or add additional context in comments.

9 Comments

thank you but im gotting error saying that psycopg2.ProgrammingError: column "datum" does not exist Notice that datum is a variable not a column. @a_horse_with_no_name
@biwia: well your query uses a column datum and you told me the data type of that column is date. I can only use the information you provide. Or did you mean to reference the date column from generate_series()?
@a_horse_with_name sorry its my fault I created like this. Sorry i was not clear execute $$SELECT MIN(sign_in_date) FROM $$||table_name INTO datum;
So that's part of a larger PL/pgSQL function? Then please edit your question and show us the complete function. The whole query doesn't really make sense to me to begin with. And why the $$ quoting around the select that makes no sense either
thank you, post edited. Please have a look @a_horse_with_no_name
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.