Finding the differences only between 2 strings in SQL

二次信任 提交于 2019-12-25 06:39:10

问题


I must compare 2 xml strings(varchar(max) in sql) like these ones:

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

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

And the result must be the differences only, which means, ill get 2 strings, the first one will me the original values, and the second one will be the new values. However if there are no differences then there will be an empty string, in this case for example:

output 1: 'name="Bob", job="student"'

output 2: 'name="john", job="teacher"'

As you see, we didn't get the id string attached because there wasn't any change, so naturally, no changes means no string to return.


回答1:


Here is a generic approach up to 100 Attributs:

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('') 
)

Result:

name: john, job: teacher, 



回答2:


Something like this?

Paste this into an empty query window and execute. Adapt to your needs:

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

Result

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


来源:https://stackoverflow.com/questions/33377196/finding-the-differences-only-between-2-strings-in-sql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!