Postgresql 使用plpgsql变量设置n_distinct时出错

Postgresql 使用plpgsql变量设置n_distinct时出错,postgresql,plpgsql,dynamic-sql,alter-table,Postgresql,Plpgsql,Dynamic Sql,Alter Table,我尝试使用一个函数来设置表的n_distinct值。代码如下: create temporary table _temp ( id integer ); create function pg_temp.setdistinct(_cnt real) returns void as $$ begin alter table _temp alter column id set (n_distinct=_cnt); end $$ language plpgsql; select pg

我尝试使用一个函数来设置表的n_distinct值。代码如下:

create temporary table _temp
(
  id integer
);

create function pg_temp.setdistinct(_cnt real)
returns void as $$
begin
  alter table _temp
    alter column id set (n_distinct=_cnt);
end
$$ language plpgsql;

select pg_temp.setdistinct(1000);
但仍会收到以下错误:


使用
EXECUTE
语句可以绕过这个问题,但是我想知道为什么我们不能在这个特定的查询中使用变量。有没有什么特别的规则我忽略了?

这是故意的。解释可在以下章节中找到:

变量替换当前仅适用于
选择
插入
更新
, 和
DELETE
命令,因为主SQL引擎允许查询 仅在这些命令中使用参数。使用非常量名称或值的步骤 在其他语句类型(一般称为实用程序语句)中,您可以 必须将实用程序语句构造为字符串并执行它

您不能使用
EXECUTE
参数化动态语句中的值,因为:

对参数符号的另一个限制是它们仅在
选择
插入
更新
删除
命令。在其他语句类型中 (通常称为实用程序语句),必须插入值 即使它们只是数据值,也是文本形式的

plpgsql函数中的唯一选项是将值连接到命令字符串中。您可以使用,但对于简单的示例,普通连接是安全且简单的:

CREATE OR REPLACE FUNCTION pg_temp.setdistinct(_cnt real)
  RETURNS void AS
$$
BEGIN
   EXECUTE 'ALTER TABLE _temp ALTER COLUMN id SET (n_distinct=' || _cnt || ')';
END
$$ LANGUAGE plpgsql;
对问题中类似的演示使用未记录的“临时”功能。
顺便说一句,大约

CREATE OR REPLACE FUNCTION pg_temp.setdistinct(_cnt real)
  RETURNS void AS
$$
BEGIN
   EXECUTE 'ALTER TABLE _temp ALTER COLUMN id SET (n_distinct=' || _cnt || ')';
END
$$ LANGUAGE plpgsql;