मेरे पास एक PostgreSQL 8.3 डेटाबेस है जहां टेबल विरासत का उपयोग किया जा रहा है। मैं अपने स्कीमा नाम के साथ सभी तालिकाओं की एक सूची प्राप्त करना चाहता हूं जो क्वेरी का उपयोग कर आधार तालिका से विरासत में मिला है। क्या पीजीएसक्यूएल का उपयोग करके हम इसे प्राप्त कर सकते हैं?PostgreSQL में प्रोग्रामेटिक रूप से विरासत में मिली टेबल कैसे खोजें?
उत्तर
चूंकि आप पोस्टग्रेएसक्यूएल के पुराने संस्करण पर हैं, तो आपको शायद> पीएल/पीजीएसक्यूएल फ़ंक्शन का उपयोग करना होगा, जो कि विरासत की गहराई को संभालने के लिए होगा। 1. आधुनिक पोस्टग्रेएसक्यूएल (या यहां तक कि 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
मिल जाएगा।
बहु गहराई विरासत के लिए आप विस्तार करने के लिए एक पुनरावर्ती CTE या PL/pgSQL में एक पाश के माध्यम से है कि अगले में माता-पिता के रूप में पिछले पाश के बच्चों का उपयोग कर (यानी 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)
यहाँ पुनरावर्ती CTE संस्करण है, जो यदि आप पृष्ठ को अद्यतन काम करेंगे, लेकिन अपने वर्तमान संस्करण पर काम नहीं करेगा। यह बहुत साफ आईएमओ है।
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);
निम्नलिखित बयान को पुन: प्राप्त तालिका public.base_table_name
के सभी बच्चे टेबल:
select bt.relname as table_name, bns.nspname as table_schema
from pg_class ct
join pg_namespace cns on ct.relnamespace = cns.oid and cns.nspname = 'public'
join pg_inherits i on i.inhparent = ct.oid and ct.relname = 'base_table_name'
join pg_class bt on i.inhrelid = bt.oid
join pg_namespace bns on bt.relnamespace = bns.oid
यह 8.3 के साथ काम करना चाहिए, हालांकि मैं 100% यकीन नहीं है।
जो यहाँ RECURSIVE
समर्थन के साथ PostgreSQL का एक संस्करण चला रहे हैं उन लोगों के लिए एक समारोह व्युत्पन्न निर्दिष्ट आधार तालिका के लिए टेबल पता चलता है कि है।
CREATE OR REPLACE FUNCTION tables_derived_from(base_namespace name, base_table name)
RETURNS TABLE (table_schema name, table_name name, oid oid)
AS $BODY$
WITH RECURSIVE inherited_id AS
(
SELECT i.inhrelid AS oid
FROM pg_inherits i
JOIN pg_class base_t ON i.inhparent = base_t.oid
JOIN pg_namespace base_ns ON base_t.relnamespace = base_ns.oid
WHERE base_ns.nspname = base_namespace AND base_t.relname = base_table
UNION
SELECT i.inhrelid AS oid
FROM pg_inherits i
JOIN inherited_id b ON i.inhparent = b.oid
)
SELECT child_ns.nspname as table_schema, child_t.relname as table_name, child_t.oid
FROM inherited_id i
JOIN pg_class child_t ON i.oid = child_t.oid
JOIN pg_namespace child_ns ON child_t.relnamespace = child_ns.oid
ORDER BY 1, 2, 3;
$BODY$ LANGUAGE sql STABLE;
यह ध्यान रखें कि एक तालिका कई तालिकाओं के वारिस कर सकते हैं और वास्तव में उस का पर्दाफाश सूचीबद्ध समाधानों में से कोई भी महत्वपूर्ण है; वे सिर्फ एक ही माता-पिता के पेड़ पर चलते हैं। पर विचार करें:
CREATE TABLE a();
CREATE TABLE b();
CREATE TABLE ab_() INHERITS (a,b);
CREATE TABLE ba_() INHERITS (b,a);
CREATE TABLE ab__() INHERITS (ab_);
CREATE TABLE ba__() INHERITS (ba_);
CREATE TABLE ab_ba_() INHERITS (ab_, ba_);
CREATE TABLE ba_ab_() INHERITS (ba_, ab_);
WITH RECURSIVE inh AS (
SELECT i.inhparent::regclass, i.inhrelid::regclass, i.inhseqno FROM pg_catalog.pg_inherits i WHERE inhparent = 'a'::regclass
UNION
SELECT i.inhparent::regclass, i.inhrelid::regclass, i.inhseqno FROM inh INNER JOIN pg_catalog.pg_inherits i ON (inh.inhrelid = i.inhparent)
) SELECT * FROM inh;
inhparent | inhrelid | inhseqno
-----------+----------+----------
a | ab_ | 1
a | ba_ | 2
ab_ | ab__ | 1
ba_ | ba__ | 1
ab_ | ab_ba_ | 1
ba_ | ab_ba_ | 2
ba_ | ba_ab_ | 1
ab_ | ba_ab_ | 2
(8 rows)
सूचना है कि ख नहीं दोनों ab_ के रूप में सभी जो किया है वह ग़लत पर दिखाई देती है, और ba_ ख प्राप्त करती हैं।
मैं "सर्वश्रेष्ठ" जिस तरह से इस संभालने के लिए एक स्तंभ है कि पाठ [] और शामिल किया जाएगा संदेह है (सरणी [inhparent :: regclass]) :: प्रत्येक तालिका के लिए पाठ। जबकि स्पष्ट रूप से आदर्श नहीं, कि कम से कम पूरा विरासत पथ का पर्दाफाश और यदि आपके पास पर्याप्त जिमनास्टिक के साथ इसे का उपयोग करने की अनुमति होगी कि आप की तरह
inhrelid path
ab_ {"{a,b}"}
ba_ {"{b,a}"}
ab_ba_ {"{a,b}","{b,a}"}
कुछ देना होगा। दुर्भाग्य से, यह बनाना बिल्कुल आसान नहीं है।
एक कुछ हद तक आसान विकल्प हर स्तर पर पूरा विरासत पथ, केवल प्रत्येक टेबल प्रत्यक्ष माता-पिता शामिल करने के लिए नहीं है। इससे आपको यह मिल जाएगा:
inhrelid parents
ab_ {a,b}
ba_ {b,a}
ab_ba_ {ab_,ba_}
- 1. ActiveRecord में PostgreSQL विरासत?
- 2. PostgreSQL: तार के रूप में तारों की सूची कैसे खोजें?
- 3. सी # में विरासत/स्पष्ट रूपांतरण विधियां विरासत में मिली हैं?
- 4. PostgreSQL विरासत: विरासत-तालिका ट्रिगर्स विरासत में हैं?
- 5. प्रोग्रामेटिक रूप से टेबल व्यू सेल में छवि जोड़ें
- 6. जांचें कि क्या PostgreSQL में तालिका को अन्य तालिका से विरासत में मिला है
- 7. निर्माता एसटीडी से विरासत में मिली वर्ग :: स्ट्रिंग
- 8. क्या दोस्ती सी ++ में विरासत में मिली है?
- 9. सभी तालिकाओं में एक विशिष्ट मान कैसे खोजें (PostgreSQL)?
- 10. पूर्ण प्रोग्रामेटिक रूप से
- 11. अन्य स्थान (मैकोज़क्स) में प्रोग्रामेटिक रूप से
- 12. दोस्ती विरासत में नहीं मिली - विकल्प क्या हैं?
- 13. स्वचालित रूप से PostgreSQL में निष्क्रिय कनेक्शन कैसे बंद करें?
- 14. एंड्रॉइड प्रोग्रामेटिक रूप से
- 15. मैं सिल्वरलाइट में प्रोग्रामेटिक रूप से कैनवास कैसे रखूं?
- 16. एंड्रॉइड प्रोग्रामेटिक रूप से
- 17. एंड्रॉइड प्रोग्रामेटिक रूप से
- 18. प्रोग्रामेटिक रूप से सिम्बियन
- 19. ऑरैक टेबल में नई लाइन चार कैसे खोजें?
- 20. postgresql में टेबल की कुल संख्या कैसे प्राप्त करें?
- 21. एकल टेबल विरासत से जुड़े एचएबीटीएम एसोसिएशन
- 22. uitableview प्रोग्रामेटिक रूप से
- 23. सिंगल टेबल विरासत में उप-वर्ग के सत्यापन कैसे चलाएं?
- 24. सिंगल टेबल विरासत या कक्षा तालिका विरासत?
- 25. ओएसएक्स प्रोग्रामेटिक रूप से
- 26. प्रोग्रामेटिक रूप से
- 27. आईफोन प्रोग्रामेटिक रूप से
- 28. डेटाटेबल प्रोग्रामेटिक रूप से
- 29. प्रोग्रामेटिक रूप से VB.NET
- 30. प्रोग्रामेटिक रूप से सीआईएल
+1। मैंने इसके बारे में नहीं सोचा था। –
यह बहुत अच्छी सवाल है। मैंने बस इसे निष्पादित करने की कोशिश की और यह सही काम किया !! मैंने इसे नामकरण सम्मेलनों को समायोजित करने के लिए संशोधित किया। धन्यवाद इस के लिए एक बहुत ... – Arun
@Arun खुशी है कि यह मदद की। –