Làm cách nào tôi có thể nhận được danh sách tất cả các hàm được lưu trữ trong cơ sở dữ liệu của một lược đồ cụ thể trong PostgreQuery?


135

Tôi muốn có thể kết nối với cơ sở dữ liệu PostgreSQL và tìm tất cả các hàm cho một lược đồ cụ thể.

Tôi nghĩ rằng tôi có thể thực hiện một số truy vấn tới pg_catalog hoặc information_schema và nhận danh sách tất cả các hàm, nhưng tôi không thể tìm ra nơi lưu trữ tên và tham số. Tôi đang tìm kiếm một truy vấn sẽ cung cấp cho tôi tên hàm và các loại tham số cần có (và thứ tự nó sẽ đưa chúng vào).

Có cách nào để làm việc này không?

Câu trả lời:


191
\df <schema>.*

trong psqlcung cấp các thông tin cần thiết.

Để xem truy vấn được sử dụng bên trong kết nối với cơ sở dữ liệu psqlvà cung cấp tùy chọn " -E" (hoặc " --echo-hidden") bổ sung và sau đó thực hiện lệnh trên.


1
Bạn có thể dán vào truy vấn đó là gì?
Rudd Zwolinski

3
CHỌN n.nspname là "Schema", p.proname là "Name", pg_catalog.pg_get_feft_result (p.oid) là "Kiểu dữ liệu kết quả", pg_catalog.pg_get_feft_argument (p.oid) là "Kiểu dữ liệu" .proisagg THEN 'agg' KHI p.proiswindow THEN 'window' KHI p.prorettype = 'pg_catalog.trigger' :: pg_catalog.regtype THEN 'kích hoạt' ELSE 'bình thường' END là "Loại" TỪ pg_cat_ .pg_namespace n ON n.oid = p.pronamespace WHERE n.nspname ~ '^ (công khai) $' ĐẶT HÀNG THEO 1, 2, 4; Trên đây là truy vấn được tạo (từ \ set ECHO_HIDDEN 'on').
Simon D

90

Sau một số tìm kiếm, tôi đã có thể tìm thấy information_schema.routinesbảng và các information_schema.parametersbảng. Sử dụng chúng, người ta có thể xây dựng một truy vấn cho mục đích này. LEFT THAM GIA, thay vì THAM GIA, là cần thiết để lấy các hàm không có tham số.

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
Bạn sẽ thấy oidvectortypesthực sự hữu ích quá. Xem câu trả lời mới: stackoverflow.com/a/24034604/398670
Craig Ringer

Đoạn mã trên sẽ không hiển thị tất cả các chức năng, Bạn cần THAM GIA TRÁI thay vì THAM GIA để hiển thị các chức năng không có tham số đầu vào.
David

35

Nếu bất kỳ ai quan tâm ở đây thì truy vấn nào được thực hiện psqltrên 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;

Bạn có thể nhận được những gì psqlchạy cho lệnh dấu gạch chéo ngược bằng cách chạy psqlvới -Ecờ.


Chỉ cần xem qua câu trả lời của bạn và thử truy vấn trên Postgres 11.5. Nó nói:ERROR: column p.proisagg does not exist
Christiaan Westerbeek

Cảm ơn vì điều đó; hai câu trả lời được bình chọn hàng đầu đã không thể hiện chức năng của tôi!
máy

29

Có một chức năng tiện dụng oidvectortypes, làm cho việc này dễ dàng hơn nhiều.

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';

Tín dụng cho Leo Hsu và Regina Obe tại Postgres Online để chỉ ra oidvectortypes. Tôi đã viết các hàm tương tự trước đây, nhưng đã sử dụng các biểu thức lồng nhau phức tạp mà hàm này không cần sử dụng.

Xem câu trả lời liên quan .


(chỉnh sửa năm 2016)

Tóm tắt các tùy chọn báo cáo điển hình:

-- 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';

THÔNG BÁO : sử dụng p.proname||'_'||p.oid AS specific_name để có được các tên duy nhất hoặc THAM GIA với information_schemacác bảng - xem routinesparameterstại câu trả lời của @ RuddZwolinski.


OID của hàm (xem  pg_catalog.pg_proc) và tên_bảng cụ thể của hàm (xem  information_schema.routines) là các tùy chọn tham chiếu chính cho các hàm. Dưới đây, một số chức năng hữu ích trong báo cáo và bối cảnh khác.

--- --- --- --- ---
--- 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;

Tên pronamelà, nhưng làm thế nào để lấy OID, vd. sử dụng trong pg_catalog.pg_get_function_result(oid))?
Peter Krauss

1
@PeterKrauss oidCột của pg_proc. Đó là một cột ẩn.
Craig Ringer

1
Xem thêm stackoverflow.com/a/25388031/161040 để biết cách loại trừ các chức năng phụ thuộc vào tiện ích mở rộng (ví dụ: các chức năng từ PostGIS).
Simon D

20

Chạy bên dưới truy vấn SQL để tạo chế độ xem sẽ hiển thị tất cả các chức năng:

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

10

Là một ý tưởng hay được đặt tên các hàm với bí danh chung trong các từ đầu tiên để lọc tên với LIKE Ví dụ với lược đồ công khai trong Postgresql 9.4, hãy chắc chắn thay thế bằng lược đồ của anh ấy

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

4

Thí dụ:

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
Câu trả lời của Milen khác nhau như thế nào?
a_horse_with_no_name

3
Đây không phải là một truy vấn, nó là một lệnh của psqlgiao diện máy khách Postgres. Điều này sẽ chỉ hoạt động trong psqlvà về mặt kỹ thuật không phải là một truy vấn SQL.
GregT

3

Nhận danh sách function_schema và 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

Hàm này trả về tất cả các thói quen do người dùng xác định trong cơ sở dữ liệu hiện tại.

SELECT pg_get_functiondef(p.oid) FROM pg_proc p
INNER JOIN pg_namespace ns ON p.pronamespace = ns.oid
WHERE ns.nspname = 'public';
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.