【问题标题】:PostgreSQL Error: function cannot execute on segment because it accesses relation "..."PostgreSQL 错误:函数无法在段上执行,因为它访问关系“...”
【发布时间】:2013-12-22 22:55:14
【问题描述】:

我正在编写一个简单的 plpgsql 函数来测试我必须使用 information_schema.columns 表在各种表上动态运行指标的想法。该函数工作正常,但是当我使用 information_schema 表中的 info 生成要传递给我的函数的表名时,我在标题中收到错误消息:

ERROR:  function cannot execute on segment because it accesses relation "my_table"

这是一个简单的函数(原理证明):

create or replace function count_rows(table_name text, column_name text)
returns bigint as $$
declare
    n bigint;
BEGIN
    execute 'select count(*) from (select ' || column_name || ' from ' || table_name || ') as t' into n;
    return n;
END;
$$ language 'plpgsql';

这个查询(以及函数)工作正常:

select * from count_rows('my_table','my_column');  -- works correctly!

但是使用来自 information_schema.columns 表的输入的查询失败并出现上述错误:

select table_name, column_name, count_rows(table_name, column_name) as num_rows
from information_schema.columns where table_name = 'my_table'; -- doesnt work

这个错误信息是什么意思?为什么不能这样查询information_schema中列出的表?

【问题讨论】:

  • 您使用的是哪个数据库版本?我对 8.2、9.2 和 9.3 进行了快速检查,但它们都没有给我那个错误(并且通过代码搜索没有找到那个错误字符串)。此外,您应该使用 quote_ident() 或 format() - 如果您的任何列名包含奇怪的字符,您可能会传递一个棘手的查询来执行。
  • 语言名称是 SQL 标识符,不应放在单引号中。你应该改用plpgsql
  • 我在 PostgreSQL 8.2.15 上。我不确定为什么这个错误在这些版本中不可重复。如果我将语言名称(plpgsql)的引号去掉,我会得到同样的错误。

标签: subquery plpgsql information-schema greenplum


【解决方案1】:

看起来您可能正在使用 Greenplum。如果是这样,问题是函数无法访问表。

如果您遇到此问题,您必须将您的函数重写为视图,或者硬编码在函数中选择表中返回的值。在这种情况下,对结果进行硬编码是没有意义的,因此您需要查看是否可以使视图工作。

【讨论】:

    【解决方案2】:

    使用 quote_ident(tablename) & quote_ident(columnname) 而不是直接的 columnname 和 tablename, 您应该要求访问所有表格

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多