如何跟踪PostgreSQL中任何函数的变化

Taj*_*der 3 sql postgresql triggers postgresql-9.4

我想跟踪PostgreSQL中任何函数的变化。

示例-假设我fun_name()在postgesql数据库中具有功能,并且正在对功能进行修改。

现在,我想跟踪类似

DateTime,Schema_name,Function_name,old_func_text,new_func_text
Run Code Online (Sandbox Code Playgroud)

请在postgresql中提出实现此目标的最佳方法。

我正在https://www.postgresql.org/docs/9.3/static/sql-createeventtrigger.html中研究事件触发器

谢谢。

kli*_*lin 5

Postgres 9.5中,有一个函数pg_event_trigger_ddl_commands()可以在事件触发器中使用,以获取插入/更改的对象的oid。

日志表:

create table function_log (
    datetime timestamp, 
    schema_name text, 
    function_name text, 
    tag text, 
    function_body text);
Run Code Online (Sandbox Code Playgroud)

事件功能和触发:

create or replace function public.on_function_event()
    returns event_trigger
    language plpgsql
as $function$
begin
    insert into function_log
    select now(), nspname, proname, command_tag, prosrc
    from pg_event_trigger_ddl_commands() e
    join pg_proc p on p.oid = e.objid
    join pg_namespace n on n.oid = pronamespace;
end
$function$;

create event trigger on_function_event
on ddl_command_end 
when tag in ('CREATE FUNCTION', 'ALTER FUNCTION')
execute procedure on_function_event();
Run Code Online (Sandbox Code Playgroud)

例:

create or replace function test()
returns int as $$ select 1; $$ language sql;

create or replace function test()
returns int as $$ select 2; $$ language sql;

alter function test() immutable;

select *
from function_log;

          datetime          | schema_name | function_name |       tag       | function_body 
----------------------------+-------------+---------------+-----------------+---------------
 2017-02-26 13:05:15.353879 | public      | test          | CREATE FUNCTION |  select 1; 
 2017-02-26 13:05:15.353879 | public      | test          | CREATE FUNCTION |  select 2; 
 2017-02-26 13:05:15.353879 | public      | test          | ALTER FUNCTION  |  select 2; 
(3 rows)
Run Code Online (Sandbox Code Playgroud)

您可以将DROP FUNCTION命令标签添加到触发器,然后pg_event_trigger_dropped_objects()以与相似的方式使用该函数pg_event_trigger_ddl_commands()

不幸的是,没有pg_event_trigger_ddl_commands()Postgres的9.4。您可以尝试使用获取插入/更改的对象,current_query()或在中编写触发函数C。我认为更简单的方法是将Postgres升级到9.5+。