Tanyakan definisi pandangan terwujud dalam Postgres

21

Saya bertanya-tanya bagaimana cara menanyakan definisi tampilan terwujud di Postgres. Sebagai referensi, apa yang saya harap lakukan sangat mirip dengan apa yang dapat Anda lakukan untuk tampilan reguler:

SELECT * FROM information_schema.views WHERE table_name = 'some_view';

yang memberi Anda kolom berikut:

table_catalog
table_schema
table_name
view_definition
check_option
is_updatable
is_insertable_into
is_trigger_updatable
is_trigger_deletable
is_trigger_insertable_into

Apakah ini mungkin untuk pandangan terwujud?

Dari penelitian saya sejauh ini, tampaknya pandangan terwujud sengaja dikeluarkan dari information_schema, karena

Information_schema hanya dapat menampilkan objek yang ada dalam standar SQL.

( http://www.postgresql.org/message-id/[email protected] )

Karena mereka tampaknya sepenuhnya dikecualikan dari information_schema, saya tidak yakin bagaimana cara melakukannya, tetapi yang ingin saya lakukan ada dua:

  1. Menanyakan apakah ada tampilan terwujud tertentu. (Sejauh ini satu-satunya cara yang saya temukan untuk melakukan ini adalah mencoba membuat tampilan mat dengan nama yang sama dan melihat apakah itu meledak.)
  2. Dan kemudian query definisi tampilan terwujud (mirip dengan view_definitionkolom aktif information_schema.views).
Sean the Bean
sumber
Pertanyaan yang agak terkait tentang permintaan batasan unik pada tampilan terwujud: dba.stackexchange.com/questions/101899
Sean the Bean
Anda akan tertarik pada cara cepat untuk menguji keberadaan: SELECT to_regclass('some_schema.some_mat_view')- jika ditemukan, itu tidak harus menjadi MV. Detail: stackoverflow.com/questions/20582500/…
Erwin Brandstetter
Juga: stackoverflow.com/questions/23092983/…
Erwin Brandstetter

Jawaban:

13

Ternyata ini tidak serumit yang saya kira! (Dengan hanya sedikit pengetahuan tentang pg_catalog ...)

Bagian 1: Permintaan apakah ada tampilan terwujud:

SELECT count(*) > 0
FROM pg_catalog.pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'm'
AND n.nspname = 'some_schema'
AND c.relname = 'some_mat_view';

Baik dan mudah.

Bagian 2: Permintaan definisi tampilan terwujud:

Untuk mendapatkan kueri untuk mendapatkan definisi tampilan mat, pertama-tama saya harus mencari definisi information_schema.viewstampilan dengan menjalankan:

SELECT view_definition
FROM information_schema.views
WHERE table_schema = 'information_schema'
AND table_name = 'views';

Kemudian saya menyalin query dan berubah c.relkind = 'v'::"char"untuk c.relkind = 'm'::"char"untuk mendapatkan pandangan tikar (bukan pandangan biasa). Lihat kueri lengkap di sini: http://pastebin.com/p60xwfes

Pada titik ini Anda bisa dengan mudah menambahkan AND c.relname = 'some_mat_view'dan menjalankannya untuk mendapatkan definisi some_mat_view.

Tetapi Anda masih harus melakukan ini lagi saat Anda ingin mencari definisi tampilan mat ...

Bonus: Buat tampilan untuk mempermudah ini

Saya memilih untuk membuat tampilan baru agar lebih mudah mencari definisi tampilan mat di masa depan. Saya pada dasarnya baru saja menambahkan CREATE VIEW materialized_views ASke awal kueri yang ditautkan di atas untuk membuat tampilan baru, dan sekarang saya bisa melakukan kueri seperti:

SELECT *
FROM materialized_views
WHERE table_schema = 'some_schema'
AND table_name = 'some_mat_view';

Jauh lebih baik!

Saya juga bisa menggunakan tampilan ini untuk dengan mudah menanyakan apakah ada tampilan terwujud dengan mengubah *ke count(*) > 0.

Penafian : Saya tidak tahu itu kolom lain dalam hasil kueri sepenuhnya benar, karena pandangan terwujud secara fundamental berbeda dari pandangan standar (saya pikir mereka benar). Tapi ini setidaknya permintaan table_schema, table_namedan view_definitiondengan benar.

Sean the Bean
sumber
0

Kekurangannya dengan jawaban lain di sini adalah Anda baru saja mendapatkan definisi SQL, sedangkan dalam kebanyakan kasus Anda tertarik pada kolom yang sebenarnya, dan dapat memanipulasi mereka sebagai teks. Berikut ini adalah jawaban saya dari pertanyaan serupa , yang mencakup nama kolom dan tipe data:

Saya tidak bisa mengatakan bahwa saya sepenuhnya memahami model data yang mendasarinya, jadi gunakan solusi saya di bawah ini dengan sebutir garam:

select 
    ns.nspname as schema_name, 
    cls.relname as table_name, 
    attr.attname as column_name,
    trim(leading '_' from tp.typname) as datatype
from pg_catalog.pg_attribute as attr
join pg_catalog.pg_class as cls on cls.oid = attr.attrelid
join pg_catalog.pg_namespace as ns on ns.oid = cls.relnamespace
join pg_catalog.pg_type as tp on tp.typelem = attr.atttypid
where 
    ns.nspname = 'your_schema' and
    cls.relname = 'your_materialized_view' and 
    not attr.attisdropped and 
    cast(tp.typanalyze as text) = 'array_typanalyze' and 
    attr.attnum > 0
order by 
    attr.attnum

Anda harus berubah 'your_schema'dan 'your_materialized_view'.

André Christoffer Andersen
sumber