PostgreSQL ERROR: $2 is declared CONSTANT

今天有开发的同事咨询在执行函数报错的问题,主要问题出现在更改入参上,仿照这个函数,创建以下测试函数,用来重现错误信息,数据库版本 8.4。

创建测试函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 CREATE OR REPLACE FUNCTION func_create_daily_table(table_name character varying, table_num integer)
 RETURNS void
 LANGUAGE plpgsql
AS $function$
declare
    today        char(8);
   v_childtable character varying;
begin
IF table_num is null then
   table_num :=1;
END IF;
  for i in 0 .. table_num loop
    v_childtable := table_name || '_' || to_char(current_date + i, 'YYYYMMDD')  ;
    execute 'create table ' || v_childtable || '(like ' || table_name || ' including all ) inherits (' || table_name || ')';
  end loop;
end;
$function$;

报错信息

1
psql:creaet_func.sql:129: ERROR:  "$2" is declared CONSTANT

备注:这里提示入参 $1 被定义成常量,且不能修改,报错的数据库版本为 8.4,接下来在 9.0 版本测试。

9.0 版本测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[pg90@redhatB ~]$ psql francs francs
psql (9.0.9)
Type "help" for help.

francs=> CREATE OR REPLACE FUNCTION func_create_daily_table(table_name character varying, table_num integer)
francs->  RETURNS void
francs->  LANGUAGE plpgsql
francs-> AS $function$
francs$> declare
francs$>     today        char(8);
francs$>    v_childtable character varying;
francs$> begin
francs$
francs$> IF table_num is null then
francs$>    table_num :=1;
francs$> END IF;
francs$
francs$>   for i in 0 .. table_num loop
francs$>     v_childtable := table_name || '_' || to_char(current_date + i, 'YYYYMMDD')  ;
francs$>     execute 'create table ' || v_childtable || '(like ' || table_name || ' including all ) inherits (' || table_name || ')';
francs$>   end loop;
francs$> end;
francs$> $function$;
CREATE FUNCTION

备注:在9.0 版本测试是正常的,猜测可能是 8.4 版本的一个 bug ,但在官网邮件列表里没有查到明确定位是bug 的信息,唯一相关的内容是以下这个帖子,遇到的问题类似,但下面用到了参数 ALIAS ,情况不太一样,有兴趣的朋友可以看下。

解决方法

主要有两种解决方法:

1. 在函数中额外使用中转变量,将入参的值先赋给中转变量,然后再去修改中转变量的值。  
2. 升级数据库版本。

参考

原创文章,作者:506227337,如若转载,请注明出处:https://blog.ytso.com/237997.html

(0)
上一篇 2022年1月29日
下一篇 2022年1月29日

相关推荐

发表回复

登录后才能评论