触发器实现变更数据捕获

应用场景:变更数据捕获cdc当程序中出现truncate语句的时候,会导致程序报错不能正常执行。如果如果修改程序的话,可以通过触发器实现变更数据捕获

不足之处:对于insert bulk是不生效的。

--创建表存放列名
if  exists (select 1 from sys.tables where name like 'hb_columncollect')
drop table hb_columncollect
create table hb_columncollect(ffieldname nvarchar(100) ,fid int )
--存储过程用来拼写非计算列的列名   
if exists (select 1 from sys.objects where name='sp_columncollect_alter' and type='P')
drop  procedure sp_columncollect_alter
go
create  procedure sp_columncollect_alter
@ftablename nvarchar(100),
@string nvarchar(max) out
as
set nocount on  
delete from hb_columncollect
exec('insert into hb_columncollect(ffieldname,fid)
     select name,column_id from sys.columns t where object_id=OBJECT_ID('''+@ftablename+''') and is_computed<>1    order by column_id ')
set @string=''
select @string=@string+ffieldname+',' from hb_columncollect order by fid
set  @string=substring(@string,1,len(@string)-1)
go
--创建表收集需要特殊处理的表名
if not exists (select 1 from sys.tables where name like 'chl_nocdctable')
create table chl_nocdctable(ftablename nvarchar(100),fconment nvarchar(1000))
go
insert into chl_nocdctable(ftablename,fconment) values('table1','截断报错')
insert into chl_nocdctable(ftablename,fconment) values('table2','截断报错')
insert into chl_nocdctable(ftablename,fconment) values('table3','截断报错')
go
--创建表存储变更数据
declare @allcolumn nvarchar(max)
declare @tablename nvarchar(100)
declare cur_cdc_on cursor for select ftablename from chl_nocdctable
open cur_cdc_on
fetch cur_cdc_on into @tablename
while @@FETCH_STATUS<>-1
begin
  exec('if exists (SELECT 1 FROM SYS.TABLES WHERE NAME =''dbo_'+@tablename+'_chl'')
  drop table cdc.dbo_'+@tablename+'_chl
  ')
  exec('select * INTO cdc.dbo_'+@tablename+'_chl from '+@tablename+' where 1=2')
  exec('alter table cdc.[dbo_'+@tablename+'_chl] add fchl_curdate datetime default getdate()')
  exec('alter table cdc.[dbo_'+@tablename+'_chl] add fchl_cdcid int identity(1,1)')
  exec('alter table cdc.[dbo_'+@tablename+'_chl] add fchl_type char(1)')
  exec sp_columncollect_alter @tablename,@allcolumn out
  exec('if  exists(select 1 from sys.objects where name =''chltri_'+@tablename+''' and type=''tr'')
  drop trigger chltri_'+@tablename )
  exec('
  create trigger chltri_'+@tablename+' on '+@tablename+' after insert,delete ,update 
  as
  insert into cdc.dbo_'+@tablename+'_chl('+@allcolumn+',fchl_type)
  select '+@allcolumn+',isnull((select distinct ''3'' from inserted),''1'') ftype from deleted
  union 
  select '+@allcolumn+',isnull((select distinct ''4'' from inserted),''2'')  from inserted
  ')
fetch cur_cdc_on into @tablename
end
close cur_cdc_on
deallocate cur_cdc_on 
go

你可能感兴趣的:(MySQL,study)