有什么方法可以只获取我们在CDC表中修改了值的列名吗?

问题描述 投票:0回答:1
DECLARE @ColumnName NVARCHAR(MAX);
DECLARE @SQLQuery NVARCHAR(MAX) = N'';
DECLARE @HasColumns BIT = 0;

DECLARE ColumnCursor CURSOR FOR
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'dbo_OINV_CT' AND TABLE_SCHEMA = 'cdc'; -- Adjust the schema name if necessary

OPEN ColumnCursor;
FETCH NEXT FROM ColumnCursor INTO @ColumnName;

WHILE @@FETCH_STATUS = 0
BEGIN
    IF @HasColumns = 0
    BEGIN
        SET @SQLQuery = 'SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE 1=0 ';
        SET @HasColumns = 1;
    END

    SET @SQLQuery = @SQLQuery +
        'OR EXISTS (
            SELECT 1
            FROM cdc.dbo_OINV_CT t1
            INNER JOIN cdc.dbo_OINV_CT t2 ON t1.__$start_lsn = t2.__$start_lsn AND t1.__$seqval = t2.__$seqval
            WHERE t1.[__$operation] = 3 -- Before update
            AND t2.[__$operation] = 4 -- After update
            AND t1.' + QUOTENAME(@ColumnName) + ' <> t2.' + QUOTENAME(@ColumnName) + '
        )' + CHAR(13);

    FETCH NEXT FROM ColumnCursor INTO @ColumnName;
END

CLOSE ColumnCursor;
DEALLOCATE ColumnCursor;



-- Execute the constructed SQL query if columns are found
IF @HasColumns = 1
BEGIN
    SET @SQLQuery = REPLACE(@SQLQuery, 'OR EXISTS', 'AND (EXISTS');
    SET @SQLQuery = REPLACE(@SQLQuery, ' OR)', ')');
    EXEC sp_executesql @SQLQuery;
END
ELSE
BEGIN
    PRINT 'No columns found in dbo_OINV_CT.';
END

尝试仅获取我们修改了 CDC 表中的值的列名称,脚本未完全执行。

Error:Msg 191, Level 15, State 1, Line 1712 SQL 语句的某些部分嵌套得太深。重写查询或将其分解为更小的查询。

sql-server
1个回答
0
投票

如果您想找出 CDC 表中任何位置是否有 any

UPDATE
行显示每列的修改,那么您可以按位聚合所有更新掩码。

不幸的是,SQL Server 不支持

BIT_OR
,这会让生活变得更容易,相反,我们需要聚合每一位的
MAX

SELECT
  cc.column_name
FROM (
    SELECT totalMasks =
      MAX(1 & __$update_mask) + MAX(2 & __$update_mask) + MAX(4 & __$update_mask) + MAX(8 & __$update_mask) +
      MAX(16 & __$update_mask) + MAX(32 & __$update_mask) + MAX(64 & __$update_mask) + MAX(128 & __$update_mask) +
      MAX(256 & __$update_mask) + MAX(512 & __$update_mask) + MAX(1024 & __$update_mask) + MAX(2048 & __$update_mask) +
      MAX(4096 & __$update_mask) + MAX(8192 & __$update_mask) + MAX(16384 & __$update_mask) + MAX(32768 & __$update_mask) +
      MAX(65536 & __$update_mask) + MAX(131072 & __$update_mask) + MAX(262144 & __$update_mask) + MAX(524288 & __$update_mask) +
      MAX(1048576 & __$update_mask) + MAX(2097152 & __$update_mask) + MAX(4194304 & __$update_mask) + MAX(8388608 & __$update_mask) +
      MAX(16777216 & __$update_mask) + MAX(33554432 & __$update_mask) + MAX(67108864 & __$update_mask) + MAX(134217728 & __$update_mask) +
      MAX(268435456 & __$update_mask) + MAX(536870912 & __$update_mask) + MAX(1073741824 & __$update_mask) + MAX(-2147483648 & __$update_mask)
    FROM cdc.dbo_OINV_CT t
    WHERE t.__$operation = 4
) t
JOIN cdc.captured_columns cc ON sys.fn_cdc_is_bit_set(cc.column_ordinal, t.totalMasks) = 1
WHERE cc.object_id = OBJECT_ID(N'dbo.OINV');
© www.soinside.com 2019 - 2024. All rights reserved.