Fungsi untuk mendokumentasikan database PostgreSQL. Bagian satu

Selama bekerja dengan PostgreSQL, lebih dari seratus fungsi untuk bekerja dengan direktori sistem telah terakumulasi: pg_class, pg_attribute, pg_constraints, dll.


Apa yang harus dilakukan dengan mereka? Mereka digunakan relatif jarang. Sertakan dalam proyek apa pun? Pelanggan Krasnoyarsk tidak akan membayar "omong kosong" seperti itu. Namun, bagaimana jika mereka bermanfaat bagi orang lain selain penulis. Dan dia memutuskan untuk meletakkannya, seperti membaca buku, di lemari umum untuk mereka yang menginginkannya.

Seseorang ingin menggunakannya dalam pekerjaan mereka. Dan seseorang tertarik selain dari pengalaman mereka dengan katalog sistem.

Tetapi agar tidak mengubah publikasi menjadi enumerasi yang membosankan, tidak diketahui mengapa fungsi-fungsi itu dibuat, saya memutuskan untuk memikirkan fungsi-fungsi itu yang bisa disatukan oleh tujuan bersama. Oleh karena itu, fungsi yang digunakan untuk menampilkan daftar karakteristik tabel tabel arbitrer dipilih.

Daftar diperpanjang karakteristik tabel database dikembalikan oleh fungsi admtf_Table_ComplexFeatures , yang akan disebut fungsi kepala dalam artikel ini. Dengan demikian, artikel akan dibatasi untuk mempertimbangkan fungsi-fungsi yang dipanggil dalam proses mengeksekusi fungsi kepala.

Paruh pertama artikel memberikan komentar tentang implementasi fungsi. Yang kedua adalah kode sumber fungsi. Bagi pembaca yang hanya tertarik pada teks sumber, kami sarankan segera melanjutkan ke Lampiran .

Lihat juga
Fungsi untuk mendokumentasikan database PostgreSQL. Bagian dua ;
Fungsi untuk mendokumentasikan database PostgreSQL. Bagian tiga .
Fungsi untuk mendokumentasikan database PostgreSQL. Akhir (bagian empat) .




Apa fitur canggih yang sedang kita bicarakan?


Untuk mendapatkan ide tentang apa yang dimaksud dengan karakteristik yang diperluas dari tabel database, kita mulai dengan mempertimbangkan daftar karakteristik berikut. Daftar ini berisi karakteristik tabel database Street yang dikembalikan oleh admtf_Table_ComplexFeatures ( 'publik' , 'street' ) .

Tabel di bawah ini berisi daftar fitur Street table yang disingkat. Seperangkat karakteristik lengkap dari tabel ini diberikan dalam Bahan Pelengkap Lampiran 2.

Tabel 1. Fitur lanjutan dari tabel Street.

Versi teks dari tabel pada gambar
KategoriTidak.JudulKomentarjenisJenis dasar? bukan NULL
tbl0jalanDaftar jalan di pemukiman
att1kode sandiKode negarakode sandismallintt
att2localityidID komunitaslocalityidbilangan bulatt
att3streetidID jalan desastreetidsmallintt
att4streettypeacrmAkronim Jalanstreettypeacrmkarakter (8)f
att5nama jalanNama jalanstreettypeacrmvarchar (150)t
pk0xpkstreetKunci utama meja jalan
pkatt1kode sandiKode negarakode sandismallintt
fk011fk_street_localityMeja kunci asing
fk022fk_street_streettypeMeja kunci asing
idx011xie1 jalanIndeks berdasarkan jenis dan nama jalan pemukiman
idx022xie2jalanKode pos
idx033xie3jalanIndeks nama jalan semua pemukiman
idx044xpkstreetIndeks unik (kunci utama) dari tabel jalan


Merinci permusuhan pada set huruf dan angka ini, Anda dapat melihat bahwa kita berbicara tentang karakteristik biasa dari tabel database:


  • Nama tabel;
  • Daftar atribut tabel dan tipenya;
  • Kunci utama dan daftar kunci asing tabel, bersama dengan atribut tabel yang menyusunnya
  • Daftar indeks tabel.

Keunikan setiap entri dari daftar karakteristik dijamin oleh nilai-nilai bidang "kategori" dan nomor seri ("Tidak.") Dari karakteristik.



Tabel 2. Kategori karakteristik tabel.

