Tergantung pada apa yang ingin Anda uji dengan tepat .
Skema informasi?
Untuk menemukan "apakah tabel itu ada" ( tidak peduli siapa yang bertanya ), menanyakan skema informasi ( information_schema.tables
) tidak benar , secara tegas, karena ( per dokumentasi ):
Hanya tabel dan tampilan yang ditunjukkan bahwa pengguna saat ini memiliki akses ke (dengan cara menjadi pemilik atau memiliki hak istimewa).
Permintaan yang diberikan oleh @kong dapat kembali FALSE
, tetapi tabel masih bisa ada. Itu menjawab pertanyaan:
Bagaimana cara memeriksa apakah tabel (atau tampilan) ada, dan pengguna saat ini memiliki akses ke sana?
SELECT EXISTS (
SELECT FROM information_schema.tables
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
);
Skema informasi terutama berguna untuk tetap portabel di versi utama dan di RDBMS yang berbeda. Tetapi implementasinya lambat, karena Postgres harus menggunakan pandangan yang canggih untuk memenuhi standar ( information_schema.tables
adalah contoh yang agak sederhana). Dan beberapa informasi (seperti OID) hilang dalam terjemahan dari katalog sistem - yang sebenarnya membawa semua informasi.
Katalog sistem
Pertanyaan anda adalah:
Bagaimana cara memeriksa apakah suatu tabel ada?
SELECT EXISTS (
SELECT FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'schema_name'
AND c.relname = 'table_name'
AND c.relkind = 'r' -- only tables
);
Gunakan katalog sistem pg_class
dan pg_namespace
secara langsung, yang juga jauh lebih cepat. Namun, per dokumentasi tentangpg_class
:
Katalog pg_class
katalog tabel dan sebagian besar segala sesuatu yang memiliki kolom atau mirip dengan tabel. Ini termasuk indeks (tetapi lihat juga pg_index
), urutan , tampilan , tampilan terwujud , tipe komposit , dan tabel TOAST ;
Untuk pertanyaan khusus ini, Anda juga dapat menggunakan sistempg_tables
. Sedikit lebih sederhana dan lebih portabel di seluruh versi Postgres utama (yang hampir tidak menjadi perhatian untuk permintaan dasar ini):
SELECT EXISTS (
SELECT FROM pg_tables
WHERE schemaname = 'schema_name'
AND tablename = 'table_name'
);
Pengidentifikasi harus unik di antara semua objek yang disebutkan di atas. Jika Anda ingin bertanya:
Bagaimana cara memeriksa apakah nama untuk tabel atau objek serupa dalam skema yang diberikan diambil?
SELECT EXISTS (
SELECT FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'schema_name'
AND c.relname = 'table_name'
);
Alternatif: dilemparkan ke regclass
SELECT 'schema_name.table_name'::regclass
Ini memunculkan pengecualian jika tabel (yang memenuhi syarat skema) (atau objek lain yang menggunakan nama itu) tidak ada.
Jika Anda tidak memenuhi syarat skema nama tabel, gips ke regclass
default ke search_path
dan mengembalikan OID untuk tabel pertama yang ditemukan - atau pengecualian jika tabel tidak ada dalam skema yang terdaftar. Perhatikan bahwa skema sistempg_catalog
dan pg_temp
(skema untuk objek sementara dari sesi saat ini) secara otomatis menjadi bagian dari search_path
.
Anda bisa menggunakannya dan menangkap kemungkinan pengecualian dalam suatu fungsi. Contoh:
Kueri seperti di atas menghindari kemungkinan pengecualian dan karenanya sedikit lebih cepat.
Jauh lebih sederhana sekarang:
SELECT to_regclass('schema_name.table_name');
Sama seperti para pemain, tetapi mengembalikan ...
... null daripada melemparkan kesalahan jika nama tidak ditemukan
[[ `psql dbname -tAc "SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'ejabberd' AND table_name = 'users');"` = 't' ]]
pg_tables
sebenarnya adalah ide yang bagus untuk "Bagaimana cara memeriksa apakah tabel ada?" (Memeriksa tabel hanya ., Bukan untuk tujuan lain, seperti dijelaskan di atas juga,pg_tables
adalah pandangan yang melibatkan beberapa tabel (pg_class
,pg_namespace
,pg_tablespace
), yang sedikit lebih mahal Yang paling alasan penting. Aku digunakan untuk permintaanpg_class
langsung dan tidak pikirkanpg_tables
ketika menulis jawaban ini. Saya menambahkannya di atas sekarang, terima kasih.pg_my_temp_schema()
untuk mendapatkan OID dari skema temp aktual jika ada. (Tapi pandangan dalaminformation_schema
jangan menyertakan OID. Anda bisaSELECT nspname FROM pg_namespace WHERE OID = pg_my_temp_schema()
) Tes Anda memiliki beberapa kelemahan. Sebuah tes yang benar akantable_schema LIKE 'pg\_temp\_%'
atau ketat:table_schema ~ '^pg_temp_\d+$'
.Mungkin menggunakan information_schema :
sumber
Untuk PostgreSQL 9.3 atau kurang ... Atau yang suka semua dinormalisasi ke teks
Tiga rasa perpustakaan SwissKnife lama saya:
relname_exists(anyThing)
,relname_normalized(anyThing)
danrelnamechecked_to_array(anyThing)
. Semua cek dari tabel pg_catalog.pg_class , dan mengembalikan tipe data universal standar ( boolean , teks atau teks []).sumber