如何解决CDC 在执行存储过程以将新列添加到源表后未捕获更改
我找到了这个存储过程并尝试了它。它应该在启用 CDC 时向源表添加/删除列并且不会丢失任何数据。但是在此过程之后,cdc 不再捕获更改。有任何想法吗?可能是什么问题?
开始
/*-------------------------------------------- -------------------------------------------------- --------- 如何执行:EXEC usp_AddOrDropColumnToCDCTableWithoutLosingData @SchemaName,@TableName,@ColumnName,@Action
添加新列 示例:EXEC usp_AddOrDropColumnToCDCTableWithoutLosingData 'dbo','T','NAME','ADD'
删除现有列 示例:EXEC usp_AddOrDropColumnToCDCTableWithoutLosingData 'dbo','Name','DROP'
----------------------------------------------- -------------------------------------------------- -------*/ 设置 ANSI_NULLS 开启
开始
设置 QUOTED_IDENTIFIER 开启
开始
创建程序 dbo.Usp_addordropcolumntocdctablewithoutlosingdata @pSchemaName VARCHAR(50),@pTableName VARCHAR(100),@pColumnName VARCHAR(100),@pAction VARCHAR(10) 作为 开始 声明 @vsqlTempTable NVARCHAR(MAX) 声明 @vsqlAlterTable NVARCHAR(MAX) 声明 @vdisableCDC NVARCHAR(MAX) 声明 @vGetAlreadyExistingColumns NVARCHAR(MAX) 声明 @vEnableCDC NVARCHAR(MAX) 声明 @vLoadCDCTable NVARCHAR(MAX) 声明 @vDropCreateTemp NVARCHAR(MAX) 声明 @vDataType VARCHAR(50) 声明 @vColumnList NVARCHAR(2000) 声明 @vColumnExists INT 声明 @vColumnExistsCDC INT 声明 @vTempTableName VARCHAR(100) 声明 @vDropColumnList NVARCHAR(2000) 声明@vDropColumnListExcSys NVARCHAR(2000)
SET @vTempTableName='##' + @pSchemaName + '_' + @pTableName
BEGIN TRY
IF ( @pAction = 'ADD'
OR @pAction = 'Drop' )
BEGIN
--Check if Column exists for SourceTable table
SET @vColumnExists=(SELECT Count(*)
FROM informatION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @pSchemaName
AND TABLE_NAME = @pTableName
AND COLUMN_NAME = @pColumnName)
IF ( @vColumnExists = 0
AND @pAction = 'ADD' )
BEGIN
PRINT ' COLUMN ::' + @pColumnName
+ ' does not exists for Source Table ::'
+ @pTableName
+ ' Please add column to Source Table to include in CDC Table.'
END
ELSE
BEGIN
PRINT ' COLUMN ::' + @pColumnName
+ ' exists for Source Table ::' + @pTableName
+ '-->Proceeding to Next Step.'
END
--Check if Column exists for CDC table
IF ( @vColumnExists != 0
AND @pAction = 'ADD' )
SET @vColumnExistsCDC=(SELECT Count(*)
FROM informatION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'cdc'
AND TABLE_NAME = @pSchemaName + '_' + @pTableName + '_CT'
AND COLUMN_NAME = @pColumnName)
IF ( @vColumnExistsCDC != 0
AND @pAction = 'ADD' )
BEGIN
PRINT ' COLUMN ::' + @pColumnName
+ ' is already part of CDC Tble ::cdc.'
+ @pSchemaName + '_' + @pTableName + 'CT'
END
IF ( @vColumnExistsCDC = 0
AND @pAction = 'ADD' )
BEGIN
PRINT ' COLUMN ::' + @pColumnName
+ ' is not part of CDC Tble ::cdc.'
+ @pSchemaName + '_' + @pTableName
+ 'CT -->Proceeding to ADD this column'
END
--copY EXISTING CDC TABLE TO TEMP TABLE
--Drop Temp table before Creating/Loading IT
SET @vDropCreateTemp=' IF Object_id(N''tempdb..'
+ @vTempTableName
+ ''') IS NOT NULL
BEGIN
DROP TABLE ##'
+ @pSchemaName + '_' + @pTableName + ' END'
PRINT @vDropCreateTemp
EXEC (@vDropCreateTemp)
SET @vsqlTempTable= 'SELECT * INTO ' + @vTempTableName
+ ' From cdc.' + @pSchemaName + '_' + @pTableName
+ '_CT'
PRINT @vsqlTempTable
EXEC(@vsqlTempTable)
IF ( @vColumnExistsCDC = 0
AND @pAction = 'ADD' )
BEGIN
--ADD COLUMN TO TEMP TABLE
SET @vDataType=(SELECT CASE
WHEN DATA_TYPE IN ( 'CHAR','varchar','nvarchar' ) THEN DATA_TYPE + '('
+ Cast(CHaraCTER_MAXIMUM_LENGTH AS VARCHAR(50))
+ ')'
WHEN Data_Type IN ( 'int','bigint','smallint','tinyint','money','bit','date','datetime' ) THEN Data_Type
WHEN data_type IN ( 'numeric','decimal' ) THEN DATA_TYPE + '('
+ Cast(Numeric_Precision_Radix AS VARCHAR(50))
+ ',' + Cast(Numeric_scale AS VARCHAR(50))
+ ')'
END AS DataType
FROM informatION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @pTableName
AND COLUMN_NAME = @pColumnName)
SET @vsqlAlterTable='ALTER TABLE ' + @vTempTableName + ' ADD '
+ @pColumnName + ' ' + @vDataType
PRINT @vsqlAlterTable
EXEC (@vsqlAlterTable)
-- ENABLE CDC ON TABLE ( INCLUDING NEW COLUMN)
IF Object_id(N'tempdb..##ColumnList') IS NOT NULL
BEGIN
DROP TABLE ##ColumnList
END
CREATE TABLE ##ColumnList
(
ColumnList NVARCHAR(2000)
)
SET @vGetAlreadyExistingColumns= N' DECLARE @vCDCAlreadyEnabledColumns NVARCHAR(2000)
SELECT @vCDCAlreadyEnabledColumns = COALESCE(@vCDCAlreadyEnabledColumns+ '','','''')
+ QUOTENAME(COLUMN_NAME) FROM informatION_SCHEMA.COLUMNS WHERE TABLE_NAME='''
+ @pSchemaName + '_' + @pTableName + '_'
+ 'CT'' AND COLUMN_NAME NOT
IN (''__$start_lsn'',''__$end_lsn'',''__$seqval'',''__$operation'',''__$update_mask'')
PRINT @vCDCAlreadyEnabledColumns
Insert into ##ColumnList values (@vCDCAlreadyEnabledColumns)'
PRINT @vGetAlreadyExistingColumns
EXEC ( @vGetAlreadyExistingColumns)
SELECT @vColumnList = ColumnList + ',[' + @pColumnName + ']'
FROM ##ColumnList
PRINT @vColumnList
-- disABLE CDC ON SOURCE TABLE
SET @vdisableCDC='EXEC sys.sp_cdc_disable_table @source_schema='''
+ @pSchemaName + ''',@source_name='''
+ @pTableName + ''',@capture_instance='''
+ @pSchemaName + '_' + @pTableName + ''''
PRINT @vdisableCDC
EXEC (@vdisableCDC)
--Enable CDC
SET @vEnableCDC='EXEC sys.sp_cdc_enable_table
@source_schema=''' + @pSchemaName
+ ''',@source_name=''' + @pTableName
+ ''',@role_name=NULL,@captured_column_list= '''
+ @vColumnList + ''''
PRINT @vEnableCDC
EXEC (@vEnableCDC)
-- INSERT RECORD FROM Temp to CDC Table
SET @vLoadCDCTable=' INSERT INTO cdc.' + @pSchemaName + '_'
+ @pTableName
+ '_CT
SELECT * FROM '
+ @vTempTableName + ''
-- Drop Table '+@vTempTableName+''
PRINT @vLoadCDCTable
EXEC (@vLoadCDCTable)
END
/***-------------------------------------DROP COLUMN LOGIC STARTS-----------------------------************/
--Build Column List excluding Drop column
IF EXISTS (SELECT 1
FROM informatION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'cdc'
AND TABLE_NAME = @pSchemaName + '_' + @pTableName + '_CT'
AND COLUMN_NAME = @pColumnName)
AND @pAction = 'Drop'
BEGIN
SELECT @vDropColumnList = Stuff(o.COLUMNNAME,1,'')
FROM informatION_SCHEMA.COLUMNS t
CROSS APPLY (SELECT ',' + Column_Name + Char(10) AS [text()]
FROM informatION_SCHEMA.COLUMNS c
WHERE c.Table_Name = t.Table_Name
AND c.COLUMN_NAME <> @pColumnName
FOR XML PATH('')) o (COLUMNNAME)
WHERE t.Table_Name = 'dbo_' + @pTableName + '_CT'
--Get Columns without Sytem Columns
SELECT @vDropColumnListExcSys = Stuff(o.COLUMNNAME,' + Column_Name + Char(10) AS [text()]
FROM informatION_SCHEMA.COLUMNS c
WHERE c.Table_Name = t.Table_Name
AND c.COLUMN_NAME <> @pColumnName
AND C.COLUMN_NAME NOT IN ( '__$start_lsn','__$end_lsn','__$seqval','__$operation','__$update_mask' )
FOR XML PATH('')) o (COLUMNNAME)
WHERE t.Table_Name = 'dbo_' + @pTableName + '_CT'
-- disABLE CDC for Drop Column
SET @vdisableCDC='EXEC sys.sp_cdc_disable_table @source_schema='''
+ @pSchemaName + ''',@capture_instance='''
+ @pSchemaName + '_' + @pTableName + ''''
EXEC (@vdisableCDC)
-- ENABLE TABLE EXCLUDING GIVEN COLUMN
SET @vEnableCDC='EXEC sys.sp_cdc_enable_table
@source_schema=''' + @pSchemaName
+ ''',@captured_column_list= '''
+ @vDropColumnListExcSys + ''''
EXEC (@vEnableCDC)
--copY DATA FROM TEMP DATA TO CDC TABLE
SET @vLoadCDCTable=' INSERT INTO cdc.' + @pSchemaName + '_'
+ @pTableName + '_CT(' + @vDropColumnList
+ ')
SELECT '
+ @vDropColumnList + ' FROM ' + @vTempTableName
+ ''
--Drop Table '+@vTempTableName+''
EXEC (@vLoadCDCTable)
END
END
ELSE
PRINT ' ADD OR Drop are the correct actions available for this Procedure.Please provide ADD or Drop for SP Signature'
END TRY
BEGIN CATCH
ROLLBACK
PRINT ' ERROR Occured and All Transactions are rolledback.'
END CATCH
结束
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。