Versi teks dari tabel pada gambar
AkronimJanji temu
tbKarakteristik tabel
attKarakteristik Atribut Tabel
seqKarakteristik urutan
pkFitur Utama Utama
pkAttKarakteristik Atribut Kunci Utama
fk99Fitur Utama Asing
fk99attKarakteristik Atribut Kunci Asing
fk99rtblKarakteristik tabel direferensikan oleh kunci asing
fk99rattKarakteristik atribut dari tabel yang dirujuk oleh kunci asing
Idx99Karakteristik indeks
Idx99attKarakteristik Atribut Indeks
Inhtbl99Karakteristik tabel yang dihasilkan


Nilai kategori diperlukan untuk membedakan kelompok karakteristik yang berbeda satu sama lain. Nomor seri, untuk membedakan karakteristik dalam grup.


Beberapa kunci asing (KUNCI ASING) dan indeks dapat dideklarasikan dalam tabel database. Oleh karena itu, nilai kategori untuk karakteristik ini dan turunannya berisi nomor seri. Misalnya, entri dengan kunci β€œKategori” = idx02att dan β€œNo.” = 1 menunjukkan atribut pertama dari indeks ke-2.


Dalam daftar kategori di atas, lokasi nomor seri ditunjukkan sebagai '99'.


Komentar 1



kode sumber operator pada gambar
SELECT * FROM admtf_Table_ComplexFeatures('pg_catalog','pg_class'); 



Artikel ini memberikan contoh karakteristik tabel, yang dijelaskan secara singkat dalam skema tambahan yang dibuat khusus untuk menunjukkan kemampuan fungsi. Tetapi pembaca, setelah membuat fungsi ini atau itu dalam database-nya, dapat menggunakan nama skema dan tabelnya sebagai parameter. Selain itu, misalnya, direktori pg_class dapat digunakan sebagai parameter, meskipun dalam hal ini sejumlah karakteristik dikeluarkan.

Akhir dari komentar itu.



Struktur fungsi kepala



Fig. 1. Fungsi yang menyebabkan fungsi kepala.

Tabel 3. Penugasan fungsi.

Versi teks dari tabel pada gambar
Tidak.JudulJanji temu
1admtf_Table_FeaturesFungsi mengembalikan daftar karakteristik tabel database
2admtf_Table_AttributesFungsi mengembalikan daftar atribut tabel database dan karakteristiknya.
3admtf_Table_ConstraintesFungsi mengembalikan daftar pembatasan tabel database dan karakteristiknya.
4admtf_Table_IndexesFungsi mengembalikan daftar indeks tabel database dan karakteristiknya.
5admtf_Table_InheritanceChildrensFungsi mengembalikan daftar tabel yang dihasilkan oleh (IHERITS) dari tabel basis data sumber.
6admtf_Table_SequencesFungsi mengembalikan daftar urutan (URUTAN) di mana tabel tergantung.
7admtf_PrimaryKey_ComplexFeaturesFungsi mengembalikan daftar lengkap (diperluas) karakteristik kunci utama (PRIMARY KEY) dari tabel database.
8admtf_ForeignKey_ComplexFeaturesFungsi mengembalikan daftar lengkap (diperpanjang) karakteristik kunci asing (KUNCI ASING) dari tabel database.
9admtf_Index_ComplexFeaturesFungsi mengembalikan daftar lengkap (diperluas) karakteristik indeks tabel database.
10admtf_Table_ComplexFeaturesFungsi mengembalikan daftar lengkap (diperluas) karakteristik tabel database.


Komentar 2.


Deskripsi fungsi akan diatur dalam urutan yang ditunjukkan di atas. Alasannya adalah bahwa artikel tersebut harus dibagi menjadi beberapa bagian. Dan fungsi-fungsi yang diatur dalam urutan ini dapat digunakan terlepas dari kenyataan bahwa beberapa di antaranya hanya akan dijelaskan di bagian publikasi berikut.


Akhir dari komentar itu.



Admtf_Table_Features daftar fungsi karakteristik tabel database




Fungsi admtf_Table_Features mengembalikan daftar karakteristik tabel database itu sendiri. Kode sumber dapat dilihat dan diunduh di sini.


Sebagai parameter, fungsi tersebut mengambil nama tabel sumber (a_TableName ) dan nama skema tempat tabel dibuat ( a_SchemaName ).


Fungsi ini mengekstrak data dasar dari entri katalog pg_class , yang berisi, selain entri tabel, juga mencatat tentang urutan, tampilan, tampilan terwujud, dan tipe komposit. Oleh karena itu, untuk memilih tabel, kondisi relkind = 'r' digunakan .



 SELECT tbl.relname,dsc.description,tbl.relnatts::INTEGER,tbl.relchecks::INTEGER, tbl.relhaspkey,tbl.relhasindex,tbl.relhassubclass,tbl.reltuples::INTEGER FROM pg_class tbl INNER JOIN pg_namespace nspc ON tbl.relnamespace = nspc.oid LEFT OUTER JOIN pg_description dsc ON tbl.oid=dsc.objoid AND dsc.objsubid=0 WHERE LOWER( nspc.nspname)=LOWER(a_SchemaName) AND tbl.relkind='r' AND LOWER(tbl.relname) =LOWER(a_TableName); 

