मैंने इसे आपके लिए कारगर बनाने के लिए समय लिया।
शुरुआत के लिए, कोड के अंदर क्या हो रहा है, इसके बारे में कुछ जानकारी।
स्पष्टीकरण
- फ़ंक्शन दो इनपुट तर्क लेता है:स्तंभ नाम और स्तंभ मान
- इसे एक बनाए गए प्रकार की आवश्यकता है कि यह एक सेट लौटाएगा
- पहला लूप उन तालिकाओं की पहचान करता है जिनमें इनपुट तर्क के रूप में निर्दिष्ट कॉलम नाम होता है
- फिर यह एक क्वेरी बनाता है जो
ILIKE
के आधार पर तुलना के साथ चरण 3 से ली गई प्रत्येक तालिका के अंदर इनपुट स्थिति से मेल खाने वाली सभी पंक्तियों को एकत्रित करता है। - आपके उदाहरण के अनुसार - फ़ंक्शन दूसरे लूप में तभी जाता है जब वर्तमान में देखी गई तालिका में कम से कम एक पंक्ति है जो निर्दिष्ट स्थिति से मेल खाती है (तब सरणी शून्य नहीं है)
- दूसरा लूप स्थिति से मेल खाने वाली पंक्तियों की सरणी को हटा देता है और प्रत्येक तत्व के लिए इसे
RETURN NEXT rec
के साथ फ़ंक्शन आउटपुट में डालता है। खंड
नोट
-
LIKE के साथ खोजना अक्षम है - मेरा सुझाव है कि एक और इनपुट तर्क "कॉलम प्रकार" जोड़ें और
pg_catalog.pg_type
में शामिल होकर इसे लुकअप में प्रतिबंधित करें। टेबल। -
दूसरा लूप इसलिए है ताकि यदि किसी विशेष तालिका के लिए 1 से अधिक पंक्ति पाई जाती है, तो प्रत्येक पंक्ति वापस आ जाती है।
-
यदि आप कुछ और खोज रहे हैं, जैसे कि आपको कुंजी-मूल्य जोड़े की आवश्यकता है, न कि केवल मान, तो आपको फ़ंक्शन का विस्तार करने की आवश्यकता है। उदाहरण के लिए आप पंक्तियों से जेसन प्रारूप बना सकते हैं।
अब, कोड पर।
टेस्ट केस
CREATE TABLE tbl1 (col1 int, id int); -- does contain values
CREATE TABLE tbl2 (col1 int, col2 int); -- doesn't contain column "id"
CREATE TABLE tbl3 (id int, col5 int); -- doesn't contain values
INSERT INTO tbl1 (col1, id)
VALUES (1, 5), (1, 33), (1, 25);
तालिका डेटा संग्रहीत करती है:
postgres=# select * From tbl1;
col1 | id
------+----
1 | 5
1 | 33
1 | 25
(3 rows)
निर्माण प्रकार
CREATE TYPE sometype AS ( schemaname text, tablename text, colname text, entirerow text );
फ़ंक्शन कोड
CREATE OR REPLACE FUNCTION search_tables_for_column (
v_column_name text
, v_column_value text
)
RETURNS SETOF sometype
LANGUAGE plpgsql
STABLE
AS
$$
DECLARE
rec sometype%rowtype;
v_row_array text[];
rec2 record;
arr_el text;
BEGIN
FOR rec IN
SELECT
nam.nspname AS schemaname
, cls.relname AS tablename
, att.attname AS colname
, null::text AS entirerow
FROM
pg_attribute att
JOIN pg_class cls ON att.attrelid = cls.oid
JOIN pg_namespace nam ON cls.relnamespace = nam.oid
WHERE
cls.relkind = 'r'
AND att.attname = v_column_name
LOOP
EXECUTE format('SELECT ARRAY_AGG(row(tablename.*)::text) FROM %I.%I AS tablename WHERE %I::text ILIKE %s',
rec.schemaname, rec.tablename, rec.colname, quote_literal(concat('%',v_column_value,'%'))) INTO v_row_array;
IF v_row_array is not null THEN
FOR rec2 IN
SELECT unnest(v_row_array) AS one_row
LOOP
rec.entirerow := rec2.one_row;
RETURN NEXT rec;
END LOOP;
END IF;
END LOOP;
END
$$;
अनुकरणीय कॉल और आउटपुट
postgres=# select * from search_tables_for_column('id','5');
schemaname | tablename | colname | entirerow
------------+-----------+---------+-----------
public | tbl1 | id | (1,5)
public | tbl1 | id | (1,25)
(2 rows)