সমস্ত সারণীতে (পোস্টগ্রিএসকিউএল) একটি নির্দিষ্ট মান কীভাবে সন্ধান করবেন?


111

পোস্টগ্রেএসকিউএল-তে একটি নির্দিষ্ট মানের জন্য প্রতিটি টেবিলের প্রতিটি কলাম অনুসন্ধান করা সম্ভব ?

ওরাকল এর জন্যও এখানে একই জাতীয় প্রশ্ন পাওয়া যায় ।


আপনি কি কোনও সরঞ্জাম খুঁজছেন বা সংযুক্ত প্রশ্নে দেখানো পদ্ধতিগুলির প্রয়োগের জন্য?
a_horse_with_no_name

না, সমস্ত ক্ষেত্র / সারণীতে নির্দিষ্ট মান সন্ধান করার সহজতম উপায়।
সান্দ্রো মুন্ডা

সুতরাং আপনি কোনও বাহ্যিক সরঞ্জাম ব্যবহার করতে চান না?
a_horse_with_no_name

1
যদি এটি বাহ্যিক সরঞ্জামের জন্য সবচেয়ে সহজ উপায় => ঠিক আছে :-)
সান্দ্রো মুন্ডা

উত্তর:


131

ডাটাবেসের বিষয়বস্তু ডাম্পিং করে কীভাবে ব্যবহার করবেন grep?

$ pg_dump --data-only --inserts -U postgres your-db-name > a.tmp
$ grep United a.tmp
INSERT INTO countries VALUES ('US', 'United States');
INSERT INTO countries VALUES ('GB', 'United Kingdom');

একই ইউটিলিটি, পিজি_ডাম্প আউটপুটে কলামের নাম অন্তর্ভুক্ত করতে পারে। শুধু পরিবর্তন --insertsকরতে --column-inserts। এইভাবে আপনি নির্দিষ্ট কলামের নামগুলিও অনুসন্ধান করতে পারেন। তবে যদি আমি কলামের নামগুলি সন্ধান করতাম তবে আমি সম্ভবত ডেটার পরিবর্তে স্কিমাটি ফেলে দেব।

$ pg_dump --data-only --column-inserts -U postgres your-db-name > a.tmp
$ grep country_code a.tmp
INSERT INTO countries (iso_country_code, iso_country_name) VALUES ('US', 'United  States');
INSERT INTO countries (iso_country_code, iso_country_name) VALUES ('GB', 'United Kingdom');

5
+1 বিনামূল্যে এবং সাধারণ। এবং যদি আপনি কাঠামো চান pg_dump এটিও করতে পারেন। এছাড়াও যদি গ্রেপ আপনার জিনিস না ব্যবহার করে তবে আপনার ফেলে দেওয়া কাঠামো এবং / অথবা ডেটাতে আপনি চান এমন সামগ্রী অনুসন্ধানের সরঞ্জামটি ফাইল করুন।
কুবেরচাঁন

আপনি যদি টেক্সট ডেটা গ্রেপ করতে চান (যা সাধারণত পোস্টগ্রিজের আরও সাম্প্রতিক সংস্করণে এনকোড থাকে), ALTER DATABASE your_db_name SET bytea_output = 'escape';এটি ডাম্প করার আগে আপনাকে ডাটাবেসে (বা এর একটি অনুলিপি) প্রয়োজন হতে পারে। (আমি কেবল একটি pg_dumpকমান্ডের জন্য এটি নির্দিষ্ট করার কোনও উপায় দেখছি না ))
ফিলস

আপনি কি বিস্তারিত ব্যাখ্যা করতে পারবেন ..? সমস্ত টেবিলের স্ট্রিং 'এবিসি' কীভাবে অনুসন্ধান করবেন?
মিঃ ভোসালে

1
আপনি যদি ইন্টেলিজ ব্যবহার করে থাকেন তবে আপনি কেবল আপনার ডিবিতে রাইট-ক্লিক করতে পারেন এবং "'পিজি_ডাম্প' দিয়ে ডাম্প" বা "ফাইলগুলিতে ডেটা ডাম্প" নির্বাচন করতে পারেন
লরেনস

3
আপনি যে ডিস্কে এটিকে ফেলে দিতে পারবেন না এমন পর্যাপ্ত পরিমাণে কোনও ডাটাবেসের কীভাবে এটি বৈধ সমাধান?
গোবিন্দ পরমার

76

এখানে একটি pl / pgsql ফাংশন যা রেকর্ডগুলি সনাক্ত করে যেখানে কোনও কলামে একটি নির্দিষ্ট মান রয়েছে। এটি আর্গুমেন্ট হিসাবে পাঠ্য বিন্যাসে অনুসন্ধানের মান, সন্ধানে সারণীর নামের একটি অ্যারে (সমস্ত টেবিলের ডিফল্ট) এবং স্কিমা নামের একটি অ্যারে (সমস্ত স্কিমার নাম ডিফল্ট) লাগে।

এটি স্কিমা, টেবিলের নাম, কলামের নাম এবং সিউডো-কলামের সাথে একটি সারণী কাঠামো ফিরিয়ে দেয় ctid(টেবিলের সারিটির অ-স্থায়ী শারীরিক অবস্থান, সিস্টেম কলাম দেখুন )

CREATE OR REPLACE FUNCTION search_columns(
    needle text,
    haystack_tables name[] default '{}',
    haystack_schema name[] default '{}'
)
RETURNS table(schemaname text, tablename text, columnname text, rowctid text)
AS $$
begin
  FOR schemaname,tablename,columnname IN
      SELECT c.table_schema,c.table_name,c.column_name
      FROM information_schema.columns c
        JOIN information_schema.tables t ON
          (t.table_name=c.table_name AND t.table_schema=c.table_schema)
        JOIN information_schema.table_privileges p ON
          (t.table_name=p.table_name AND t.table_schema=p.table_schema
              AND p.privilege_type='SELECT')
        JOIN information_schema.schemata s ON
          (s.schema_name=t.table_schema)
      WHERE (c.table_name=ANY(haystack_tables) OR haystack_tables='{}')
        AND (c.table_schema=ANY(haystack_schema) OR haystack_schema='{}')
        AND t.table_type='BASE TABLE'
  LOOP
    FOR rowctid IN
      EXECUTE format('SELECT ctid FROM %I.%I WHERE cast(%I as text)=%L',
       schemaname,
       tablename,
       columnname,
       needle
      )
    LOOP
      -- uncomment next line to get some progress report
      -- RAISE NOTICE 'hit in %.%', schemaname, tablename;
      RETURN NEXT;
    END LOOP;
 END LOOP;
END;
$$ language plpgsql;

গিথুবের সংস্করণটিও দেখুনএকই ভিত্তিতে তবে কিছু গতি যুক্ত করা এবং প্রতিবেদনের উন্নতি করা হয়েছে।

পরীক্ষার ডাটাবেসে ব্যবহারের উদাহরণ:

  • সর্বজনীন স্কিমাতে সমস্ত সারণীতে অনুসন্ধান করুন:
অনুসন্ধান_কলামগুলি ('foobar') থেকে * নির্বাচন করুন;
 স্কিম্যানাম | টেবিলের নাম | কলামনাম | rowctid
------------ + + ----------- + + ------------ + + ---------
 সর্বজনীন | s3 | ব্যবহারকারীর নাম | (0,11)
 সর্বজনীন | এস 2 | পুনঃনামকরণ | (7,29)
 সর্বজনীন | ডাব্লু | শরীর | (0,2)
(3 সারি)
  • একটি নির্দিষ্ট সারণীতে অনুসন্ধান করুন:
 অনুসন্ধান_কলামগুলি ('foobar', '{w}') থেকে * নির্বাচন করুন;
 স্কিম্যানাম | টেবিলের নাম | কলামনাম | rowctid
------------ + + ----------- + + ------------ + + ---------
 সর্বজনীন | ডাব্লু | শরীর | (0,2)
(1 সারি)
  • একটি নির্বাচন থেকে প্রাপ্ত টেবিলের একটি উপসেট অনুসন্ধান করুন:
অনুসন্ধান_কলামগুলি ('ফুবার', অ্যারে (টেবিলের নাম নির্বাচন করুন: তথ্য_সেমিকা থেকে নাম নির্বাচন করুন ables টেবিল যেখানে টেবিলের নাম 's%'), অ্যারে ['পাবলিক']) নির্বাচন করুন;
 স্কিম্যানাম | টেবিলের নাম | কলামনাম | rowctid
------------ + + ----------- + + ------------ + + ---------
 সর্বজনীন | এস 2 | পুনঃনামকরণ | (7,29)
 সর্বজনীন | s3 | ব্যবহারকারীর নাম | (0,11)
(২ টি সারি)
  • সংশ্লিষ্ট বেস টেবিল এবং সিটিডি সহ ফলাফল সারি পান:
সর্বজনীন থেকে * নির্বাচন করুন। যেখানে সিটিডি = '(0,2)';
 শিরোনাম | শরীর | TSV         
------- + + -------- + + ---------------------
 টোটো | foobar | 'ফুবার': 2 'টোটো': 1

ভেরিয়েন্ট

  • কঠোর সাম্যের পরিবর্তে নিয়মিত অভিব্যক্তির বিরুদ্ধে পরীক্ষা করার জন্য, গ্রেপের মতো, প্রশ্নের এই অংশটি:

    SELECT ctid FROM %I.%I WHERE cast(%I as text)=%L

    এতে পরিবর্তন করা যেতে পারে:

    SELECT ctid FROM %I.%I WHERE cast(%I as text) ~ %L

  • সংবেদনশীল তুলনার ক্ষেত্রে আপনি লিখতে পারেন:

    SELECT ctid FROM %I.%I WHERE lower(cast(%I as text)) = lower(%L)


ত্রুটি: "ডিফল্ট" লাইন 3 এর কাছাকাছি বা কাছাকাছি সিনট্যাক্স ত্রুটি: খড়ের ছাঁচ_ টেবিলের নাম [] ডিফল্ট '{}' (পোস্টগ্রাএসকিউএল 8.2.17 ব্যবহার করে আপগ্রেড করতে পারে না)
হেনো

@ হেন্নো: হ্যাঁ এর জন্য পিজি -9.1 দরকার। এটি সুস্পষ্ট করতে এখনই সম্পাদিত। এটি পুরানো সংস্করণগুলির সাথে ব্যবহার করতে আপনাকে এটিকে মানিয়ে নিতে হবে।
ড্যানিয়েল ভ্যারিটি

1
@ রাজেন্দ্র_প্রসাদ: নিয়মিত এক্সপ্রেশন অপারেটরের ক্ষেত্রে একটি সংবেদনশীল রূপ থাকে: ~*নিম্ন () এর চেয়ে বেশি পর্যাপ্ত। তবে যাইহোক, t.*উপরের উত্তরের অংশ নয়। কলাম অনুসারে কলাম অনুসন্ধান করা কলাম বিভাজকগুলির কারণে সারিটি মান হিসাবে সন্ধান করার মতো নয়।
ড্যানিয়েল ভ্যারিট

2
এটি স্কিমা-সারণী-কলামে প্রতি এক সারি দেয়।
দ্য জিটিকনার্ড

1
অনেক ধন্যবাদ. এই সমাধানটি আমার পক্ষে নিখুঁতভাবে কাজ করে। আমাকে 1000 টিরও বেশি টেবিলের তালিকায় একটি সারণী সন্ধান করতে হয়েছিল যার মধ্যে একটি নির্দিষ্ট ইউআরএল রয়েছে। তুমি আমার দিন বাঁচিয়েছ!
সুনীল

7

নির্দিষ্ট মানের জন্য প্রতিটি টেবিলের প্রতিটি কলাম অনুসন্ধান করতে

এটি ঠিক কীভাবে মিলবে তা নির্ধারণ করে না।
বা ঠিক কী ফিরে আসবে তা নির্ধারণ করে না।

ধরে নেওয়া যাক:

  • প্রদত্ত মানকে সমান করার বিপরীতে - এর পাঠ্য উপস্থাপনায় প্রদত্ত মান সম্বলিত যে কোনও কলামের সাথে কোনও সারি খুঁজুন ।
  • সারণীর নাম ( regclass) এবং টিপল আইডি ( ctid) ফিরিয়ে দিন , কারণ এটি সহজ।

এখানে একটি মৃত সহজ, দ্রুত এবং সামান্য নোংরা উপায়:

CREATE OR REPLACE FUNCTION search_whole_db(_like_pattern text)
  RETURNS TABLE(_tbl regclass, _ctid tid) AS
$func$
BEGIN
   FOR _tbl IN
      SELECT c.oid::regclass
      FROM   pg_class c
      JOIN   pg_namespace n ON n.oid = relnamespace
      WHERE  c.relkind = 'r'                           -- only tables
      AND    n.nspname !~ '^(pg_|information_schema)'  -- exclude system schemas
      ORDER BY n.nspname, c.relname
   LOOP
      RETURN QUERY EXECUTE format(
         'SELECT $1, ctid FROM %s t WHERE t::text ~~ %L'
       , _tbl, '%' || _like_pattern || '%')
      USING _tbl;
   END LOOP;
END
$func$  LANGUAGE plpgsql;

কল করুন:

SELECT * FROM search_whole_db('mypattern');

সংযুক্ত না করে অনুসন্ধানের প্যাটার্ন সরবরাহ করুন %

কিছুটা নোংরা কেন?

textউপস্থাপনে সারিটির জন্য পৃথককারী এবং সজ্জকারগণ যদি অনুসন্ধানের প্যাটার্নের অংশ হতে পারে তবে মিথ্যা ধনাত্মকতা থাকতে পারে:

  • কলাম বিভাজক: ,ডিফল্টরূপে
  • পুরো সারিটি বন্ধনীতে আবদ্ধ:()
  • কিছু মান ডাবল উদ্ধৃতিতে আবদ্ধ হয় "
  • \ পালানোর চর হিসাবে যুক্ত হতে পারে

এবং কিছু কলামের পাঠ্য উপস্থাপনা স্থানীয় সেটিংসের উপর নির্ভর করতে পারে - তবে সেই অস্পষ্টতা আমার সমাধানের জন্য নয়, প্রশ্নের অন্তর্নিহিত।

প্রতিটি যোগ্যতা সারি একবারে একবারে ফিরে আসে , এমনকি এটি একাধিকবার মেলে এমনকি (এখানে অন্যান্য উত্তরের বিপরীতে)।

এটি সিস্টেম ক্যাটালগ বাদে পুরো ডিবি অনুসন্ধান করে। সাধারণত শেষ করতে দীর্ঘ সময় লাগবে । আপনি অন্যান্য স্ক্রিন / টেবিলগুলিতে সীমাবদ্ধ রাখতে চাইতে পারেন (বা এমনকি কলামগুলি) যেমন অন্য উত্তরে প্রদর্শিত হয়েছে। অথবা বিজ্ঞপ্তি যুক্ত করুন এবং একটি অগ্রগতি সূচকও অন্য উত্তরে প্রদর্শিত হয়েছে।

regclassঅবজেক্ট আইডেন্টিফায়ার টাইপ সারণী নাম, স্কিমা-যোগ্যতাসম্পন্ন যেখানে প্রয়োজন বর্তমান অনুযায়ী দুর্বোধ্য হিসেবে প্রতিনিধিত্ব করা হয় search_path:

কি ctid?

আপনি অনুসন্ধানের প্যাটার্নটিতে বিশেষ অর্থ সহ অক্ষরগুলি পালাতে চাইতে পারেন। দেখা:


এই দুর্দান্ত সমাধানটি নিম্ন () - 'নির্বাচন করুন $ 1 থেকে কোথাও নিম্ন (টি :: পাঠ্য) ~~ নিম্ন (% এল)' এর সাথে আরও ভাল
জর্জি বোঞ্চেভ

5

এবং যদি কেউ মনে করে এটি সাহায্য করতে পারে। এখানে @ দানিয়েল ভারিটের ফাংশনটি রয়েছে, এমন আরও একটি প্যারাম রয়েছে যেগুলি অনুসন্ধানে ব্যবহৃত কলামগুলির নাম স্বীকার করে। এভাবে প্রক্রিয়াজাতকরণের সময় হ্রাস পায়। অন্তত আমার পরীক্ষায় এটি অনেক কমেছে।

CREATE OR REPLACE FUNCTION search_columns(
    needle text,
    haystack_columns name[] default '{}',
    haystack_tables name[] default '{}',
    haystack_schema name[] default '{public}'
)
RETURNS table(schemaname text, tablename text, columnname text, rowctid text)
AS $$
begin
  FOR schemaname,tablename,columnname IN
      SELECT c.table_schema,c.table_name,c.column_name
      FROM information_schema.columns c
      JOIN information_schema.tables t ON
        (t.table_name=c.table_name AND t.table_schema=c.table_schema)
      WHERE (c.table_name=ANY(haystack_tables) OR haystack_tables='{}')
        AND c.table_schema=ANY(haystack_schema)
        AND (c.column_name=ANY(haystack_columns) OR haystack_columns='{}')
        AND t.table_type='BASE TABLE'
  LOOP
    EXECUTE format('SELECT ctid FROM %I.%I WHERE cast(%I as text)=%L',
       schemaname,
       tablename,
       columnname,
       needle
    ) INTO rowctid;
    IF rowctid is not null THEN
      RETURN NEXT;
    END IF;
 END LOOP;
END;
$$ language plpgsql;

বেলো উপরে তৈরি সার্চ ফাংশন ব্যবহারের একটি উদাহরণ।

SELECT * FROM search_columns('86192700'
    , array(SELECT DISTINCT a.column_name::name FROM information_schema.columns AS a
            INNER JOIN information_schema.tables as b ON (b.table_catalog = a.table_catalog AND b.table_schema = a.table_schema AND b.table_name = a.table_name)
        WHERE 
            a.column_name iLIKE '%cep%' 
            AND b.table_type = 'BASE TABLE'
            AND b.table_schema = 'public'
    )

    , array(SELECT b.table_name::name FROM information_schema.columns AS a
            INNER JOIN information_schema.tables as b ON (b.table_catalog = a.table_catalog AND b.table_schema = a.table_schema AND b.table_name = a.table_name)
        WHERE 
            a.column_name iLIKE '%cep%' 
            AND b.table_type = 'BASE TABLE'
            AND b.table_schema = 'public')
);

5

একটি নতুন পদ্ধতি সংরক্ষণ না করে আপনি একটি কোড ব্লক ব্যবহার করতে পারেন এবং উপস্থিতিগুলির একটি সারণী অর্জন করতে পারেন। আপনি স্কিমা, টেবিল বা কলামের নাম দ্বারা ফলাফলগুলি ফিল্টার করতে পারবেন।

DO $$
DECLARE
  value int := 0;
  sql text := 'The constructed select statement';
  rec1 record;
  rec2 record;
BEGIN
  DROP TABLE IF EXISTS _x;
  CREATE TEMPORARY TABLE _x (
    schema_name text, 
    table_name text, 
    column_name text,
    found text
  );
  FOR rec1 IN 
        SELECT table_schema, table_name, column_name
        FROM information_schema.columns 
        WHERE table_name <> '_x'
                AND UPPER(column_name) LIKE UPPER('%%')                  
                AND table_schema <> 'pg_catalog'
                AND table_schema <> 'information_schema'
                AND data_type IN ('character varying', 'text', 'character', 'char', 'varchar')
        LOOP
    sql := concat('SELECT ', rec1."column_name", ' AS "found" FROM ',rec1."table_schema" , '.',rec1."table_name" , ' WHERE UPPER(',rec1."column_name" , ') LIKE UPPER(''','%my_substring_to_find_goes_here%' , ''')');
    RAISE NOTICE '%', sql;
    BEGIN
        FOR rec2 IN EXECUTE sql LOOP
            RAISE NOTICE '%', sql;
            INSERT INTO _x VALUES (rec1."table_schema", rec1."table_name", rec1."column_name", rec2."found");
        END LOOP;
    EXCEPTION WHEN OTHERS THEN
    END;
  END LOOP;
  END; $$;

SELECT * FROM _x;

আপনি অনুসন্ধানের স্ট্রিংটি কোথায় নির্দিষ্ট করবেন? অথবা এটি কেবল পুরো ডিবি, টেবিলের সাহায্যে টেবিলটি ফেলে দিচ্ছে?
জিমটুট

1
আমি স্ট্রিংয়ের জন্য কোনও প্যারামিটার তৈরি করিনি। আপনি এটি হার্ডকোড করতে পারেন এবং এটি একটি ব্লক হিসাবে সরাসরিভাবে চালনা করতে পারেন বা এটি থেকে কোনও সঞ্চিত পদ্ধতি তৈরি করতে পারেন। যাই হোক, অনুসন্ধান করার জন্য আপনার স্ট্রিং দুই শতাংশ চিহ্ন মধ্যে এখানে যায়: কোথায় বড় হাতের ( '।, Rec1 "COLUMN_NAME",') মতো বড় হাতের ( '' ',' %% ',' '')
profimedica

5

কোনও কার্যকারিতা তৈরি বা বাহ্যিক সরঞ্জাম ব্যবহার না করে এটি অর্জনের একটি উপায় রয়েছে is পোস্টগ্রিসের query_to_xml()ফাংশনটি ব্যবহার করে যা অন্য কোয়েরির ভিতরে একটি ক্যোয়ারিকে গতিশীলভাবে চালাতে পারে, অনেকগুলি টেবিল জুড়ে একটি পাঠ্য অনুসন্ধান করা সম্ভব। এটি সমস্ত টেবিলের জন্য সারি গণনা পুনরুদ্ধার করার জন্য আমার উত্তরের ভিত্তিতে :

fooস্কিমাতে সমস্ত টেবিল জুড়ে স্ট্রিংটি অনুসন্ধান করতে , নিম্নলিখিতটি ব্যবহার করা যেতে পারে:

with found_rows as (
  select format('%I.%I', table_schema, table_name) as table_name,
         query_to_xml(format('select to_jsonb(t) as table_row 
                              from %I.%I as t 
                              where t::text like ''%%foo%%'' ', table_schema, table_name), 
                      true, false, '') as table_rows
  from information_schema.tables 
  where table_schema = 'public'
)
select table_name, x.table_row
from found_rows f
  left join xmltable('//table/row' 
                     passing table_rows
                       columns
                         table_row text path 'table_row') as x on true

নোট করুন যে এর ব্যবহারের xmltableজন্য পোস্টগ্রিস 10 বা আরও নতুন প্রয়োজন। পুরানো পোস্টগ্রাস সংস্করণের জন্য, এটি এক্সপ্যাথ () ব্যবহার করেও করা যেতে পারে।

with found_rows as (
  select format('%I.%I', table_schema, table_name) as table_name,
         query_to_xml(format('select to_jsonb(t) as table_row 
                              from %I.%I as t 
                              where t::text like ''%%foo%%'' ', table_schema, table_name), 
                      true, false, '') as table_rows
  from information_schema.tables 
  where table_schema = 'public'
)
select table_name, x.table_row
from found_rows f
   cross join unnest(xpath('/table/row/table_row/text()', table_rows)) as r(data)

সাধারণ সারণী এক্সপ্রেশন ( WITH ...) কেবলমাত্র সুবিধার জন্য ব্যবহৃত হয়। এটি publicস্কিমাতে সমস্ত টেবিলের মধ্য দিয়ে লুপ করে । প্রতিটি টেবিলের জন্য নিম্নলিখিত কোয়েরিটি query_to_xml()ফাংশনটির মাধ্যমে পরিচালিত হয় :

select to_jsonb(t)
from some_table t
where t::text like '%foo%';

XML সামগ্রীর ব্যয়বহুল প্রজন্মটি কেবল সারিগুলির জন্য সম্পন্ন করা হয়েছে যাতে সন্ধানের স্ট্রিং রয়েছে তা নিশ্চিত করার জন্য যেখানে ক্লজটি ব্যবহৃত হয়। এটি এ জাতীয় কিছু ফিরে আসতে পারে:

<table xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<row>
  <table_row>{"id": 42, "some_column": "foobar"}</table_row>
</row>
</table>

সম্পূর্ণ সারিটিতে রূপান্তরটি jsonbসম্পন্ন হয়েছে, যাতে ফলস্বরূপ যে কোনও মানটি কোন কলামের সাথে সম্পর্কিত তা দেখতে পাবে।

উপরের দিক থেকে কিছু এইরকম ফিরে আসতে পারে:

table_name   |   table_row
-------------+----------------------------------------
public.foo   |  {"id": 1, "some_column": "foobar"}
public.bar   |  {"id": 42, "another_column": "barfoo"}

পোস্টগ্রিস 10+ এর জন্য অনলাইন উদাহরণ

পুরানো পোস্টগ্রাস সংস্করণগুলির জন্য অনলাইন উদাহরণ


আমি পুরানো পোস্টগ্র্যাস এসকিউএল সংস্করণগুলির জন্য কোড চালানোর চেষ্টা করছি এবং আমি নিম্নলিখিত ত্রুটিটি পাচ্ছিERROR: 42883: function format("unknown", information_schema.sql_identifier, information_schema.sql_identifier) does not exist
ম্যাট

আপনার সম্ভবত তাদের কাস্ট করা দরকার:format('%I.%I', table_schema::text, table_name::text)
a_horse_with_no_name

ঠিক আছে, এটি করেছেন, এখন আমার আছেERROR: 42883: function format("unknown", character varying, character varying) does not exist
ম্যাট

তারপরে আপনার অনেকগুলি পোস্টগ্রাস সংস্করণ এত পুরানো, সেই আইডির এমনকি format()কার্যকারিতা নেই
a_horse_with_no_name

আমার মনে হয় রেডশিফট 8.3 এর উপর ভিত্তি করে?
ম্যাট

3

অগ্রগতি প্রতিবেদন কার্যকারিতা সহ এখানে @ ড্যানিয়েল ভুরিটের ফাংশন। এটি তিনটি উপায়ে অগ্রগতির প্রতিবেদন করেছে:

  1. রাইস নোটিশ দ্বারা;
  2. সরবরাহিত {প্রগ্রেস_সেক} ক্রমের মান হ্রাস করে search অনুসন্ধানের জন্য ums মোট কলমের সংখ্যা number
  3. সি: \ উইন্ডোজ \ টেম্পের। {প্রগ্রেস_সেক} .txt এ অবস্থিত পাঠ্য ফাইলে সারণিগুলির সহ প্রগতি লিখে।

: _

CREATE OR REPLACE FUNCTION search_columns(
    needle text,
    haystack_tables name[] default '{}',
    haystack_schema name[] default '{public}',
    progress_seq text default NULL
)
RETURNS table(schemaname text, tablename text, columnname text, rowctid text)
AS $$
DECLARE
currenttable text;
columnscount integer;
foundintables text[];
foundincolumns text[];
begin
currenttable='';
columnscount = (SELECT count(1)
      FROM information_schema.columns c
      JOIN information_schema.tables t ON
        (t.table_name=c.table_name AND t.table_schema=c.table_schema)
      WHERE (c.table_name=ANY(haystack_tables) OR haystack_tables='{}')
        AND c.table_schema=ANY(haystack_schema)
        AND t.table_type='BASE TABLE')::integer;
PERFORM setval(progress_seq::regclass, columnscount);

  FOR schemaname,tablename,columnname IN
      SELECT c.table_schema,c.table_name,c.column_name
      FROM information_schema.columns c
      JOIN information_schema.tables t ON
        (t.table_name=c.table_name AND t.table_schema=c.table_schema)
      WHERE (c.table_name=ANY(haystack_tables) OR haystack_tables='{}')
        AND c.table_schema=ANY(haystack_schema)
        AND t.table_type='BASE TABLE'
  LOOP
    EXECUTE format('SELECT ctid FROM %I.%I WHERE cast(%I as text)=%L',
       schemaname,
       tablename,
       columnname,
       needle
    ) INTO rowctid;
    IF rowctid is not null THEN
      RETURN NEXT;
      foundintables = foundintables || tablename;
      foundincolumns = foundincolumns || columnname;
      RAISE NOTICE 'FOUND! %, %, %, %', schemaname,tablename,columnname, rowctid;
    END IF;
         IF (progress_seq IS NOT NULL) THEN 
        PERFORM nextval(progress_seq::regclass);
    END IF;
    IF(currenttable<>tablename) THEN  
    currenttable=tablename;
     IF (progress_seq IS NOT NULL) THEN 
        RAISE NOTICE 'Columns left to look in: %; looking in table: %', currval(progress_seq::regclass), tablename;
        EXECUTE 'COPY (SELECT unnest(string_to_array(''Current table (column ' || columnscount-currval(progress_seq::regclass) || ' of ' || columnscount || '): ' || tablename || '\n\nFound in tables/columns:\n' || COALESCE(
        (SELECT string_agg(c1 || '/' || c2, '\n') FROM (SELECT unnest(foundintables) AS c1,unnest(foundincolumns) AS c2) AS t1)
        , '') || ''',''\n''))) TO ''c:\WINDOWS\temp\' || progress_seq || '.txt''';
    END IF;
    END IF;
 END LOOP;
END;
$$ language plpgsql;

3

- নীচে ফাংশনটিতে সমস্ত টেবিলের তালিকা তৈরি করা হবে যা ডাটাবেসে একটি নির্দিষ্ট স্ট্রিং রয়েছে

 select TablesCount(‘StringToSearch’);

- ডাটাবেসের সমস্ত টেবিলের মধ্য দিয়ে সূচিত করে

CREATE OR REPLACE FUNCTION **TablesCount**(_searchText TEXT)
RETURNS text AS 
$$ -- here start procedural part
   DECLARE _tname text;
   DECLARE cnt int;
   BEGIN
    FOR _tname IN SELECT table_name FROM information_schema.tables where table_schema='public' and table_type='BASE TABLE'  LOOP
         cnt= getMatchingCount(_tname,Columnames(_tname,_searchText));
                                RAISE NOTICE 'Count% ', CONCAT('  ',cnt,' Table name: ', _tname);
                END LOOP;
    RETURN _tname;
   END;
$$ -- here finish procedural part
LANGUAGE plpgsql; -- language specification

- শর্ত পূরণের জন্য সারণীর গণনা ফিরিয়ে দেয়। - উদাহরণস্বরূপ, যদি টেবিলের যে কোনও একটি ক্ষেত্রে উদ্দেশ্যযুক্ত পাঠ্য বিদ্যমান থাকে - তবে গণনাটি 0 এর চেয়ে বেশি হবে We আমরা বিজ্ঞপ্তিগুলি খুঁজে পেতে পারি - পোস্টগ্রিজ ডাটাবেসে ফলাফল দর্শকের বার্তা বিভাগে।

CREATE OR REPLACE FUNCTION **getMatchingCount**(_tname TEXT, _clause TEXT)
RETURNS int AS 
$$
Declare outpt text;
    BEGIN
    EXECUTE 'Select Count(*) from '||_tname||' where '|| _clause
       INTO outpt;
       RETURN outpt;
    END;
$$ LANGUAGE plpgsql;

- প্রতিটি টেবিলের ক্ষেত্রগুলি পান। একটি সারণীর সমস্ত কলাম সহ যেখানে ক্লজ তৈরি করে।

CREATE OR REPLACE FUNCTION **Columnames**(_tname text,st text)
RETURNS text AS 
$$ -- here start procedural part
DECLARE
                _name text;
                _helper text;
   BEGIN
                FOR _name IN SELECT column_name FROM information_schema.Columns WHERE table_name =_tname LOOP
                                _name=CONCAT('CAST(',_name,' as VarChar)',' like ','''%',st,'%''', ' OR ');
                                _helper= CONCAT(_helper,_name,' ');
                END LOOP;
                RETURN CONCAT(_helper, ' 1=2');

   END;
$$ -- here finish procedural part
LANGUAGE plpgsql; -- language specification
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.