仅查找 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,
我必须比较 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,