I want to create procedure which can create a table with dynamic table name. It takes a date, formats and appends it to the table name.
What I did:
CREATE OR REPLACE PROCEDURE l2.accounts_balances_load(var_balancedate date)
LANGUAGE plpgsql
AS $procedure$
declare var_balancedate_ int = to_char(var_balancedate, 'YYYYMMDD') ;
begin
raise notice 'SQL:: %', var_balancedate_;
execute format ('create table if not exists l2.accounts_balances_%I partition of l2.accounts_balances', var_balancedate_);
end;
$procedure$
;
I call with:
call l2.accounts_balances_load('2023-10-02');
But I get error:
SQL Error [42601]: ERROR: syntax error at or near ""20231002""
Где: PL/pgSQL function l2.accounts_balances_load(date) line 9 at EXECUTE
What am I doing wrong?
You need the format specifier
%sinstead of%Iforformat()in this case. Like:Also, no point in coercing the formatted date in
var_balancedate_tointand back. I made ittext.The specifier
%Itreats the input as identifier and double-quotes the string if it wouldn't be valid otherwise. A string of digits gets double-quoted. The subsequent concatenation makes an illegal name.Now, your table name is an identifier, but you are only appending the number. You would have to double-quote the whole name. Since
var_balancedate_is assigned the result ofto_char(), we know the string is safe, so no SQL injection possible, and%sis fine.Else you would concatenate the whole table name, and pass it in with the
%Ispecifier to be quoted as a whole.Related: