创建带动态日期后缀分区表的存储过程出现语法错误求助
问题
希望创建一个生成带动态表名的存储过程,接收日期参数并格式化为YYYYMMDD后追加到表名,用于创建分区表。编写的存储过程代码如下:
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
解决方法
问题出在变量类型定义上:你把to_char返回的字符串类型日期格式值,赋值给了int类型变量var_balancedate_。当使用format函数的%I占位符(用于标识符转义)处理数值类型时,PostgreSQL会自动给数值加上双引号,最终生成的SQL语句会变成:
create table if not exists l2.accounts_balances_"20231002" partition of l2.accounts_balances
带双引号的数字作为表名后缀不符合语法规范,因此触发报错。
有两种修正方式:
方式一:修正变量类型
把var_balancedate_的类型改为text,直接存储to_char返回的字符串:
CREATE OR REPLACE PROCEDURE l2.accounts_balances_load(var_balancedate date) LANGUAGE plpgsql AS $procedure$ 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_%I partition of l2.accounts_balances', var_balancedate_); end; $procedure$ ;
方式二:直接在format中处理日期(更简洁)
不需要额外变量,直接在format函数里调用to_char生成格式后的字符串:
CREATE OR REPLACE PROCEDURE l2.accounts_balances_load(var_balancedate date) LANGUAGE plpgsql AS $procedure$ begin execute format ('create table if not exists l2.accounts_balances_%I partition of l2.accounts_balances', to_char(var_balancedate, 'YYYYMMDD')); end; $procedure$ ;
执行修正后的存储过程,就能正常创建分区表l2.accounts_balances_20231002了。
内容的提问来源于stack exchange,提问作者ogkush
相关产品推荐
相关产品推荐