Selain itu, fungsi mengakses data direktori pg_namespace dan pg_description . Yang pertama berisi nama skema database, dan yang kedua berisi komentar pada semua objek database.


Penting untuk memperhatikan kondisi objsubid = 0 . Ini mendefinisikan komentar di atas meja, karena nilai dari bidang objek adalah sama untuk kedua tabel dan atributnya. Komentar pada atribut tabel terdapat dalam entri di mana objsub cocok dengan jumlah atribut ini.



Tabel 4. Hasil dari mengeksekusi fungsi admtf_Table_Features ('public', 'Street').

JudulKomentarJumlah atributJumlah Kendala PERIKSA? apakah ada kunci utama? adalah indeks yang diumumkan? apakah ada keturunanJumlah entri dalam tabel
jalanDaftar jalan di pemukiman220ttf20150

Komentar 3


Perhatikan jumlah atribut tabel jalan. Ini berbeda secara signifikan dari jumlah atribut yang ditentukan dalam skema bantu.


Tabel 5. Atribut tambahan dari tabel Street.


attnameatttypidattnumCatatan
cminTanggal 29-4Atribut sistem
xmin28-3Atribut sistem
ctid27-1Atribut sistem
kode sandi7953691Atribut yang valid
localityid7953522Atribut yang valid
streetid7953643Atribut yang valid
streettypeacrm19191684Atribut yang valid
nama jalan10435Atribut yang valid
........ pg.dropped.6 ........06Atribut jarak jauh
........ pg.dropped.7 ........07Atribut jarak jauh

Faktanya adalah bahwa PostgreSQL, selain atribut utama, juga memperhitungkan beberapa atribut sistem, dan bahkan atribut yang dihapus.


Komentar akhir



Function admtf_Table_Attributes daftar atribut tabel database dan karakteristiknya


Fungsi admtf_Table_Attributes mengembalikan daftar atribut tabel database. Kode sumber dapat dilihat dan diunduh di sini.


Sebagai parameter, fungsi tersebut mengambil nama tabel sumber ( a_TableName ) dan nama skema tempat tabel dibuat ( a_SchemaName ).


Fungsi mengambil data utama dari entri direktori pg_attribute dan pg_type . Yang pertama berisi catatan dengan data tentang atribut tabel, tampilan, tampilan terwujud, tipe komposit, dan bahkan fungsi. Yang kedua adalah tentang karakteristik tipe atribut.


Mungkin beberapa klarifikasi diperlukan dengan cara agar pengguna dan tipe dasar didefinisikan dalam fungsi.


Atribut tabel dideklarasikan dengan tipe kustom jika bidang typbasetype lebih besar dari 0 dalam entri direktori pg_type yang sesuai. Jika tidak, atributnya adalah tipe dasar. Oleh karena itu, direktori pg_type terlibat dua kali dalam klausa FROM. Di entri direktori pertama, keberadaan tipe pengguna ditentukan, jika tidak ditentukan ( typbasetype = 0 ), maka nilai tipe dasar dihasilkan dari entri ini. Kalau tidak, tipe dasar ditentukan dari catatan yang btyp.OID = typ.typbasetype.


Secara langsung garis dengan tipe dasar dibentuk menggunakan fungsi katalog sistem FORMAT_TYPE (type_oid, typemod) . Parameter pertama di antaranya adalah tipe dasar catatan OID. Parameter kedua adalah nilai pengubah untuk jenis yang berisi ukuran. Misalnya, VARCHAR (100) atau NUMERIC (4,2), DECIMAL (4,2). Nilai parameter typemod diambil dari typ.typtypmod jika atributnya adalah tipe pengguna, jika tidak dari attr.atttypmod , mis. langsung dari catatan atribut.



