如何在PostgreSQL中获取存储在特定模式数据库中的所有函数的列表?

How can I get a list of all functions stored in the database of a particular schema in PostgreSQL?

我希望能够连接到PostgreSQL数据库并找到特定模式的所有函数。

我的想法是我可以对pg_catalog或information_schema进行一些查询并得到所有函数的列表,但我无法弄清楚名称和参数的存储位置。 我正在寻找一个查询,它将为我提供函数名称和它所采用的参数类型(以及它们采用的顺序)。

有没有办法做到这一点?


1
\df <schema>.*

psql中提供必要的信息。

要查看内部使用的查询,请使用psql连接到数据库并提供额外的"-E"(或"--echo-hidden")选项,然后执行上述命令。


经过一番搜索,我找到了information_schema.routines表和information_schema.parameters表。使用这些,可以为此目的构建查询。 LEFT JOIN而不是JOIN是检索没有参数的函数所必需的。

1
2
3
4
5
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;


如果有人对此感兴趣,那么psql在postgres 9.1上执行的查询:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;

通过使用-E标志运行psql,可以获得psql为反斜杠命令运行的内容。


有一个方便的功能,oidvectortypes,这使得这更容易。

1
2
3
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的Leo Hsu和Regina Obe指出oidvectortypes。我之前编写过类似的函数,但是使用了复杂的嵌套表达式,这个函数摆脱了它的需要。

见相关答案。

(2016年编辑)

总结典型的报告选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-- 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表格加入&mdash;在@ RuddZwolinski的回答中看到routinesparameters

函数的OID(参见&nbsp; pg_catalog.pg_proc)和函数的specific_name(参见&nbsp; information_schema.routines)是函数的主要参考选项。下面是报告和其他上下文中的一些有用功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
--- --- --- --- ---
--- 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;


在SQL查询下运行以创建一个将显示所有函数的视图:

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

在第一个单词上命名带有通用别名的函数是一个好主意,用LIKE表示名称
在Postgresql 9.4中使用公共模式的示例,请务必替换为他的方案

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


例:

1
2
3
4
5
6
7
8
9
10
11
12
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)