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

Rud*_*ski 117 postgresql function

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

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

有没有办法做到这一点?

Mil*_*dev 168

\df <schema>.*
Run Code Online (Sandbox Code Playgroud)

psql给出了必要的信息.

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

  • 这种方法的一个问题是,查询是针对特定版本的 Postgres 生成的,而对于其他版本可能会失败。例如,在 Postgres 11 上,您会收到“错误:列 p.proisagg 不存在”。 (3认同)
  • 你能粘贴那个查询是什么吗? (2认同)
  • 为简单起见,这应该是公认的答案. (2认同)
  • 选择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')。 (2认同)

Rud*_*ski 73

经过一番搜索,我找到了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;
Run Code Online (Sandbox Code Playgroud)

  • 您会发现`oidvectortypes`也非常有用.请参阅新答案:http://stackoverflow.com/a/24034604/398670 (2认同)

jb.*_*jb. 32

如果有人对此感兴趣,那么psqlpostgres 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;
Run Code Online (Sandbox Code Playgroud)

你能得到psql一个反斜杠命令运行运行psql-E标志.

  • @ChristiaanWesterbeek,这适用于 &lt; 11,对于 11+ 使用 `p.prokind = 'a'` 作为 agg,使用 `p.prokind = 'w' 作为 window (2认同)

Cra*_*ger 25

有一个方便的功能,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';
Run Code Online (Sandbox Code Playgroud)

感谢狮子座Hsu和里贾纳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';
Run Code Online (Sandbox Code Playgroud)

注意:使用p.proname||'_'||p.oid AS specific_name 来获得唯一的名称,或加入information_schema表-看routinesparameters在@ 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;
Run Code Online (Sandbox Code Playgroud)


lau*_*rch 18

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

CREATE OR REPLACE VIEW show_functions AS
    SELECT routine_name FROM information_schema.routines 
        WHERE routine_type='FUNCTION' AND specific_schema='public';
Run Code Online (Sandbox Code Playgroud)


小智 12

获取 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;
Run Code Online (Sandbox Code Playgroud)


Alb*_*dez 7

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

SELECT routine_name FROM information_schema.routines WHERE routine_type='FUNCTION' AND specific_schema='public' AND routine_name LIKE 'aliasmyfunctions%';
Run Code Online (Sandbox Code Playgroud)


小智 5

例子:

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)
Run Code Online (Sandbox Code Playgroud)

  • 这与迈伦的答案有何不同? (6认同)
  • 这不是一个查询,它是 `psql` Postgres 客户端接口的命令。这仅适用于“psql”,并且从技术上讲不是 SQL 查询。 (3认同)