PostgreSQLの特定のスキーマのデータベースに格納されているすべての関数のリストを取得するにはどうすればよいですか?


135

PostgreSQLデータベースに接続して、特定のスキーマのすべての関数を見つけられるようにしたいと考えています。

私の考えでは、pg_catalogまたはinformation_schemaにクエリを実行してすべての関数のリストを取得することはできましたが、名前とパラメーターがどこに保存されているのかわかりません。関数名と関数のパラメータタイプ(および関数の順序)を取得するクエリを探しています。

これを行う方法はありますか?

回答:


191
\df <schema>.*

中には、psql必要な情報を提供します。

内部で使用されているクエリを確認するにはpsql、追加の " -E"(または " --echo-hidden")オプションを使用してデータベースに接続し、上記のコマンドを実行します。


1
そのクエリを貼り付けてもらえますか?
Rudd Zwolinski、2009

3
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 n.nspname〜 '^(public)$' ORDER BY 1、2、4; 上記は生成されたクエリです(\ set ECHO_HIDDEN 'on'から)。
Simon D

90

少し調べたところ、information_schema.routines表と表を見つけることができましたinformation_schema.parameters。これらを使用して、この目的でクエリを作成できます。JOINではなくLEFT 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

上記のコードはすべての関数を表示するわけではありません。入力パラメーターのない関数も表示するには、JOINではなくLEFT 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;

フラグpsqlpsql付けて実行すると、バックスラッシュコマンドの実行内容を取得できます-E


ちょうどあなたの答えに出会い、Postgres 11.5でクエリを試してみました。それは言う:ERROR: column p.proisagg does not exist
クリスティアン・ウェスターベーク

これをありがとう; 上位投票された2つの回答は私の機能を示していません!
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のテーブル-を参照routinesしてparametersRuddZwolinskiの答え@で。


関数の 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))ますか?
Peter Krauss

1
@PeterKraussのoidpg_proc。これは非表示の列です。
クレイグリンガー2016年

1
拡張機能に依存する関数(例:PostGISの関数)を除外する方法については、stackoverflow.com / a / 25388031/161040も参照してください。
Simon 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の例でパブリックスキーマを使用して名前をフィルタリングするための最初の単語に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
それはミレンの答えとどう違うのですか?
a_horse_with_no_name 2013

3
これはクエリではなく、psqlPostgresクライアントインターフェースのコマンドです。これは機能するだけでpsql、厳密にはSQLクエリではありません。
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';
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.