Как я могу получить список всех функций, хранящихся в базе данных конкретной схемы в PostgreSQL?
Я хочу иметь возможность подключиться к базе данных PostgreSQL и найти все функции для конкретной схемы.
Моя мысль заключалась в том, что я могу сделать некоторый запрос к pg_catalog или information_schema и получить список всех функций, но я не могу понять, где хранятся имена и параметры. Я ищу запрос, который даст мне имя функции и типы параметров, которые она принимает (и в каком порядке она принимает их).
Есть ли способ сделать это?
Ответы
Ответ 1
После некоторого поиска мне удалось найти таблицу 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
\df <schema>.*
в psql
дает необходимую информацию.
Чтобы увидеть запрос, который внутренне соединяется с базой данных с помощью psql
и предоставляет дополнительную опцию "-E
" (или "--echo-hidden
" ), а затем выполните приведенную выше команду.
Ответ 3
Если кто-то заинтересован, то какой запрос выполняется 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
.
Ответ 4
Там есть удобная функция 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
для получения уникальных имен или для СОХРАНЕНИЯ с помощью information_schema
tables — см. 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;
Ответ 5
Запустите ниже SQL-запрос, чтобы создать представление, которое покажет все функции:
CREATE OR REPLACE VIEW show_functions AS
SELECT routine_name FROM information_schema.routines
WHERE routine_type='FUNCTION' AND specific_schema='public';
Ответ 6
Является хорошей идеей, названной функциями с общим псевдонимом для первых слов для имени фильтра с помощью LIKE
Пример с общедоступной схемой в Postgresql 9.4, обязательно замените его схемой
SELECT routine_name FROM information_schema.routines WHERE routine_type='FUNCTION' AND specific_schema='public' AND routine_name LIKE 'aliasmyfunctions%';
Ответ 7
Пример:
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)