Як я можу отримати список усіх функцій, що зберігаються в базі даних певної схеми в PostgreSQL?


135

Я хочу мати можливість підключитися до бази даних PostgreSQL і знайти всі функції для певної схеми.

Думав, що я можу зробити запит до pg_catalog або information_schema і отримати список усіх функцій, але я не можу зрозуміти, де зберігаються імена та параметри. Я шукаю запит, який дасть мені ім'я функції та типи параметрів, які вона потребує (і в якому порядку їх приймає).

Чи є спосіб це зробити?

Відповіді:


191
\df <schema>.*

в psqlдає необхідну інформацію.

Щоб побачити запит, який використовується внутрішньо, підключіться до бази даних psqlта надайте додатковий варіант " -E" (або " --echo-hidden") та виконайте вищевказану команду.


1
Не могли б ви вставити, що це за запит?
— Rudd Zwolinski

3
Виберіть n.nspname як "Схема", p.proname - як "Ім'я", pg_catalog.pg_get_function_result (p.oid) як "Тип даних результату", pg_catalog.pg_get_function_arguments (p.oid) як "Типи даних аргументу", CASE WHEN p .proisagg ТАГО 'agg' КОЛИ p.proiswindow ТАМО 'вікно' КОЛИ p.prorettype = 'pg_catalog.trigger' :: pg_catalog.regtype ТАГО 'тригер' ELSE 'нормальний' END як "Тип" ВІД pg_catalog.pg_proc p НАЛІГЛЯ ПРИЄДНАЙТЕ pg_catalog .pg_pacepace n ON n.oid = p.pronamespace ДЕ n.nspname ~ '^ (public) $' ЗАМОВИТИ 1, 2, 4; Вище формується запит (від \ set ECHO_HIDDEN 'on').
— Саймон Д

90

Після деяких пошуків я зміг знайти information_schema.routinesтаблицю та information_schema.parametersтаблиці. Використовуючи ці, можна побудувати запит для цієї мети. LEFT JOIN замість JOIN необхідний для отримання функцій без параметрів.

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
Ви oidvectortypesтеж знайдете корисне. Дивіться нову відповідь: stackoverflow.com/a/24034604/398670
— Крейг Рінгер

У наведеному вище коді не відображатимуться всі функції. Вам потрібно ЛІВНЕ СПОЛУЧЕННЯ замість ПРИЄДНАТИ, щоб також відображалися функції без вхідних параметрів.
— Девід

35

Якщо когось цікавить тут, то який запит виконується psqlна 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;

Ви можете отримати те , що psqlпрацює для зворотних косих команд, запустивши psqlз -Eпрапором.


Щойно натрапив на вашу відповідь і спробував запит на Postgres 11.5. Там написано:ERROR: column p.proisagg does not exist
— Крістіан Вестербек

Дякую за це; два голосові відповіді не показали моєї функції!
— machineghost

29

Є зручна функція oidvectortypes, яка значно спрощує це.

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

Кредит Лео Хсу і Регіна Obe в Postgres онлайн за вказівку oidvectortypes. Я раніше писав подібні функції, але використовував складні вкладені вирази, в яких ця функція позбавляється від потреби.

Дивіться відповідна відповідь .


(редагувати у 2016 році)

Узагальнення типових варіантів звіту:

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

УВАГА : використання p.proname||'_'||p.oid AS specific_name для отримання унікальних імен, або JOIN з information_schemaтаблицями - см routinesі parametersна @ відповідь RuddZwolinski в.


Функція по OID (див  pg_catalog.pg_proc) і функція в SPECIFIC_NAME (див  information_schema.routines) є основними еталонними параметрами для функцій. Нижче наведено деякі корисні функції у звіті та інші контексти.

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

Це pronameім'я, але як отримати OID, наприклад, використання в pg_catalog.pg_get_function_result(oid))?
— Пітер Краус

1
@PeterKrauss oidСтовпець pg_proc. Це прихований стовпчик.
— Крейг Рінгер

1
Дивіться також stackoverflow.com/a/25388031/161040 про те, як виключити функції, що залежать від розширення (наприклад, функції PostGIS).
— Саймон Д

20

Запустіть нижче SQL-запиту, щоб створити подання, в якому будуть показані всі функції:

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

10

Хороша ідея назвала функції з комунікаційним псевдонімом на перших словах для filtre ім'я з LIKE Приклад з публічною схемою в Postgresql 9.4, обов'язково замініть його схемою

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

4

Приклад:

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
Як це відрізняється від відповіді Мілена?
— a_horse_with_no_name

3
Це не запит, це команда psqlклієнтського інтерфейсу Postgres. Це працюватиме лише в psqlтехнічному відношенні і не є SQL-запитом.
— GregT

3

Отримати список function_schema та 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;

2

Ця функція повертає всі визначені користувачем процедури у поточній базі даних.

SELECT pg_get_functiondef(p.oid) FROM pg_proc p
INNER JOIN pg_namespace ns ON p.pronamespace = ns.oid
WHERE ns.nspname = 'public';
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.