仅查找 SQL 中 2 个字符串之间的差异

Finding the differences only between 2 strings in SQL

我必须比较 2 xml 个字符串(sql 中的 varchar(max)),如下所示:

'<table_name id="2" name="Bob"  job="student"/>'

'<table_name id="2" name="john" job="teacher"/>'

并且结果必须只是差异,这意味着,我得到 2 个字符串,第一个是原始值,第二个是新值。但是,如果没有差异,则将是一个空字符串,例如在这种情况下:

输出 1:'name="Bob", job="student"'

输出 2:'name="john", job="teacher"'

如您所见,我们没有附加 id 字符串,因为没有任何变化,所以自然地,没有变化意味着没有字符串到 return。

是这样的吗?

将其粘贴到空查询中 window 并执行。适应您的需求:

DECLARE @XML1 XML='<table_name id="2" name="Bob"  job="student"/>';
DECLARE @XML2 XML='<table_name id="2" name="john" job="teacher"/>';

WITH AttributValues AS
(
    SELECT @XML1.value('/table_name[1]/@id','varchar(max)') AS id1
          ,@XML1.value('/table_name[1]/@name','varchar(max)') AS name1
          ,@XML1.value('/table_name[1]/@job','varchar(max)') AS job1
          ,@XML2.value('/table_name[1]/@id','varchar(max)') AS id2
          ,@XML2.value('/table_name[1]/@name','varchar(max)') AS name2
          ,@XML2.value('/table_name[1]/@job','varchar(max)') AS job2
)
SELECT 'The differences: '
     + CASE WHEN id1<>id2 THEN 'id: ' + id1 + ' or ' + id2 + ' | ' ELSE '' END  
     + CASE WHEN name1<>name2 THEN 'name: ' + name1 + ' or ' + name2 + ' | ' ELSE '' END  
     + CASE WHEN job1<>job2 THEN 'job: ' + job1 + ' or ' + job2 ELSE '' END  
FROM AttributValues

结果

The differences: name: Bob or john | name: student or teacher

这是最多 100 个属性的通用方法:

DECLARE @XML1 XML='<table_name id="2" name="Bob"  job="student"/>';
DECLARE @XML2 XML='<table_name id="2" name="john" job="teacher"/>';

WITH CountAttributs AS
(
    SELECT LEN(CAST(@XML1 AS VARCHAR(MAX)))-LEN(REPLACE(CAST(@XML1 AS VARCHAR(MAX)),'=','')) AS X
)
, E1(N) AS(SELECT 1 FROM(VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))t(N)) --10 ^ 1
, E2(N) AS(SELECT 1 FROM E1 a CROSS JOIN E1 b) -- 10 ^ 2 = 100 rows
, CteTally AS
(
    SELECT TOP((SELECT X FROM CountAttributs)) ROW_NUMBER() OVER(ORDER BY(SELECT NULL)) AS Nmbr
    FROM E2
)
,AttributNames AS
(
    SELECT Nmbr,@XML1.value('local-name((*/@*[sql:column("Nmbr")])[1])', 'varchar(max)') AS AttributName
    FROM CteTally
)
SELECT
(
    SELECT '' + CASE WHEN @XML1.value('(*/@*[fn:local-name()=sql:column("AttributName")])[1]','varchar(max)')
                          <> @XML2.value('(*/@*[fn:local-name()=sql:column("AttributName")])[1]','varchar(max)') 
                     THEN AttributName + ': ' + @XML2.value('(*/@*[fn:local-name()=sql:column("AttributName")])[1]','varchar(max)') + ', ' ELSE '' END 
    FROM AttributNames
    FOR XML PATH('') 
)

结果:

name: john, job: teacher,