我要完成的工作是相互比较两行,指出行与行之间的差异。每行都有相当多的列,我正尝试使其易于查看,以了解哪些更改了。下面的代码是我的想法,但是我知道这行不通,但这只是一个开始。
SELECT
(SELECT concat('Case WHEN T1.', column_name, ' <> T2.', column_name, ' THEN ''', column_name, ' Changed Values('' + CONVERT(varchar(100), T1.', column_name, ') + '', '' + CONVERT(varchar(100), T2.', column_name, ') + '')'' ELSE '''' END AS ', column_name)
FROM information_schema.columns
WHERE table_name = 'Table')
FROM
(
SELECT * FROM Table
WHERE ID = '13'
) AS T1
JOIN
(
SELECT * FROM Table
WHERE ID = '2006'
) AS T2
ON T1.CreateTimeStamp = T2.CreateTimeStamp
我有主意,因为在这种情况下可以正常工作,但是我希望这可以成为其他表的可重用代码,而不必每次都键入数十或数百列。
SELECT
Case WHEN T1.R1<> T2.R1 THEN 'Changed Values(' + CONVERT(varchar(100),T1.R1) + ', ' + CONVERT(varchar(100),T2.R1) + ')' ELSE '' END AS R1,
Case WHEN T1.R2<> T2.R2 THEN 'Changed Values(' + CONVERT(varchar(100),T1.R2) + ', ' + CONVERT(varchar(100),T2.R2) + ')' ELSE '' END AS R2
FROM
(
SELECT * FROM Table
WHERE ID = '13'
) AS T1
JOIN
(
SELECT * FROM Table
WHERE ID = '2006'
) AS T2
ON T1.CreateTimeStamp = T2.CreateTimeStamp
在此示例中,请假设CreateTimeStamp在两行之间始终相等。
答案 0 :(得分:1)
您需要将整个查询创建为动态SQL。请注意,我正在使用QUOTENAME()
来防止SQL注入异常命名的列。我还尝试保持代码格式,因此调试时不会头痛。
DECLARE @SQL NVARCHAR(MAX);
SELECT @SQL = N' SELECT ' + NCHAR(10)
--Concatenate all columns except ID and CreateTimeStamp
+ STUFF(( SELECT REPLACE( CHAR(9) + ',CASE WHEN T1.<<ColumnName>> <> T2.<<ColumnName>> ' + CHAR(10)
+ CHAR(9) + CHAR(9) + 'THEN ''Changed Values('' + CONVERT(varchar(100),T1.<<ColumnName>>) + '', '' + CONVERT(varchar(100),T2.<<ColumnName>>) + '')'' ' + CHAR(10)
+ CHAR(9) + CHAR(9) + 'ELSE '''' END AS <<ColumnName>>', '<<ColumnName>>', QUOTENAME(COLUMN_NAME)) + NCHAR(10)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Table'
AND COLUMN_NAME NOT IN( 'ID', 'CreateTimeStamp')
FOR XML PATH(''), TYPE).value('./text()[1]', 'nvarchar(max)'), 2, 1, '') + NCHAR(10)
--Add rest of the query
+ 'FROM Table AS T1 ' + NCHAR(10)
+ 'JOIN Table AS T2 ON T1.CreateTimeStamp = T2.CreateTimeStamp ' + NCHAR(10)
+ 'WHERE ID = @ID1 ' + NCHAR(10)
+ 'AND ID = @ID2;'
--PRINT for debugging purposes
PRINT @SQL;
--Execute the dynamic built code
EXECUTE sp_executesql @SQL,
N'@ID1 int, @ID2 int',
@ID1 = 13,
@ID2 = 2006;
在this article上说明了串联方法。