kode sumber operator pada gambar
 SELECT attr.attnum, attr.attname::VARCHAR(100), CASE WHEN COALESCE(typ.typbasetype,0)>0 THEN typ.typname::VARCHAR(100) ELSE '' END, FORMAT_TYPE(COALESCE(NULLIF(typ.typbasetype,0),typ.oid), COALESCE(NULLIF(typ.typtypmod,-1),attr.atttypmod))::VARCHAR(256), attr.attnotnull, dsc.description FROM pg_attribute attr INNER JOIN pg_class tbl ON tbl.oid = attr.attrelid INNER JOIN pg_namespace nspc ON tbl.relnamespace = nspc.oid INNER JOIN pg_type typ ON attr.atttypid=typ.oid LEFT OUTER JOIN pg_description dsc ON dsc.objoid=attr.attrelid AND dsc.objsubid=attr.attnum WHERE LOWER( nspc.nspname)=LOWER(a_SchemaName) AND LOWER(tbl.relname) =LOWER(a_TableName) AND tbl.relkind='r' AND attr.attnum>0 AND attr.atttypID>0 ORDER BY tbl.relname,attr.attnum; 


Selain itu, fungsi mengakses data direktori pg_class , pg_namespace dan pg_description . Direktori pertama dan kedua digunakan untuk mencari atribut dengan nama skema dan tabel database.

Direktori ketiga digunakan untuk mengambil komentar untuk atribut tabel.


Komentar pada atribut tabel ada di entri di mana dsc.objoid berisi OID dari tabel sumber, dan dsc.objsubid adalah nomor seri dari atribut dalam tabel, yaitu. attr.attnum .


Untuk mencegah fungsi mengembalikan atribut sistem dan jarak jauh, klausa WHERE menetapkan kondisi attr.attnum> 0 AND attr.atttypID> 0 .



Tabel 6. Hasil menjalankan fungsi admtf_Table_Attributes ('publik', 'Street').

Tidak.JudulJenis khususJenis dasar? bukan NULLKomentar
1kode sandikode sandismallinttKode negara
2localityidlocalityidbilangan bulattID komunitas
3streetidstreetidsmallinttID jalan desa
4streettypeacrmstreettypeacrmkarakter (8)fAkronim Jalan
5nama jalanvarchar (150)tNama jalan pemukiman

Versi fungsi menggunakan regclass alias untuk tipe oid


Pengidentifikasi objek PostgreSQL (OID) memiliki tipe yang sama dengan OID, yang saat ini diimplementasikan sebagai integer empat-byte yang tidak ditandatangani. Tetapi karena adanya alias dari tipe ini, integer dapat direpresentasikan sebagai nama objek. Dan sebaliknya - mengonversi nama objek menjadi bilangan bulat dari tipe OID.


Sebagai contoh, lihat pernyataan SELECT berikut. Itu biasa mengambil nama-nama tabel atribut dan nama-nama jenisnya - alih-alih mengakses bidang direktori yang sesuai dengan nama-nama karakteristik ini, mereka digunakan:

  • attrelid :: regclass (attrelid :: regclass: NAME) ,
  • atttypid :: regtype (atttypid :: regtype: NAME)
  • typbasetype :: regtype (typbasetype :: regtype: NAME) .


 SELECT attr.attname,attr.attrelid::regclass, attr.atttypid::regtype, typ.typbasetype::regtype,attr.attrelid::regclass::name, attr.atttypid::regtype::name,typ.typbasetype::regtype::name FROM pg_attribute attr INNER JOIN pg_type typ ON attr.atttypid=typ.oid WHERE attr.attrelid=('public'||'.'||'Street')::regclass AND attr.attnum>0 AND attr.atttypID>0 ORDER BY attr.attnum; 

Berikut ini adalah hasil dari mengeksekusi query ini.



Dalam daftar nilai output dari operator SELECT sebelum konversi menggunakan alias dari tipe OID, semua nilai kecuali nama atribut adalah angka, tetapi sebagai hasilnya, nama tabel dan tipe atribut ditampilkan. Jenis nilai output dapat dipertimbangkan di baris kedua dari header tabel.


Selain itu, dalam klausa WHERE pernyataan, kondisi attr.attrelid = ('public' || '.' || 'Street') :: regclass terletak , di sisi kiri yang merupakan nilai numerik, dan di sebelah kanan adalah string yang dikonversi ke nilai numerik dengan menggunakan alias regclass .



kode sumber operator pada gambar
 SELECT attr.attnum, attr.attname::VARCHAR(100), CASE WHEN COALESCE(typ.typbasetype,0)>0 THEN typ.typname::VARCHAR(100) ELSE '' END, FORMAT_TYPE(COALESCE(NULLIF(typ.typbasetype,0),typ.oid), COALESCE(NULLIF(typ.typtypmod,-1),attr.atttypmod))::VARCHAR(256), attr.attnotnull, dsc.description FROM pg_attribute attr INNER JOIN pg_type typ ON attr.atttypid=typ.oid LEFT OUTER JOIN pg_description dsc ON dsc.objoid=attr.attrelid AND dsc.objsubid=attr.attnum WHERE attr.attrelid=( a_SchemaName ||'.'|| a_TableName)::regclass AND attr.attnum>0 AND attr.atttypID>0 ORDER BY attr.attnum; 


