Postgres 用户定义函数:SQL 中的自连接

Postgres User-defined functions: self-joins in SQL

我有以下 SQL 在 psql 中工作得很好:

SELECT
   parent.relname, child.relname       AS child
FROM pg_inherits
    JOIN pg_class parent            ON pg_inherits.inhparent = parent.oid
    JOIN pg_class child             ON pg_inherits.inhrelid   = child.oid
    JOIN pg_namespace nmsp_parent   ON nmsp_parent.oid  = parent.relnamespace
    JOIN pg_namespace nmsp_child    ON nmsp_child.oid   = child.relnamespace
WHERE parent.relname='table_name';

问题是当我把它放在创建函数块中时:

CREATE OR REPLACE FUNCTION my_function(tablename text)
RETURNS SETOF RECORD AS
$$


  SELECT
   parent.relname, child.relname       AS child
FROM pg_inherits
    JOIN pg_class parent            ON pg_inherits.inhparent = parent.oid
    JOIN pg_class child             ON pg_inherits.inhrelid   = child.oid
    JOIN pg_namespace nmsp_parent   ON nmsp_parent.oid  = parent.relnamespace
    JOIN pg_namespace nmsp_child    ON nmsp_child.oid   = child.relnamespace
WHERE parent.relname= tablename;



$$ LANGUAGE plpgsql;

我收到一个错误:

ERROR:  schema "parent" does not exist
LINE 10:     parent.relname

,

当我尝试 "public.parent.relname" 时,我得到的错误是:

ERROR:  cross-database references are not implemented: 

    public.parent.relname
    LINE 10:     public.parent.relname

如何正确处理这种情况,我的语法有什么问题?

我在您提供的示例中发现了几个错误。我以你的例子为例,有几件事跳出来了:

  • Return类型未声明(可以是记录,table,自定义类型,...)
  • 未声明语言名称 (plpgsql, sql, c,...)
  • ...

看看 documentation,你可以找到更多关于如何在 PostgreSQL 中创建函数的信息,还有很多例子(google,Whosebug,博客帖子)。

基于您的示例(还取决于 return 类型、语言名称)对我有用的工作示例:

CREATE OR REPLACE FUNCTION my_function()
RETURNS SETOF RECORD AS 
$$ 
SELECT
    parent.relname, child.relname       AS child
FROM pg_inherits
    JOIN pg_class parent            ON pg_inherits.inhparent = parent.oid
    JOIN pg_class child             ON pg_inherits.inhrelid   = child.oid
    JOIN pg_namespace nmsp_parent   ON nmsp_parent.oid  = parent.relnamespace
    JOIN pg_namespace nmsp_child    ON nmsp_child.oid   = child.relnamespace
WHERE parent.relname='table_name';
$$ LANGUAGE sql;

这对我有用:

CREATE OR REPLACE FUNCTION my_function (tablename text)
RETURNS TEXT AS
$$
DECLARE
  ret text := '';

BEGIN

SELECT
    parent.relname, child.relname

FROM pg_inherits
    JOIN pg_class parent            ON pg_inherits.inhparent = parent.oid
    JOIN pg_class child             ON pg_inherits.inhrelid   = child.oid
    JOIN pg_namespace nmsp_parent   ON nmsp_parent.oid  = parent.relnamespace
    JOIN pg_namespace nmsp_child    ON nmsp_child.oid   = child.relnamespace
WHERE parent.relname= tablename;



RETURN ret;


END;


$$ LANGUAGE plpgsql;

因为语言必须 "plpgsql" BEGIN/END 需要块