postgresql 在具有动态表名的过程中,在““20231002””处或附近出现错误

qv7cva1a  于 12个月前  发布在  PostgreSQL
关注(0)|答案(1)|浏览(113)

我想创建一个程序,它可以创建一个动态表名的表。它需要一个日期,格式和附加到表名。
我做了什么:

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


我做错了什么?

1u4esq0p

1u4esq0p1#

在这种情况下,您需要格式说明符%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说明符一起传递,以将其作为一个整体引用。
相关信息:

  • 触发器函数中具有动态表名的查询
  • 表名作为PostgreSQL函数参数
  • 在plpgsql函数中定义表名和列名作为参数?

相关问题