Menggunakan alias regclass dari pernyataan utama, Anda dapat menghapus koneksi ke dua direktori. Tetapi peningkatan seperti itu hampir tidak berpengaruh pada kinerja fungsi - di kedua versi, fungsi dieksekusi dalam 11 ms. Mungkin karena fakta bahwa tabel tes memiliki beberapa atribut.
Komentar 4

Kelemahan serius dalam kondisi dalam bentuk attr.attrelid = (a_SchemaName || '.' || a_TableName) :: regclass dimanifestasikan ketika ada skema dan / atau tabel dengan nama yang tidak biasa dalam database. Misalnya, "Skema saya" dan / atau "Tabel saya" . Nilai-nilai tersebut harus ditransmisikan dalam tanda kutip ganda atau menggunakan fungsi QUOTE_IDENT, jika tidak fungsi tersebut akan gagal dengan kesalahan sistem.



kode sumber operator pada gambar
 /*       Β«   Β»*/ SELECT attr.attname,attr.attrelid::regclass, attr.atttypid::regtype,typ.typbasetype::regtype, attr.attrelid::regclass::name, attr.atttypid::regtype::name,typ.typbasetype::regtype::name FROM pg_attribute attr INNER JOIN pg_type typ ON attr.atttypid=typ.oid WHERE attr.attrelid=(' '||'.'||' ')::regclass AND attr.attnum>0 AND attr.atttypID>0 ORDER BY attr.attnum; /*       */ SELECT attr.attname,attr.attrelid::regclass, attr.atttypid::regtype,typ.typbasetype::regtype, attr.attrelid::regclass::name, attr.atttypid::regtype::name,typ.typbasetype::regtype::name FROM pg_attribute attr INNER JOIN pg_type typ ON attr.atttypid=typ.oid WHERE attr.attrelid=('" "'||'.'||'" "')::regclass AND attr.attnum>0 AND attr.atttypID>0 ORDER BY attr.attnum; 


Oleh karena itu, saya lebih suka menggunakan kondisi dalam bentuk RENDAH (nspc.nspname) = RENDAH (a_SchemaName) DAN RENDAH (tbl.relname) = RENDAH (a_TableName) , yang tidak menyebabkan kesalahan sistem.

Komentar akhir

LAMPIRAN 1. Skrip


Membuat Fungsi admtf_Table_Features


