Bagaimana saya bisa mendapatkan daftar semua fungsi yang tersimpan dalam database skema tertentu di PostgreSQL?

135

Saya ingin dapat terhubung ke database PostgreSQL dan menemukan semua fungsi untuk skema tertentu.

Pikir saya adalah bahwa saya bisa membuat beberapa permintaan ke pg_catalog atau information_schema dan mendapatkan daftar semua fungsi, tapi saya tidak tahu di mana nama dan parameter disimpan. Saya mencari kueri yang akan memberi saya nama fungsi dan tipe parameter yang diperlukan (dan urutan apa yang diperlukan).

Apakah ada cara untuk melakukan ini?

Rudd Zwolinski
sumber

Jawaban:

191
\df <schema>.*

di psqlmemberikan informasi yang diperlukan.

Untuk melihat kueri yang digunakan terhubung secara internal ke database dengan psqldan menyediakan opsi " -E" (atau " --echo-hidden") tambahan dan kemudian jalankan perintah di atas.

Milen A. Radev
sumber
1
Bisakah Anda menempelkan apa itu query?
Rudd Zwolinski
3
SELECT n.nspname sebagai "Skema", p.proname sebagai "Nama", pg_catalog.pg_get_function_result (p.oid) sebagai "tipe data hasil", pg_catalog.pg_get_function_arguments (p.oid) sebagai "tipe data argumen", KASUS SAAT .proisagg LALU 'agg' KETIKA p.proiswindow LALU 'jendela' KETIKA p.prorettype = 'pg_catalog.trigger' :: pg_catalog.regtype KEMUDIAN 'pemicu' ELSE 'normal' AKHIR sebagai "Jenis" DARI pg_catalog.pg_proc p LEFT JOIN pg_catalog .pg_namespace n ON n.oid = p.pronamespace WHERE n.nspname ~ '^ (publik) $' ORDER OLEH 1, 2, 4; Di atas adalah kueri yang dihasilkan (dari \ set ECHO_HIDDEN 'on').
Simon D
90

Setelah beberapa pencarian, saya dapat menemukan information_schema.routinestabel dan information_schema.parameterstabel. Dengan menggunakan itu, orang dapat membuat kueri untuk tujuan ini. LEFT JOIN, alih-alih BERGABUNG, diperlukan untuk mengambil fungsi tanpa parameter.

SELECT routines.routine_name, parameters.data_type, parameters.ordinal_position
FROM information_schema.routines
    LEFT JOIN information_schema.parameters ON routines.specific_name=parameters.specific_name
WHERE routines.specific_schema='my_specified_schema_name'
ORDER BY routines.routine_name, parameters.ordinal_position;
Rudd Zwolinski
sumber
2
Anda akan menemukan oidvectortypessangat berguna juga. Lihat jawaban baru: stackoverflow.com/a/24034604/398670
Craig Ringer
Kode di atas tidak akan menampilkan semua fungsi, Anda perlu BERGABUNG LEFT alih-alih BERGABUNG untuk juga menampilkan fungsi tanpa parameter input.
David
35

Jika ada yang tertarik di sini adalah query apa yang dijalankan oleh psqlpada postgres 9.1:

SELECT n.nspname as "Schema",
  p.proname as "Name",
  pg_catalog.pg_get_function_result(p.oid) as "Result data type",
  pg_catalog.pg_get_function_arguments(p.oid) as "Argument data types",
 CASE
  WHEN p.proisagg THEN 'agg'
  WHEN p.proiswindow THEN 'window'
  WHEN p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype THEN 'trigger'
  ELSE 'normal'
 END as "Type"
FROM pg_catalog.pg_proc p
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
WHERE pg_catalog.pg_function_is_visible(p.oid)
      AND n.nspname <> 'pg_catalog'
      AND n.nspname <> 'information_schema'
ORDER BY 1, 2, 4;

Anda bisa mendapatkan apa yang psqldijalankan untuk perintah backslash dengan menjalankan psqldengan -Eflag.

jb.
sumber
Baru saja menemukan jawaban Anda dan mencoba kueri di Postgres 11.5. Dikatakan:ERROR: column p.proisagg does not exist
Christiaan Westerbeek
Terima kasih untuk ini; dua jawaban terpilih tidak menunjukkan fungsi saya!
machineghost
29

Ada fungsi praktis oidvectortypes, yang membuat ini jauh lebih mudah.

SELECT format('%I.%I(%s)', ns.nspname, p.proname, oidvectortypes(p.proargtypes)) 
FROM pg_proc p INNER JOIN pg_namespace ns ON (p.pronamespace = ns.oid)
WHERE ns.nspname = 'my_namespace';

Penghargaan untuk Leo Hsu dan Regina Obe di Postgres Online untuk menunjukkan oidvectortypes. Saya menulis fungsi yang sama sebelumnya, tetapi menggunakan ekspresi bersarang kompleks yang fungsi ini menghilangkan kebutuhan.

Lihat jawaban terkait .


(sunting pada 2016)

Meringkas opsi laporan yang khas:

-- Compact:
SELECT format('%I.%I(%s)', ns.nspname, p.proname, oidvectortypes(p.proargtypes))

-- With result data type: 
SELECT format(
       '%I.%I(%s)=%s', 
       ns.nspname, p.proname, oidvectortypes(p.proargtypes),
       pg_get_function_result(p.oid)
)

