【问题标题】:How can I get a list of all functions stored in the database of a particular schema in PostgreSQL?如何获取存储在 PostgreSQL 中特定模式的数据库中的所有函数的列表?
【发布时间】:2010-11-23 18:05:46
【问题描述】:

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

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

有没有办法做到这一点?

【问题讨论】:

    标签: postgresql function


    【解决方案1】:

    获取 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】:

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

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

      【讨论】:

        【解决方案3】:

        此函数返回当前数据库中所有用户定义的例程。

        SELECT pg_get_functiondef(p.oid) FROM pg_proc p
        INNER JOIN pg_namespace ns ON p.pronamespace = ns.oid
        WHERE ns.nspname = 'public';
        

        【讨论】:

          【解决方案4】:

          经过一番搜索,我找到了 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;
          

          【讨论】:

          • 您会发现oidvectortypes 也非常有用。查看新答案:stackoverflow.com/a/24034604/398670
          • 上面的代码不会显示所有函数,你需要一个 LEFT JOIN 而不是 JOIN 来显示没有输入参数的函数。
          【解决方案5】:
          \df <schema>.*
          

          psql 中提供了必要的信息。

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

          【讨论】:

          • 你能粘贴那个查询是什么吗?
          • 选择 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 '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 n.nspname ~ '^(public)$' ORDER BY 1, 2, 4;以上是生成的查询(来自\set ECHO_HIDDEN 'on')。
          • 这种方法的一个问题是查询是针对特定版本的 Postgres 生成的,而对于其他版本可能会失败。例如,在 Postgres 11 上,你会得到 ERROR: column p.proisagg does not exist
          • 感谢--echo-hidden 的提及,这当然非常有帮助
          【解决方案6】:

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

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

          【讨论】:

            【解决方案7】:

            有一个方便的功能,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';
            

            感谢Leo Hsu and Regina Obe at Postgres Online 指出oidvectortypes。我以前写过类似的函数,但使用了复杂的嵌套表达式,这个函数不需要。

            See related answer.


            (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 的回答中的 routinesparameters


            函数的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))中使用?
            • @PeterKrauss pg_procoid 列。这是一个隐藏的列。
            • 另请参阅stackoverflow.com/a/25388031/161040,了解如何排除依赖于扩展的函数(例如来自 PostGIS 的函数)。
            【解决方案8】:

            如果有人对此感兴趣,请查看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;
            

            您可以通过运行带有-E 标志的psql 来获得psql 为反斜杠命令运行的内容。

            【讨论】:

            • 刚刚遇到您的答案并尝试在 Postgres 11.5 上进行查询。它说:ERROR: column p.proisagg does not exist
            • 谢谢你;投票最多的两个答案没有显示我的功能!
            【解决方案9】:

            例子:

            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)
            

            【讨论】:

            • 这与 Milen 的回答有何不同?
            • 这不是查询,它是psql Postgres 客户端接口的命令。这仅适用于psql,并且在技术上不是 SQL 查询。
            猜你喜欢
            • 2015-08-17
            • 2020-12-27
            • 1970-01-01
            • 2011-04-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多