如何获得PostgreSQL中特定模式的数据库中存储的所有功能的列表?


135

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

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

有没有办法做到这一点?

Answers:


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)作为“参数数据类型”,当p时.proisagg当p.proiswindow时'agg'然后p.prorettype ='pg_catalog.trigger':: pg_catalog.regtype THEN'trigger'ELSE'normal'END时为“ Type”,则来自pg_catalog.pg_proc p左联接pg_catalog .pg_namespace n ON n.oid = p.pronamespace WHERE n.nspname〜'^(public)$'ORDER BY 1,2,4; 上面是生成的查询(来自\ set ECHO_HIDDEN'on')。
西蒙D

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
Craig Ringer 2014年

上面的代码不会显示所有功能,您需要使用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
Christiaan Westerbeek,

谢谢你 这两个最受好评的答案没有显示我的功能!
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';

感谢Postgres Online上的Leo Hsu和Regina Obe指出了这一点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表联接—请参见@RuddZwolinski的routines以及parameters在其答案中。


函数的 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中的功能)。
西蒙D

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

LIKE 在PostgreSQL 9.4中用带有公共模式的Example 的名字在filtre的第一个单词上用commun别名命名函数是一个好主意,一定要用他的方案替换

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
这与Milen的答案有何不同?
a_horse_with_no_name

3
这不是查询,而是psqlPostgres客户端界面的命令。这仅在psqlSQL查询中起作用,从技术上讲不是。
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';
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.