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

时间:2018-08-13 20:39:31

标签: postgresql self-join

我有以下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

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

2 个答案:

答案 0 :(得分:0)

在您提供的示例中,我看到了几个错误。我以您的示例为例,突然出现了几件事:

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

看看documentation,您可以找到有关如何在PostgreSQL中创建函数的更多信息,并且还有很多示例(谷歌,stackoverflow,博客文章)。

根据您的示例(也取决于返回类型,语言名称)为我工作的示例:

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;

答案 1 :(得分:0)

这对我有用:

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块