如何在PostgreSQL中以编程方式查找继承的表?
发布时间:2020-12-13 18:07:55 所属栏目:百科 来源:网络整理
导读:我有一个PostgreSQL 8.3数据库,其中正在使用表继承.我想获得所有表的列表及其模式名称,该名称是使用查询从基表继承的.我们有什么方法可以使用PGSQL获得这个吗? 由于你使用的是旧版本的PostgreSQL,你可能不得不使用PL / PgSQL函数来处理的继承深度. 1.在现代
我有一个PostgreSQL 8.3数据库,其中正在使用表继承.我想获得所有表的列表及其模式名称,该名称是使用查询从基表继承的.我们有什么方法可以使用PGSQL获得这个吗?
由于你使用的是旧版本的PostgreSQL,你可能不得不使用PL / PgSQL函数来处理>的继承深度. 1.在现代PostgreSQL(甚至8.4)上,您将使用递归公用表表达式(WITH RECURSIVE).
pg_catalog.pg_inherits表是关键.鉴于: create table pp( ); -- The parent we'll search for CREATE TABLE notpp(); -- Another root for multiple inheritance create table cc( ) inherits (pp); -- a 1st level child of pp create table dd( ) inherits (cc,notpp); -- a 2nd level child of pp that also inherits aa create table notshown( ) inherits (notpp); -- Table that inherits only notpp create table ccdd () inherits (cc,dd) -- Inheritance is a graph not a tree; join node 正确的结果将找到cc,dd和ccdd,但找不到notpp或notshown. 单深度查询是: SELECT pg_namespace.nspname,pg_class.relname FROM pg_catalog.pg_inherits INNER JOIN pg_catalog.pg_class ON (pg_inherits.inhrelid = pg_class.oid) INNER JOIN pg_catalog.pg_namespace ON (pg_class.relnamespace = pg_namespace.oid) WHERE inhparent = 'pp'::regclass; ……但这只会找到cc. 对于多深度继承(即tableC继承tableB继承tableA),您必须通过递归CTE或PL / PgSQL中的循环来扩展它,使用最后一个循环的子节点作为下一个循环的父节点. 更新:这是一个8.3兼容版本,应该递归地查找直接或间接从给定父级继承的所有表.如果使用多重继承,它应该在树的任何位置找到任何具有目标表作为其父节点之一的表. CREATE OR REPLACE FUNCTION find_children(oid) RETURNS SETOF oid as $$ SELECT i.inhrelid FROM pg_catalog.pg_inherits i WHERE i.inhparent = $1 UNION SELECT find_children(i.inhrelid) FROM pg_catalog.pg_inherits i WHERE i.inhparent = $1; $$LANGUAGE 'sql' STABLE; CREATE OR REPLACE FUNCTION find_children_of(parentoid IN regclass,schemaname OUT name,tablename OUT name) RETURNS SETOF record AS $$ SELECT pg_namespace.nspname,pg_class.relname FROM find_children($1) inh(inhrelid) INNER JOIN pg_catalog.pg_class ON (inh.inhrelid = pg_class.oid) INNER JOIN pg_catalog.pg_namespace ON (pg_class.relnamespace = pg_namespace.oid); $$LANGUAGE 'sql' STABLE; 用法: regress=# SELECT * FROM find_children_of('pp'::regclass); schemaname | tablename ------------+----------- public | cc public | dd public | ccdd (3 rows) 这是递归CTE版本,如果您更新Pg将会起作用,但不适用于您当前的版本.这是更清洁的IMO. WITH RECURSIVE inh AS ( SELECT i.inhrelid FROM pg_catalog.pg_inherits i WHERE inhparent = 'pp'::regclass UNION SELECT i.inhrelid FROM inh INNER JOIN pg_catalog.pg_inherits i ON (inh.inhrelid = i.inhparent) ) SELECT pg_namespace.nspname,pg_class.relname FROM inh INNER JOIN pg_catalog.pg_class ON (inh.inhrelid = pg_class.oid) INNER JOIN pg_catalog.pg_namespace ON (pg_class.relnamespace = pg_namespace.oid); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |