PLPGSQL সহ বর্তমান অনুসন্ধান_পথে কোনও সারণী বিদ্যমান কিনা তা আমি কীভাবে নির্ধারণ করতে পারি?


10

আমি একটি অ্যাপ্লিকেশনটির জন্য একটি সেটআপ স্ক্রিপ্ট লিখছি যা অন্য অ্যাপ্লিকেশনটির জন্য একটি অ্যাডন, তাই আমি অন্য অ্যাপ্লিকেশনের টেবিলগুলি বিদ্যমান কিনা তা পরীক্ষা করে দেখতে চাই। যদি তা না হয় তবে আমি ব্যবহারকারীকে একটি দরকারী ত্রুটি দিতে চাই। তবে, আমি জানি না কী স্কিমাটি টেবিলগুলি ধারণ করবে।

DO LANGUAGE plpgsql $$
BEGIN
    PERFORM 1
    FROM
        pg_catalog.pg_class c
        JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
    WHERE
        n.nspname = current_setting('search_path')
        AND c.relname = 'foo'
        AND c.relkind = 'r'; -- not sure if I actually need this or not...

    IF NOT FOUND THEN
        RAISE 'This application depends on tables created by another application';
    END IF;
END;
$$;

যাইহোক, ডিফল্টরূপে থাকা current_setting('search_path')একটি পাঠ্য ফেরত দেয় "$user",publicযা ভয়াবহভাবে কার্যকর নয়।

কেবলমাত্র অন্য যে জিনিসটি আমি ভাবতে পারি তা হ'ল টেবিল থেকে নির্বাচনের চেষ্টা করা এবং ব্যতিক্রমটি ধরা। এটি কাজটি করবে, তবে আমি এটি খুব মার্জিত বলে মনে করি না এবং আমি পড়েছি যে এটি ব্যবহার করা ব্যয়বহুল (যদিও এই পরিস্থিতিতে এটি ঠিক হবে যেহেতু আমি কেবল এটি একবার চালাচ্ছি?)।

উত্তর:


18

দ্রুত এবং ময়লা

Postgres সালে 9.4+ ব্যবহার

SELECT to_regclass('foo');

অনুসন্ধানের পথে সনাক্তকারীকে পাওয়া না গেলে NULL ফেরত দেয়।
পোস্টগ্রিসে 9.3 বা তার বেশি বয়সীদের জন্য একটি কাস্টregclass ব্যবহার করুন :

SELECT 'foo'::regclass;

এটি একটি ব্যতিক্রম উত্থাপন করে , যদি বস্তুটি খুঁজে পাওয়া যায় না!

যদি 'foo'পাওয়া যায়, তবে oidতার textপ্রতিনিধিত্ব করে ফেরত দেওয়া হয় । এটি কেবলমাত্র সারণীর নাম, বর্তমান অনুসন্ধানের পথ অনুসারে স্কিমা-যোগ্য এবং যেখানে প্রয়োজন সেখানে ডাবল-কোটেড।

যদি অবজেক্টটি না পাওয়া যায় তবে আপনি নিশ্চিত হতে পারেন যে এটি অনুসন্ধানের পথের কোথাও নেই or বা স্কিমি-যোগ্য নামের জন্য মোটেই নেই schema.foo)

যদি এটি পাওয়া যায় তবে দুটি ত্রুটি রয়েছে :

  1. অনুসন্ধানের অন্তর্নিহিত স্কিমের অন্তর্ভুক্ত search_path যেমন, pg_catalogএবংpg_temp । তবে আপনি নিজের উদ্দেশ্যে টেম্প এবং সিস্টেম সারণীগুলি বাদ দিতে চাইতে পারেন। (?)

  2. regclassসিস্টেম ক্যাটালগের সমস্ত অবজেক্টের জন্য কাজ করার জন্য একটি কাস্ট pg_class: সূচি, ভিউ, সিকোয়েন্স ইত্যাদি কেবল সারণী নয়। আপনি একচেটিয়াভাবে একটি নিয়মিত টেবিল খুঁজছেন বলে মনে হচ্ছে। তবে একই নামের অন্যান্য বস্তুতেও সম্ভবত আপনার সমস্যা আছে। বিবরণ:

ধীর এবং নিশ্চিত

আমরা আপনার অনুসন্ধানে ফিরে এসেছি, তবে ব্যবহার করবেন না current_setting('search_path'), যা খালি সেটিংটি দেয় returns ডেডিকেটেড সিস্টেম তথ্য ফাংশন ব্যবহার করুন current_schemas()। প্রতি ডকুমেন্টেশন:

current_schemas(boolean) name[]
অনুসন্ধানের পথে স্কিমার নামগুলি impচ্ছিকভাবে অন্তর্নিহিত স্কিমা সহ

"$user"অনুসন্ধানের পথে চূড়ান্তভাবে সমাধান করা হয়। নামের সাথে কোনও স্কিমা SESSION_USERউপস্থিত না থাকলে স্কিমাটি আরম্ভ করার জন্য ফিরে আসে না। এছাড়াও, আপনি ঠিক কী চান তার উপর নির্ভর করে, আপনি অতিরিক্তভাবে অন্তর্নিহিত স্কিমাগুলি ( pg_catalogএবং সম্ভবত pg_temp) আউটপুটও করতে পারেন - তবে আমি ধরে নিই যে আপনি হাতে থাকা মামলায় এইগুলি চান না, তাই ব্যবহার করুন:

DO 
$do$
BEGIN
   IF EXISTS (
      SELECT  -- list can be empty
      FROM   pg_catalog.pg_class c
      JOIN   pg_catalog.pg_namespace n ON n.oid = c.relnamespace
      WHERE  n.nspname = ANY(current_schemas(FALSE))
      AND    n.nspname NOT LIKE 'pg_%'  -- exclude system schemas!
      AND    c.relname = 'foo'
      AND    c.relkind = 'r')           -- you probably need this
   THEN
      RAISE 'This application depends on tables created by another application';
   END IF;
END
$do$;

এসকিউএল ফিডল , সর্বশেষDOবিবৃতিব্যতীত সমস্ত প্রদর্শন করছে।
এসকিউএল ফিডল (জেডিবিসি) এর DOসমাপ্তি অক্ষরযুক্ত বিবৃতিতে সমস্যা রয়েছে ।


1

আপনি কনফিগার মানটি একটি অ্যারেতে রূপান্তর করতে পারেন এবং $userবর্তমান ব্যবহারকারীর নামের সাথে প্রতিস্থাপন করতে পারেন । অ্যারেটি যেখানে অবস্থাতে ব্যবহার করা যেতে পারে:

where n.nspname = any(string_to_array(replace(current_setting('search_path'), '$user', current_user), ','))

0
./sshi.sh vb20deployment controller <<'HERE'
export PGPASSWORD="postgres"
cd logu/postgresql/bin
row=1
tableArray=(table1 table2 table3 table4 table5 table6)

for (( x=0 ; x<=5 ; x++)) ; do        

./psql.bin --port=5432 --username=postgres --host=hostname.rds.amazonaws.com --dbname=mydb -c "SELECT * FROM information_schema.tables WHERE '${tableArray[$x]}' = table_name" | while read -a Record ; do
  row=$((row + 1))
  if [[ $row -gt 3 ]]; then

     echo ${Record[4]}

   fi
done

done


HERE
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.