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