PostgreSQL'de belirli bir şemanın veritabanında saklanan tüm işlevlerin bir listesini nasıl alabilirim?


135

Bir PostgreSQL veritabanına bağlanmak ve belirli bir şema için tüm işlevleri bulmak istiyorum.

Benim düşüncem, pg_catalog veya information_schema için bazı sorgu yapmak ve tüm işlevlerin bir listesini almak oldu, ama adları ve parametreleri nerede saklandığını anlayamıyordu oldu. Bana işlev adını ve parametre türlerini (ve hangi sırayla alır) verecek bir sorgu arıyorum.

Bunu yapmanın bir yolu var mı?

Yanıtlar:


191
\df <schema>.*

in psqlgerekli bilgileri verir.

Kullanılan sorguyu görmek için dahili bir veritabanına bağlanıp psqlfazladan bir " -E" (veya " --echo-hidden") seçeneği sağlayın ve yukarıdaki komutu yürütün.


1
Bu sorgunun ne olduğunu yapıştırabilir misiniz?
Rudd Zwolinski

3
N.nspname öğesini "Şema" olarak, p.proname "Ad" olarak, pg_catalog.pg_get_function_result (p.oid) "Sonuç veri türü" olarak seçin, pg_catalog.pg_get_function_arguments (p.oid) "Bağımsız değişken veri türleri" olarak, CASE WHEN p .proisagg SONRA 'agg' NE ZAMAN p.proiswindow SONRA 'penceresi' NE ZAMAN p.prorettype = 'pg_catalog.trigger' :: pg_catalog.regtype SONRA 'ELSE' normal 'SONUNU "Tür" olarak tetikler pg_catalog.pg_proc p LEFT JOIN .pg_namespace n ON n.oid = p.pronamespace NEREDE n.nspname ~ '^ (genel) $' ORDER BY 1, 2, 4; Yukarıda oluşturulan sorgu (\ set ECHO_HIDDEN 'açık' öğesinden).
Simon D

90

Biraz arama yaptıktan sonra information_schema.routinesmasa ve information_schema.parametersmasaları bulabildim . Bunları kullanarak, bu amaç için bir sorgu yapılabilir. Parametresiz işlevleri almak için JOIN yerine LEFT JOIN gereklidir.

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;

2
Siz de oidvectortypesgerçekten faydalı bulacaksınız . Yeni yanıtı görün: stackoverflow.com/a/24034604/398670
Craig Ringer

Yukarıdaki kod tüm işlevleri göstermeyecektir, giriş parametreleri olmayan işlevleri de göstermek için JOIN yerine bir SOL JOIN'e ihtiyacınız vardır.
David

35

Eğer ilgilenen varsa burada psqlpostgres 9.1 hangi sorgu tarafından yürütülür olduğunu :

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;

Bayrakla çalışarak psqlters eğik çizgi komutu için çalışanı elde edebilirsiniz .psql-E


Cevabınız geldi ve soruyu Postgres 11.5'te denedi. Diyor ki:ERROR: column p.proisagg does not exist
Christiaan Westerbeek

Bunun için teşekkürler; en çok oylanan iki cevap benim fonksiyonumu göstermedi!
machineghost

29

Kullanışlı bir işlev var, oidvectortypesbu çok daha kolay.

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';

İşaret ettikleri için Postgres Online'da Leo Hsu ve Regina Obe'ye teşekkür ederiz oidvectortypes. Daha önce benzer işlevler yazdım, ancak bu işlevin ihtiyaçtan kurtulduğu karmaşık iç içe ifadeler kullandım.

İlgili cevaba bakınız .


(2016 yılında düzenleyin)

Tipik rapor seçeneklerini özetleme:

-- 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';

DİKKAT : Kullanım p.proname||'_'||p.oid AS specific_name benzersiz adlar elde etmek, ya da birlikte JOIN için information_schematablolar - bakınız routinesve parametersRuddZwolinski cevabı @ de.


İşlevin OID (bkz  pg_catalog.pg_proc) ve işlevin specific_name (bkz  information_schema.routines) işlevlerine ana referans seçeneklerdir. Aşağıda, raporlama ve diğer bağlamlarda bazı yararlı işlevler bulunmaktadır.

--- --- --- --- ---
--- 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;

Bu pronameaddır, ancak OID'yi nasıl alacağınız, ör. kullanmak pg_catalog.pg_get_function_result(oid))?
Peter Krauss

1
@PeterKrauss oidsütunu pg_proc. Gizli bir sütun.
Craig Ringer

1
Ayrıca bkz stackoverflow.com/a/25388031/161040 uzatma bağımlı işlevleri nasıl hariç tutulacağına ilişkin (PostGIS gelen örn fonksiyonlar).
Simon D

20

Tüm işlevleri gösterecek bir görünüm oluşturmak için SQL sorgusunun altında çalıştırın:

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

10

LIKE Postgresql 9.4'te kamu şeması ile Örnek ile adı filtrelemek için ilk sözcükler üzerinde komün takma adı ile işlevler adlı iyi bir fikir , onun şemasını değiştirdiğinizden emin olun

SELECT routine_name 
FROM information_schema.routines 
WHERE routine_type='FUNCTION' 
  AND specific_schema='public'
  AND routine_name LIKE 'aliasmyfunctions%';

4

Misal:

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)

5
Bu Milen'in cevabından nasıl farklı?
a_horse_with_no_name

3
Bu bir sorgu değil, psqlPostgres istemci arayüzünün bir komutu . Bu sadece çalışır psqlve teknik olarak bir SQL sorgusu değildir.
GregT

3

Function_schema ve function_name listesini al ...


> 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;

2

Bu işlev, geçerli veritabanındaki tüm kullanıcı tanımlı yordamları döndürür.

SELECT pg_get_functiondef(p.oid) FROM pg_proc p
INNER JOIN pg_namespace ns ON p.pronamespace = ns.oid
WHERE ns.nspname = 'public';
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.