Komentar pada kode sumber fungsi dapat ditemukan di sini.
kode sumber fungsi
 BEGIN TRANSACTION; DROP FUNCTION IF EXISTS admtf_Table_Features (a_SchemaName NAME,a_TableName NAME); /********************************************************************************************************/ /*     ,   */ /********************************************************************************************************/ CREATE OR REPLACE FUNCTION admtf_Table_Features (a_SchemaName NAME default 'public', /*     */ a_TableName NAME default NULL /*   */ ) RETURNS TABLE (rs_TableName NAME,rs_TableDescription TEXT,rs_NumberOfAttribute INTEGER,rs_NumberOfChecks INTEGER,rs_hasPKey BOOLEAN,rs_hasIndex BOOLEAN,rs_hasSubClass BOOLEAN,rs_NumberOfRow INTEGER) AS $BODY$ DECLARE c_TableKind CONSTANT CHAR:='r'; v_TableOID OID; /*   */ v_TableName NAME; /*   */ v_TableDescription TEXT; /*   */ v_TableNumberOfRowCalc INTEGER; /*     */ --****************************************************************************************************** BEGIN SELECT INTO rs_TableName,rs_TableDescription,rs_NumberOfAttribute, rs_NumberOfChecks,rs_hasPKey,rs_hasIndex,rs_hasSubClass, rs_NumberOfRow tbl.relname,dsc.description,tbl.relnatts::INTEGER,tbl.relchecks::INTEGER, tbl.relhaspkey,tbl.relhasindex,tbl.relhassubclass,tbl.reltuples::INTEGER FROM pg_class tbl INNER JOIN pg_namespace nspc ON tbl.relnamespace = nspc.oid LEFT OUTER JOIN pg_Description dsc ON tbl.oid=dsc.objoid AND dsc.objsubid=0 WHERE nspc.nspname=LOWER(a_SchemaName) AND tbl.relkind=c_TableKind AND tbl.relname =LOWER(a_TableName); EXECUTE 'SELECT count(*) FROM ' ||LOWER(a_SchemaName) ||'.'||quote_ident(LOWER(a_TableName)) INTO v_TableNumberOfRowCalc; RETURN QUERY SELECT rs_TableName,rs_TableDescription,rs_NumberOfAttribute, rs_NumberOfChecks,rs_hasPKey,rs_hasIndex, rs_hasSubClass,v_TableNumberOfRowCalc AS rs_NumberOfRow; END $BODY$ LANGUAGE plpgsql; COMMENT ON FUNCTION admtf_Table_Features(a_SchemaName NAME,a_TableName NAME) IS '   ,  '; --ROLLBACK TRANSACTION; COMMIT TRANSACTION; BEGIN TRANSACTION; DROP FUNCTION IF EXISTS admtf_Table_Features (a_SchemaName VARCHAR(256),a_TableName VARCHAR(256)); /********************************************************************************************************/ /*     ,   */ /********************************************************************************************************/ CREATE OR REPLACE FUNCTION admtf_Table_Features (a_SchemaName VARCHAR(256) default 'public', /*     */ a_TableName VARCHAR(256) default NULL /*   */ ) RETURNS TABLE (rs_TableName VARCHAR(256),rs_TableDescription TEXT,rs_NumberOfAttribute INTEGER,rs_NumberOfChecks INTEGER,rs_hasPKey BOOLEAN,rs_hasIndex BOOLEAN,rs_hasSubClass BOOLEAN,rs_NumberOfRow INTEGER) AS $BODY$ DECLARE c_TableKind CONSTANT CHAR:='r'; v_TableOID OID; /*   */ v_TableName VARCHAR(256); /*   */ v_TableDescription TEXT; /*   */ v_TableNumberOfRowCalc INTEGER; /*     */ --****************************************************************************************************** BEGIN RETURN QUERY SELECT tf.rs_TableName::VARCHAR(256), tf.rs_TableDescription::TEXT, tf.rs_NumberOfAttribute::INTEGER, tf.rs_NumberOfChecks::INTEGER, tf.rs_hasPKey::BOOLEAN, tf.rs_hasIndex::BOOLEAN, tf.rs_hasSubClass::BOOLEAN, tf.rs_NumberOfRow::INTEGER FROM admtf_Table_Features(a_SchemaName::NAME,a_TableName::NAME) tf; END $BODY$ LANGUAGE plpgsql; COMMENT ON FUNCTION admtf_Table_Features(a_SchemaName VARCHAR(256),a_TableName VARCHAR(256)) IS '   ,  '; --ROLLBACK TRANSACTION; COMMIT TRANSACTION; SELECt * FROM admtf_Table_Features('public'::VARCHAR(256),'Street'::VARCHAR(256)); SELECt * FROM admtf_Table_Features('public':: NAME,'Street'::NAME); 



Membuat Fungsi admtf_Table_Attributes


