【问题标题】:Error when setting n_distinct using a plpgsql variable使用 plpgsql 变量设置 n_distinct 时出错
【发布时间】:2016-07-01 17:17:59
【问题描述】:

我尝试使用函数来设置表的 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);

仍然收到以下错误:

ERROR:  invalid value for floating point option "n_distinct": _cnt
CONTEXT:  SQL statement "alter table _temp
         alter column id set (n_distinct=_cnt)"
PL/pgSQL function pg_temp_3.setdistinct(real) line 3 at SQL statement

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

【问题讨论】:

    标签: postgresql plpgsql dynamic-sql alter-table


    【解决方案1】:

    这是设计使然。手册在Variable Substitution一章中有说明:

    变量替换目前仅适用于SELECTINSERTUPDATE、 和DELETE 命令,因为主 SQL 引擎允许查询 仅在这些命令中的参数。使用非常量名称或值 在其他语句类型(通常称为实用程序语句)中,您 必须将实用程序语句构造为字符串和EXECUTE

    不能使用EXECUTE 参数化动态语句中的值,因为quoting the chapter Executing Dynamic Commands

    参数符号的另一个限制是它们只能在 SELECTINSERTUPDATEDELETE 命令。在其他语句类型中 (通常称为实用程序语句),您必须插入值 即使它们只是数据值,也可以以文本形式显示。

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

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

    架构限定 pg_temp. 使其成为(未记录的!)“临时”功能,反映了问题。
    关于n_distinct的手册。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-22
      • 1970-01-01
      • 2020-10-13
      • 2015-03-13
      • 2012-10-12
      • 1970-01-01
      相关资源
      最近更新 更多