很遗憾,mysql不支持database级别的trigger。无法使用触发器记录ddl。
如果需要获取dll记录可以使用debezium/cdc在mysql的binlog中解析。
能记录:
不能记录
-- 参考文章:https://blog.csdn.net/weixin_42212488/article/details/127873487
-- 官方文档:https://www.postgresql.org/docs/13/functions-event-triggers.html#PG-EVENT-TRIGGER-TABLE-REWRITE-FUNCTIONS
drop table ddl_log;
create table ddl_log(
id serial8,
"user" text,
txid bigint,
schema_name text,
ddl_type text,
object varchar,
ddl_query text,
query_time timestamp
);
truncate audit_ddl;
select * from audit_ddl;
drop function ddl_listen_common();
create or replace function ddl_listen_common()
returns event_trigger
language plpgsql
as
$$
declare
query text;
command record;
begin
query := current_query();
if exists(select * from pg_event_trigger_ddl_commands()) then
for command in select * from pg_event_trigger_ddl_commands()
loop
insert into audit_ddl("user", txid, schema_name, ddl_type, object, ddl_query, query_time)
VALUES (current_user,txid_current(),command.schema_name,command.command_tag,command.object_identity,query, statement_timestamp());
end loop ;
end if;
end;
$$
security definer;
drop event trigger trg_ddl_listen_common;
create event trigger trg_ddl_listen_common on ddl_command_end execute procedure ddl_listen_common();
drop function ddl_listen_drop;
create or replace function ddl_listen_drop()
returns event_trigger
language plpgsql
as
$$
declare
query text;
command record;
begin
query := current_query();
if exists(select * from pg_event_trigger_dropped_objects()) is not null then
for command in select * from pg_event_trigger_dropped_objects()
loop
insert into audit_ddl("user", txid, schema_name, ddl_type, object, ddl_query, query_time)
VALUES (current_user,txid_current(),command.schema_name,'DROP '||command.object_type,command.object_identity,query, statement_timestamp());
end loop;
end if;
end;
$$
security definer;
drop event trigger trg_ddl_listen_drop;
create event trigger trg_ddl_listen_drop on sql_drop execute procedure ddl_listen_drop();
drop table if exists ischema.schema_evo;
create table ischema.schema_evo(
id bigint primary key
,name varchar(30)
,address varchar(30)
);
insert into ischema.schema_evo values(1,'zhangsna','beijing');
alter table ischema.schema_evo add "gender" varchar(10);
insert into ischema.schema_evo values(2,'lisi','male','shanghai');
alter table ischema.schema_evo rename column "name" to name_abbr;
insert into ischema.schema_evo values(3,'lvzhou','male','shanghai');
alter table ischema.schema_evo alter column "name_abbr" type varchar(50);
insert into ischema.schema_evo values(4,'wangwu','female','chongqing');
alter table ischema.schema_evo drop column address;
insert into ischema.schema_evo values(5,'zhaoliu','male');
-- 不支持truncate记录。
truncate ischema.schema_evo;
select * from ischema.schema_evo where 1=1 order by id desc limit 10;
能记录
不能记录
-- 参考文章:https://blog.csdn.net/qq_40205468/article/details/88845215
drop table ischema.audit_ddl;
truncate ischema.audit_ddl;
select * from ischema.audit_ddl;
drop trigger trg_ddl_listen ON DATABASE;
-- 以下均为触发器内容,一次执行即可。
CREATE TRIGGER trg_ddl_listen
ON DATABASE
FOR CREATE_TABLE, DROP_TABLE, ALTER_TABLE
AS
/* 本触发器只针对触发器的增删改,进行记录触发器的相关信息 */
IF OBJECT_ID(N'ischema.audit_ddl', N'U') is NULL
begin
CREATE TABLE ischema.audit_ddl
(
rowid INT IDENTITY ,
EventType VARCHAR(20) ,
PostTime DATETIME ,
SPID INT ,
ServerName VARCHAR(255) ,
LoginName VARCHAR(255) ,
DatabaseName VARCHAR(255) ,
UserName VARCHAR(255),
SchemaName VARCHAR(20) ,
ObjectName VARCHAR(255) ,
ObjectType VARCHAR(20) ,
CommandText NVARCHAR(MAX) ,
remark NVARCHAR(MAX) ,
commandtext_check INT
);
end
DECLARE
@EeventType VARCHAR(20),
@PostTime DATETIME,
@SPID INT,
@ServerName VARCHAR(255),
@LoginName VARCHAR(255),
@DatabaseName VARCHAR(255),
@UserName VARCHAR(255),
@SchemaName VARCHAR(255),
@ObjectName VARCHAR(255),
@ObjectType VARCHAR(20),
@CommandText NVARCHAR(MAX),
@Remarks NVARCHAR(MAX),
@Commandtest_check INT
SET @EeventType=EVENTDATA().value('(/EVENT_INSTANCE/EventType)[1]','VARCHAR(20)')
SET @PostTime=EVENTDATA().value('(/EVENT_INSTANCE/PostTime)[1]','DATETIME')
SET @SPID=EVENTDATA().value('(/EVENT_INSTANCE/SPID)[1]','INT')
SET @ServerName=EVENTDATA().value('(/EVENT_INSTANCE/ServerName)[1]','VARCHAR(255)')
SET @LoginName=EVENTDATA().value('(/EVENT_INSTANCE/LoginName)[1]','VARCHAR(255)')
SET @DatabaseName=EVENTDATA().value('(/EVENT_INSTANCE/LoginName)[1]','VARCHAR(255)')
SET @UserName=EVENTDATA().value('(EVENT_INSTANCE/UserName)[1]','VARCHAR(255)')
SET @SchemaName=EVENTDATA().value('(EVENT_INSTANCE/SchemaName)[1]','VARCHAR(255)')
SET @ObjectName=EVENTDATA().value('(EVENT_INSTANCE/ObjectName)[1]','VARCHAR(255)')
SET @ObjectType=EVENTDATA().value('(EVENT_INSTANCE/ObjectType)[1]','VARCHAR(255)')
SET @CommandText=EVENTDATA().value('(EVENT_INSTANCE/TSQLCommand/CommandText)[1]','NVARCHAR(MAX)')
INSERT INTO ischema.audit_ddl
( EventType ,
PostTime ,
SPID ,
ServerName ,
LoginName ,
DatabaseName ,
UserName ,
SchemaName ,
ObjectName ,
ObjectType ,
CommandText ,
remark ,
commandtext_check
)
SELECT @EeventType,
@PostTime,
@SPID,
@ServerName,
@LoginName,
@DatabaseName,
@UserName,
@SchemaName,
@ObjectName,
@ObjectType,
@CommandText,
'',
0;
drop table ischema.schema_evo;
create table ischema.schema_evo(
id bigint primary key
,name varchar(30)
,address varchar(30)
);
-- 启动表的CDC跟踪。
EXEC sys.sp_cdc_enable_table @source_schema = 'ischema', @source_name = 'schema_evo', @role_name = NULL, @supports_net_changes = 0;
insert into ischema.schema_evo values(1,'test','xinjiang');
alter table ischema.schema_evo add gender varchar(10);
insert into ischema.schema_evo values(2,'test','beijing','female');
alter table ischema.schema_evo alter column "name" varchar(50);
insert into ischema.schema_evo values(3,'test','hangzhou','male');
-- 已经启用cdc的表无法修改列名称:Cannot alter column 'name' because it is 'REPLICATED'.
exec sp_rename 'ischema.schema_evo.name','name_abbr';
alter table ischema.schema_evo drop column address;
insert into ischema.schema_evo values(4,'test','female');
-- 已经启用cdc的表无法truncate:Cannot truncate table 'ischema.schema_evo' because it is published for replication or enabled for Change Data Capture.
TRUNCATE table ischema.schema_evo;
select * from ischema.schema_evo;
-- 获取ddl, 可以通过 "ddl_command"列 获取到具体的ddl命令。
-- 参考:https://learn.microsoft.com/zh-cn/sql/relational-databases/system-stored-procedures/sys-sp-cdc-get-ddl-history-transact-sql?view=sql-server-ver16&redirectedfrom=MSDN
EXEC sys.sp_cdc_get_ddl_history @capture_instance = 'ischema_schema_evo';
能记录
不能记录
-- 参考文章:https://blog.csdn.net/u014257861/article/details/80182067
-- DBA账号授权。
grant administer DATABASE TRIGGER to cdcuser;
SELECT * FROM USER_SYS_PRIVS; -- 要有:ADMINISTER DATABASE TRIGGER 权限
DROP TABLE audit_ddl;
create table audit_ddl (
opertime timestamp PRIMARY KEY,
ip varchar2(20),
hostname varchar2(30),
operation varchar2(30),
object_type varchar2(30),
object_name varchar2(30),
sql_stmt clob,
db_schema varchar2(30)
);
TRUNCATE TABLE audit_ddl;
SELECT * FROM audit_ddl;
DROP TRIGGER trg_ddl_listen;
create or replace trigger trg_ddl_listen
after ddl on database
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
n NUMBER;
stmt clob := NULL;
sql_text ora_name_list_t;
BEGIN
n := ora_sql_txt(sql_text);
FOR i IN 1 .. n LOOP
stmt := stmt || sql_text(i);
END LOOP;
INSERT INTO audit_ddl
(opertime, ip, hostname, operation, object_type, object_name, sql_stmt,db_schema)
VALUES
(systimestamp,
sys_context('userenv', 'ip_address'),
sys_context('userenv', 'HOST'),
ora_sysevent,
ora_dict_obj_type,
ora_dict_obj_name,
stmt,
user
);
COMMIT;
END;
drop table DBO.SCHEMA_EVO;
create table DBO.SCHEMA_EVO(
id numeric(10,0) primary key
,name varchar(30)
,address varchar(30)
);
INSERT INTO DBO.SCHEMA_EVO VALUES(1,'TEST','BEIJING');
ALTER TABLE DBO.SCHEMA_EVO ADD gender varchar(10);
INSERT INTO DBO.SCHEMA_EVO VALUES(2,'TEST','SHANGHAI','FEMALE');
ALTER TABLE DBO.SCHEMA_EVO MODIFY name varchar(50) default 'abbr';
INSERT INTO DBO.SCHEMA_EVO VALUES(3,'TEST','SHANGHAI','MALE');
ALTER TABLE DBO.SCHEMA_EVO RENAME COLUMN name TO name_abbr;
INSERT INTO DBO.SCHEMA_EVO VALUES(4,'TEST','SUZHOU','FEMALE');
ALTER TABLE DBO.SCHEMA_EVO DROP COLUMN address;
INSERT INTO DBO.SCHEMA_EVO VALUES(5,'TEST','FEMALE');
-- 支持记录TRUNCATE操作.
TRUNCATE TABLE DBO.SCHEMA_EVO;
SELECT * FROM DBO.SCHEMA_EVO;