-- With complete argument description: 
SELECT format('%I.%I(%s)', ns.nspname, p.proname, pg_get_function_arguments(p.oid))

-- ... and mixing it.

-- All with the same FROM clause:
FROM pg_proc p INNER JOIN pg_namespace ns ON (p.pronamespace = ns.oid)
WHERE ns.nspname = 'my_namespace';

PEMBERITAHUAN : gunakan p.proname||'_'||p.oid AS specific_name untuk mendapatkan nama unik, atau BERGABUNG dengan information_schematabel - lihat routinesdan parameterspada jawaban @ RuddZwolinski.


OID fungsi (lihat  pg_catalog.pg_proc) dan nama_ fungsi spesifik (lihat  information_schema.routines) adalah opsi referensi utama untuk fungsi. Di bawah ini, beberapa fungsi yang berguna dalam pelaporan dan konteks lainnya.

--- --- --- --- ---
--- Useful overloads: 

CREATE FUNCTION oidvectortypes(p_oid int) RETURNS text AS $$
    SELECT oidvectortypes(proargtypes) FROM pg_proc WHERE oid=$1;
$$ LANGUAGE SQL IMMUTABLE;

CREATE FUNCTION oidvectortypes(p_specific_name text) RETURNS text AS $$
    -- Extract OID from specific_name and use it in oidvectortypes(oid).
    SELECT oidvectortypes(proargtypes) 
    FROM pg_proc WHERE oid=regexp_replace($1, '^.+?([^_]+)$', '\1')::int;
$$ LANGUAGE SQL IMMUTABLE;

CREATE FUNCTION pg_get_function_arguments(p_specific_name text) RETURNS text AS $$
    -- Extract OID from specific_name and use it in pg_get_function_arguments.
    SELECT pg_get_function_arguments(regexp_replace($1, '^.+?([^_]+)$', '\1')::int)
$$ LANGUAGE SQL IMMUTABLE;

--- --- --- --- ---
--- User customization: 

CREATE FUNCTION pg_get_function_arguments2(p_specific_name text) RETURNS text AS $$
    -- Example of "special layout" version.
    SELECT trim(array_agg( op||'-'||dt )::text,'{}') 
    FROM (
        SELECT data_type::text as dt, ordinal_position as op
        FROM information_schema.parameters 
        WHERE specific_name = p_specific_name 
        ORDER BY ordinal_position
    ) t
$$ LANGUAGE SQL IMMUTABLE;
Craig Ringer
sumber
Itu pronameadalah nama, tetapi bagaimana mendapatkan OID untuk, mis. gunakan di pg_catalog.pg_get_function_result(oid))?
Peter Krauss
1
@PeterKrauss oidKolom pg_proc. Itu kolom tersembunyi.
Craig Ringer
1
Lihat juga stackoverflow.com/a/25388031/161040 untuk mengecualikan fungsi yang bergantung pada ekstensi (mis. Fungsi dari PostGIS).
Simon D
20

Jalankan di bawah query SQL untuk membuat tampilan yang akan menampilkan semua fungsi:

CREATE OR REPLACE VIEW show_functions AS
    SELECT routine_name FROM information_schema.routines 
        WHERE routine_type='FUNCTION' AND specific_schema='public';
Laudarch
sumber
10

Adalah ide yang baik bernama fungsi dengan alias komun pada kata-kata pertama untuk filtre nama dengan LIKE Contoh dengan skema publik di Postgresql 9.4, pastikan untuk mengganti dengan rencananya

SELECT routine_name 
FROM information_schema.routines 
WHERE routine_type='FUNCTION' 
  AND specific_schema='public'
  AND routine_name LIKE 'aliasmyfunctions%';
Alberto Morales Fernández
sumber
4

Contoh:

perfdb-# \df information_schema.*;

List of functions
        Schema      |        Name        | Result data type | Argument data types |  Type  
 information_schema | _pg_char_max_length   | integer | typid oid, typmod integer | normal
 information_schema | _pg_char_octet_length | integer | typid oid, typmod integer | normal
 information_schema | _pg_datetime_precision| integer | typid oid, typmod integer | normal
 .....
 information_schema | _pg_numeric_scale     | integer | typid oid, typmod integer | normal
 information_schema | _pg_truetypid         | oid     | pg_attribute, pg_type     | normal
 information_schema | _pg_truetypmod        | integer | pg_attribute, pg_type     | normal
(11 rows)
Ritu
sumber
5
Bagaimana itu berbeda dengan jawaban Milen?
a_horse_with_no_name
3
Ini bukan query, ini perintah dari psqlantarmuka klien Postgres. Ini hanya akan berfungsi psqldan secara teknis bukan query SQL.
GregT
3

Dapatkan Daftar function_schema dan function_name ...


> select n.nspname as function_schema,
> 
> p.proname as function_name
> 
> from pg_proc p
> 
> left join pg_namespace n on p.pronamespace = n.oid
> 
> where n.nspname not in ('pg_catalog', 'information_schema')
> 
> order by function_schema, function_name;
gila
sumber
2

Fungsi ini mengembalikan semua rutin yang ditentukan pengguna dalam database saat ini.

SELECT pg_get_functiondef(p.oid) FROM pg_proc p
INNER JOIN pg_namespace ns ON p.pronamespace = ns.oid
WHERE ns.nspname = 'public';
Alex
sumber