चूंकि आप PostgreSQL के इतने पुराने संस्करण पर हैं, इसलिए आपको शायद> 1 की विरासत गहराई को संभालने के लिए PL/PgSQL फ़ंक्शन का उपयोग करना होगा। आधुनिक 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
) आपको इसे पुनरावर्ती सीटीई या पीएल/पीजीएसक्यूएल में लूप के माध्यम से विस्तारित करना होगा, अंतिम लूप के बच्चों का उपयोग अगले में माता-पिता के रूप में करना होगा।
अपडेट करें :यहां एक 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)
यहां रिकर्सिव सीटीई संस्करण है, जो अगर आप पीजी अपडेट करते हैं तो काम करेगा, लेकिन आपके वर्तमान संस्करण पर काम नहीं करेगा। यह ज्यादा साफ 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);