docker安装
bash
docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=Zcyc123456" -p 1433:1433 --name sqlserver -d mcr.microsoft.com/mssql/server:2017-latest
开启库cdc模式
选择你自己的数据库,执行以下sql语句
sql
EXEC sys.sp_cdc_enable_db;
校验
sql
SELECT is_cdc_enabled FROM sys.databases WHERE name = YourDatabaseName
开启表cdc
原因:即使您在数据库级别启用了CDC(Change Data Capture)功能,对于要捕获变更的特定表,仍然需要在表级别单独启用CDC。启动数据库级别的CDC功能为该数据库开启了使用CDC技术的基础环境,但不会自动对任何用户表进行变更数据捕获。
批量开启表cdc
sql
-- 确保当前数据库已启用CDC
USE test;
GO
-- 获取dbo架构下所有用户表名(可以根据需要修改查询以选择不同架构或添加其他过滤条件)
DECLARE @TableNames TABLE (TableName SYSNAME);
INSERT INTO @TableNames (TableName)
SELECT t.name
FROM sys.tables t
WHERE t.is_ms_shipped = 0 -- 排除系统表和临时表
AND t.schema_id = SCHEMA_ID('dbo') -- 只考虑dbo架构下的表
-- AND t.some_column IS NOT NULL -- 添加任何其他你想要应用的筛选条件
-- 遍历表格并启用CDC
DECLARE @CurrentTableName SYSNAME;
DECLARE TableCursor CURSOR FOR
SELECT TableName FROM @TableNames;
OPEN TableCursor;
FETCH NEXT FROM TableCursor INTO @CurrentTableName;
WHILE @@FETCH_STATUS = 0
BEGIN
IF NOT EXISTS (SELECT 1 FROM sys.change_tracking_tables WHERE object_id = OBJECT_ID(@CurrentTableName) AND is_track_columns_updated_on = 1)
BEGIN
DECLARE @Sql NVARCHAR(MAX) = N'EXEC sys.sp_cdc_enable_table
@source_schema = N''dbo'',
@source_name = N''' + @CurrentTableName + ''',
@role_name = NULL,
@capture_instance = N''dbo_' + @CurrentTableName + '''';
EXEC sp_executesql @Sql;
END
FETCH NEXT FROM TableCursor INTO @CurrentTableName;
END
CLOSE TableCursor;
DEALLOCATE TableCursor;
docker中启动SQL Server Agent
还需要开启SQL Server Agent才能够使用cdc功能
bash
docker exec -it sql1 "bash"
root@b9a09ce17c02:/# /opt/mssql/bin/mssql-conf set sqlagent.enabled true
SQL Server needs to be restarted in order to apply this setting. Please run
'systemctl restart mssql-server.service'.
root@b9a09ce17c02:/# exit
exit
[root@localhost ~]#
[root@localhost ~]# docker stop sql1
sql1
[root@localhost ~]# docker start sql1
sql1
检查是否开启成功
sql
-- Check if CDC is enabled on the database
SELECT name, is_cdc_enabled FROM sys.databases WHERE name = 'your_database_name';
-- Check if CDC is enabled on the tables
SELECT s.name AS schema_name, t.name AS table_name, t.is_tracked_by_cdc
FROM sys.tables t
JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE t.is_tracked_by_cdc = 1;