我想创建可以创建具有动态表名的表的过程。它需要一个日期、格式并将其附加到表名称中。
我做了什么:
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$
;
我打电话的方式:
call l2.accounts_balances_load('2023-10-02');
但是我收到错误:
SQL Error [42601]: ERROR: syntax error at or near ""20231002""
Где: PL/pgSQL function l2.accounts_balances_load(date) line 9 at EXECUTE
我做错了什么?
%s
而不是 %I
来表示 format()
。喜欢:
CREATE OR REPLACE PROCEDURE l2.accounts_balances_load(var_balancedate date)
LANGUAGE plpgsql AS
$proc$
DECLARE
var_balancedate_ text := to_char(var_balancedate, 'YYYYMMDD');
BEGIN
RAISE NOTICE 'SQL:: %', var_balancedate_;
EXECUTE format(
'CREATE TABLE IF NOT EXISTS l2.accounts_balances_%s
PARTITION OF l2.accounts_balances', var_balancedate_);
END
$proc$;
此外,将
var_balancedate_
中的格式化日期强制为 int
并返回也没有意义。我做到了text
。
说明符
%I
将输入视为标识符,并在字符串无效时用双引号引起来。一串数字被双引号括起来。 后续串联产生了非法名称。
现在,您的表名称是一个标识符,但您仅附加数字。您必须用双引号引用整个名称。由于
var_balancedate_
被分配了 to_char()
的结果,我们知道该字符串是安全的,因此不可能进行 SQL 注入,并且 %s
没问题。%I
说明符一起传递以作为整体引用。
相关: