使用plpgsql变量设置n_distinct时出错

时间:2016-03-16 01:34:08

标签: postgresql plpgsql dynamic-sql alter-table

我尝试使用函数为表设置n_distinct值。代码如下:

A = LOAD 'file1.txt' AS (a1:chararray,a2:chararray,a3:chararray);
B = LOAD 'file2.txt' AS (b1:chararray,b2:chararray);
C = JOIN A BY a2, B BY b1;
D =  FOREACH C GENERATE A::a1,B::b2,A::a3;
STORE D INTO 'file3.txt'

然而收到以下错误:

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 语句绕过该问题,但我想知道为什么我们不能在此特定查询中使用变量。有没有我忽视的特定规则?

1 个答案:

答案 0 :(得分:2)

这是设计的。可以在Variable Substitution一章中找到解释:

  

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

无法使用EXECUTE对动态语句中的值进行参数化,因为quoting the chapter Executing Dynamic Commands

  

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

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

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;

使用未记录的"临时"问题中的演示功能。
顺便说一句,关于n_distinct