Как я могу получить список всех функций, хранящихся в базе данных конкретной схемы в PostgreSQL?

135

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

Я думал, что мог бы сделать какой-нибудь запрос к pg_catalog или information_schema и получить список всех функций, но я не могу понять, где хранятся имена и параметры. Я ищу запрос, который даст мне имя функции и типы параметров, которые она принимает (и в каком порядке она принимает их).

Есть ли способ сделать это?

Радд Зволински
источник

Ответы:

191
\df <schema>.*

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

Чтобы увидеть запрос, который используется внутри, подключитесь к базе данных psqlи предоставьте дополнительную опцию « -E» (или « --echo-hidden»), а затем выполните указанную выше команду.

Милен А. Радев
источник
1
Не могли бы вы вставить этот запрос?
Радд Зволински
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 THEN 'agg' WHEN p.proiswindow THEN 'window' WHEN p.prorettype = 'pg_catalog.trigger' :: pg_catalog.regtype THEN 'вызывать' ELSE 'normal' END как "Тип" ОТ pg_catalog.pg_proc p ВЕРНУТЬСЯ pg_catalog .pg_namespace n ON n.oid = p.pronamespace ГДЕ n.nspname ~ '^ (public) $' ORDER BY 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
Крейг Рингер
Приведенный выше код не покажет все функции. Вам нужно LEFT JOIN вместо JOIN, чтобы также показать функции без входных параметров.
Дэвид
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
Кристиан Вестербик
Спасибо за это; два ответа с наибольшим количеством голосов не показали мою функцию!
машина-
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';

Благодарим Лео Хсу и Реджину Обе из Postgres Online за указание 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) И специфическое_имя функции (см.  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';
laudarch
источник
10

Является ли хорошей идеей именовать функции с общим псевдонимом в первых словах для фильтра имя с 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';
Alex
источник