Komentar pada kode sumber fungsi dapat ditemukan di sini.
kode sumber fungsi
 BEGIN TRANSACTION; DROP FUNCTION IF EXISTS admtf_Table_Attributes (a_SchemaName NAME,a_TableName NAME); /********************************************************************************************************/ /*      */ /********************************************************************************************************/ CREATE OR REPLACE FUNCTION admtf_Table_Attributes (a_SchemaName NAME default 'public', /*     */ a_TableName NAME default NULL /*   */ ) RETURNS TABLE (r_AttributeNumber SMALLINT,r_AttributeName NAME,r_UserTypeName NAME,r_TypeName NAME,r_isNotNULL BOOLEAN, r_Description Text) AS $BODY$ DECLARE c_TableKind CONSTANT CHAR:='r'; v_Scale INTEGER; /*   */ --****************************************************************************************************** BEGIN RETURN QUERY SELECT attr.attnum AS r_AttributeNumber, attr.attname::NAME AS r_AttributeName, CASE WHEN COALESCE(typ.typbasetype,0)>0 THEN typ.typname::NAME ELSE ''::NAME END AS r_UserTypeName, FORMAT_TYPE(COALESCE(NULLIF(typ.typbasetype,0),typ.oid), COALESCE(NULLIF(typ.typtypmod,-1),attr.atttypmod))::NAME AS r_TypeName, attr.attnotnull AS r_isNotNULL, dsc.description AS r_Description FROM pg_attribute attr INNER JOIN pg_class tbl ON tbl.oid = attr.attrelid INNER JOIN pg_namespace nsp ON tbl.relnamespace=nsp.oid LEFT OUTER JOIN pg_type typ ON attr.atttypid=typ.oid LEFT OUTER JOIN pg_type btyp ON typ.typbasetype=btyp.oid LEFT OUTER JOIN pg_description dsc ON dsc.objoid=attr.attrelid AND dsc.objsubid=attr.attnum WHERE LOWER(nsp.nspname)=LOWER(a_SchemaName) AND LOWER(tbl.relname)=LOWER(a_TableName) AND tbl.relkind=c_TableKind AND attr.attnum>0 AND attr.atttypID>0 ORDER BY tbl.relname,attr.attnum; RETURN; END $BODY$ LANGUAGE plpgsql; COMMENT ON FUNCTION admtf_Table_Attributes(a_SchemaName NAME,a_TableName NAME) IS '   '; --ROLLBACK TRANSACTION; COMMIT TRANSACTION; BEGIN TRANSACTION; DROP FUNCTION IF EXISTS admtf_Table_Attributes (a_SchemaName VARCHAR(256),a_TableName VARCHAR(256)); /********************************************************************************************************/ /*      */ /********************************************************************************************************/ CREATE OR REPLACE FUNCTION admtf_Table_Attributes (a_SchemaName VARCHAR(256) default 'public', /*     */ a_TableName VARCHAR(256) default NULL /*   */ ) RETURNS TABLE (r_AttributeNumber SMALLINT,r_AttributeName VARCHAR(256),r_UserTypeName VARCHAR(256),r_TypeName VARCHAR(256),r_isNotNULL BOOLEAN, r_Description Text) AS $BODY$ DECLARE c_TableKind CONSTANT CHAR:='r'; v_Scale INTEGER; /*   */ --****************************************************************************************************** BEGIN RETURN QUERY SELECT ta.r_AttributeNumber::SMALLINT, ta.r_AttributeName::VARCHAR(256), ta.r_UserTypeName::VARCHAR(256), ta.r_TypeName::VARCHAR(256), ta.r_isNotNULL::BOOLEAN, ta.r_Description::TEXT FROM admtf_Table_Attributes(a_SchemaName::NAME,a_TableName::NAME) ta; RETURN; END $BODY$ LANGUAGE plpgsql; COMMENT ON FUNCTION admtf_Table_Attributes(a_SchemaName VARCHAR(256),a_TableName VARCHAR(256)) IS '   '; --ROLLBACK TRANSACTION; COMMIT TRANSACTION; SELECT * FROM admtf_Table_Attributes('public'::VARCHAR(256),'Street'::VARCHAR(256)); SELECT * FROM admtf_Table_Attributes('public'::NAME,'Street'::NAME); 


Membuat Fungsi admtf_Table_Attributes Menggunakan Regclass Alias


Komentar pada kode sumber fungsi dapat ditemukan di sini.
kode sumber fungsi
 BEGIN TRANSACTION; DROP FUNCTION IF EXISTS admtf_Table_Attributes (a_SchemaName NAME,a_TableName NAME); /********************************************************************************************************/ /*      */ /********************************************************************************************************/ CREATE OR REPLACE FUNCTION admtf_Table_Attributes (a_SchemaName NAME default 'public', /*     */ a_TableName NAME default NULL /*   */ ) RETURNS TABLE (r_AttributeNumber SMALLINT,r_AttributeName NAME,r_UserTypeName NAME,r_TypeName NAME,r_isNotNULL BOOLEAN, r_Description Text) AS $BODY$ DECLARE c_TableKind CONSTANT CHAR:='r'; v_Scale INTEGER; /*   */ --****************************************************************************************************** BEGIN RETURN QUERY SELECT attr.attnum AS r_AttributeNumber, attr.attname::NAME AS r_AttributeName, CASE WHEN COALESCE(typ.typbasetype,0)>0 THEN typ.typname::NAME ELSE ''::NAME END AS r_UserTypeName, FORMAT_TYPE(COALESCE(NULLIF(typ.typbasetype,0),typ.oid), COALESCE(NULLIF(typ.typtypmod,-1),attr.atttypmod))::NAME AS r_TypeName, attr.attnotnull AS r_isNotNULL, dsc.description AS r_Description FROM pg_attribute attr INNER JOIN pg_type typ ON attr.atttypid=typ.oid LEFT OUTER JOIN pg_type btyp ON typ.typbasetype=btyp.oid LEFT OUTER JOIN pg_description dsc ON dsc.objoid=attr.attrelid AND dsc.objsubid=attr.attnum WHERE attr.attrelid=(LOWER(a_SchemaName)||'.'|| LOWER(a_TableName))::regclass AND attr.attnum>0 AND attr.atttypID>0 ORDER BY attr.attnum; RETURN; END $BODY$ LANGUAGE plpgsql; COMMENT ON FUNCTION admtf_Table_Attributes(a_SchemaName NAME,a_TableName NAME) IS '   '; --ROLLBACK TRANSACTION; COMMIT TRANSACTION; BEGIN TRANSACTION; DROP FUNCTION IF EXISTS admtf_Table_Attributes (a_SchemaName VARCHAR(256),a_TableName VARCHAR(256)); /********************************************************************************************************/ /*      */ /********************************************************************************************************/ CREATE OR REPLACE FUNCTION admtf_Table_Attributes (a_SchemaName VARCHAR(256) default 'public', /*     */ a_TableName VARCHAR(256) default NULL /*   */ ) RETURNS TABLE (r_AttributeNumber SMALLINT,r_AttributeName VARCHAR(256),r_UserTypeName VARCHAR(256),r_TypeName VARCHAR(256),r_isNotNULL BOOLEAN, r_Description Text) AS $BODY$ DECLARE c_TableKind CONSTANT CHAR:='r'; v_Scale INTEGER; /*   */ --****************************************************************************************************** BEGIN RETURN QUERY SELECT ta.r_AttributeNumber::SMALLINT, ta.r_AttributeName::VARCHAR(256), ta.r_UserTypeName::VARCHAR(256), ta.r_TypeName::VARCHAR(256), ta.r_isNotNULL::BOOLEAN, ta.r_Description::TEXT FROM admtf_Table_Attributes(a_SchemaName::NAME,a_TableName::NAME) ta; RETURN; END $BODY$ LANGUAGE plpgsql; COMMENT ON FUNCTION admtf_Table_Attributes(a_SchemaName VARCHAR(256),a_TableName VARCHAR(256)) IS '   '; --ROLLBACK TRANSACTION; COMMIT TRANSACTION; SELECT * FROM admtf_Table_Attributes('public'::VARCHAR(256),'Street'::VARCHAR(256)); SELECT * FROM admtf_Table_Attributes('public'::NAME,'Street'::NAME); 



