PostgreSQL: Cách liệt kê tất cả các chức năng được lưu trữ truy cập vào bảng cụ thể


13

Giới thiệu:

Cơ sở dữ liệu PostgreSQL với hàng trăm chức năng được lưu trữ, bao gồm lỗi thời, không được sử dụng, v.v.

Vấn đề

Tôi cần tìm ra tất cả các hàm được lưu trữ có bất kỳ mối quan hệ nào với bảng X - vì tôi muốn thay đổi cấu trúc bảng. Một số trong số chúng có thể không được sử dụng, vì vậy tôi không thể làm điều đó chỉ bằng cách xem qua mã.

Giải pháp tôi có ATM là chạy \df+đầu ra của psql và grepping, nhưng tôi thích giải pháp giống như cơ sở dữ liệu hơn, tức là bằng cách sử dụng lược đồ thông tin. Đây chắc chắn sẽ là một nhiệm vụ lặp đi lặp lại và tôi muốn có nó tốt đẹp và sạch sẽ.

Bất kỳ đề xuất?

Câu trả lời:


18

Phần thân của một hàm chỉ được lưu dưới dạng chuỗi . Không có danh sách các đối tượng được tham chiếu. (Chẳng hạn, khác với các khung nhìn, ví dụ, nơi các liên kết thực tế đến các bảng được tham chiếu được lưu.)

Truy vấn này cho Postgres 10 trở lên sử dụng chức năng thông tin danh mục hệ thốngpg_get_functiondef() để xây dựng lại CREATE FUNCTIONtập lệnh cho các chức năng có liên quan và tìm kiếm tên bảng với biểu thức chính quy không phân biệt chữ hoa chữ thường:

SELECT n.nspname AS schema_name
     , p.proname AS function_name
     , pg_get_function_arguments(p.oid) AS args
     , pg_get_functiondef(p.oid) AS func_def
FROM   pg_proc p
JOIN   pg_namespace n ON n.oid = p.pronamespace
WHERE  NOT p.proisagg
AND    n.nspname NOT LIKE 'pg_%'
AND    n.nspname <> 'information_schema'
AND    pg_get_functiondef(p.oid) ~* '\mbig\M';

Nó nên thực hiện công việc, nhưng rõ ràng nó không phải là chống đạn. Nó có thể thất bại đối với SQL động nơi tên bảng được tạo động và nó có thể trả về bất kỳ số dương nào sai - đặc biệt nếu tên bảng là một từ phổ biến.

Các hàm tổng hợp và tất cả các hàm từ các lược đồ hệ thống được loại trừ.

\m\M đánh dấu bắt đầu và kết thúc của một từ trong cụm từ thông dụng.

Danh mục hệ thống pg_procđã thay đổi trong Postgres 11. proisaggđã được thay thế bằng prokind, các thủ tục lưu trữ thực sự đã được thêm vào. Bạn cần phải thích nghi. Liên quan:


1
Đúng ... nó không hoàn toàn mạnh mẽ, theo nghĩa là nó sẽ không tìm thấy các EXECUTEbiểu thức như thế nào 'mm_'||name_parameter, và nó sẽ không đối phó chính xác với các tên được trích dẫn như "my""table""hoặc gấp chữ hoa, nhưng nó sẽ làm hầu hết những gì hầu hết mọi người sẽ muốn .
Craig Ringer

@CraigRinger: Vâng, các truy vấn động EXECUTEgần như không thể bao quát được. Nhưng trường hợp gấp có thể được bao phủ ~*thay vì ~- hoặc bất kỳ trường hợp khớp mẫu không phân biệt chữ hoa chữ thường nào khác.
Erwin Brandstetter

Chừng nào nhà điều hành không đủ điên rồ để thực sự tạo ra các bảng có tên "MyTable"MyTable, ít nhất là ... và thành thật mà nói, đó là một "tốt, có thể được cho phép nhưng nó không thông minh".
Craig Ringer

Cảm ơn câu trả lời! Tôi thực sự không sử dụng xây dựng tên bảng động ở bất cứ đâu và tất cả các tên bảng là chữ thường.
Serge Kudriavtsev

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.