PostgreSQL: Як перелічити всі збережені функції, що мають доступ до певної таблиці


13

Вступ:

База даних PostgreSQL з кількома сотнями збережених функцій, включаючи застарілі, не використовувані тощо

Проблема

Мені потрібно з’ясувати всі збережені функції, які мають будь-яке відношення до таблиці X - як я хочу змінити структуру таблиці. Деякі з них можуть не використовуватися, тому я не можу це зробити, просто переглянувши код.

У мене є ATM-рішення, яке працює у форматі psql \df+та виведення даних, але я вважаю за краще більш схоже на базу даних рішення, тобто за допомогою інформаційної схеми. Це, безумовно, буде повторюваним завданням, і я хотів би, щоб воно було приємним і чистим.

Будь-які пропозиції?

Відповіді:


18

Тіло функції просто зберігається як рядок . Немає списку посилаються об’єктів. (Це відрізняється від представлень, наприклад, де зберігаються фактичні посилання на посилання на таблиці.)

Цей запит для Postgres 10 або старіших версій використовує інформацію про системний каталогpg_get_functiondef() для реконструкції CREATE FUNCTIONскрипту для відповідних функцій та здійснює пошук назви таблиці з регулярним виразом, нечутливим до регістру:

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

Він повинен зробити цю роботу, але це, очевидно, не є кулезахисним. Він може не працювати в динамічному SQL, де ім'я таблиці генерується динамічно, і він може повернути будь-яку кількість помилкових позитивів, особливо якщо ім'я таблиці є загальним словом.

Функції сукупності та всі функції із системних схем виключаються.

\mі\M позначте початок і кінець слова в регулярному виразі.

Системний каталог pg_procзмінено у Postgres 11. proisaggбуло замінено на prokindсправжні збережені процедури. Вам потрібно адаптуватися. Пов'язані:


1
Так ... це не зовсім надійно, в тому сенсі, що він не знайде EXECUTEвиразів на зразок 'mm_'||name_parameter, і він не справляється правильно з цитованими іменами на кшталт "my""table""або зі складанням регістру, але це зробить більшість того, що хоче більшість людей .
Крейг Рінгер

@CraigRinger: Так, динамічні запити EXECUTEмайже неможливо охопити. Але складання корпусу може бути прикрито ~*замість ~- або будь-яке інше нечутливе до випадку узор.
Erwin Brandstetter

До тих пір, поки оператор не досить божевільний, щоб насправді створити таблиці з назвою "MyTable"і MyTable, принаймні ... і чесно, це "добре, що може бути дозволено, але це не розумно".
Крейг Рінгер

Дякую за відповідь! Насправді я ніде не використовую динамічну побудову імен таблиці, і всі назви таблиць бувають малі.
Сергій Кудрявцев

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.