LAMPIRAN 2. Bahan tambahan


Skema basis data bantu





  • NEGARA - Klasifikasi negara di dunia - OKSM (Semua-Rusia klasifikasi negara di dunia);
  • HOUSEADDR - Daftar nomor rumah di jalan-jalan pemukiman;
  • LCLTYTYPE - Direktori jenis permukiman;
  • LOKALITAS - Daftar pemukiman;
  • STREET β€” ;
  • STREETTYPE β€” ;
  • TERRITORY β€” (, , , ..);
  • TERRITORYTYPE β€” .



Street ()


.
1. Street ().

KategoriTidak.JudulKomentarjenisJenis dasar? bukan NULL
tbl0jalanDaftar jalan di pemukiman
att1kode sandiKode negarakode sandismallintt
att2localityidID komunitaslocalityidbilangan bulatt
att3streetidID jalan desastreetidsmallintt
att4streettypeacrmAkronim Jalanstreettypeacrmkarakter (8)f
att5nama jalanNama jalanstreettypeacrmvarchar (150)t
pk0xpkstreetKunci utama meja jalan
pkatt1kode sandiKode negarakode sandismallintt
pkatt2localityidID komunitaslocalityidbilangan bulatt
pkatt3streetidID jalan desastreetidsmallintt
fk011fk_street_localityMeja kunci asing
fk01att1kode sandiKode negarakode sandismallintt
fk01att2localityidID komunitaslocalityidbilangan bulatt
fk01rtbl0locality
fk01ratt1wcrccodewcrccodesmallintt
fk01ratt2localityidlocalityidintegert
fk022fk_street_streettype
fk02att1streettypeacrmstreettypeacrmcharacter(8)f
fk02rtbl0streettype
fk02ratt1streettypeacrmstreettypeacrmcharacter(8)t
idx011xie1street
idx01att1wcrccodewcrccodesmallintt
idx01att2localityidlocalityidintegert
idx01att3streettypeacrmstreettypeacrmcharacter(8)f
idx01att4streetnamevarchar(150)t
idx022xie2street
idx02att1wcrccodewcrccodesmallint
idx02att2localityidlocalityidintegert
idx02att3streetnamevarchar(150)t
idx033xie3street
idx03att1streetnamevarchar(150)t
idx044xpkstreet( ) street
idx04att1wcrccodewcrccodesmallintt
idx04att2localityidlocalityidintegert
idx04att3streetidstreetidsmallintt



Fungsi untuk mendokumentasikan database PostgreSQL. ;
Fungsi untuk mendokumentasikan database PostgreSQL. Bagian tiga .
Fungsi untuk mendokumentasikan database PostgreSQL. Akhir (bagian empat) .

Source: https://habr.com/ru/post/id415575/


All Articles