Sql server 2005 在SQL Server中使用XQuery比较两组XML数据
假设我将员工数据存储在日志表的Sql server 2005 在SQL Server中使用XQuery比较两组XML数据,sql-server-2005,tsql,xquery-sql,Sql Server 2005,Tsql,Xquery Sql,假设我将员工数据存储在日志表的xml列中。有时,存储过程中的xml列中的数据也会更新 下面是示例 DECLARE @XML1 XML DECLARE @XML2 XML SET @XML1 = '<NewDataSet> <Employee> <EmpID>1005</EmpID> <Name> keith </Name> <DOB>12/02/1981</DOB> <DeptID>
xml
列中。有时,存储过程中的xml
列中的数据也会更新
下面是示例
DECLARE @XML1 XML
DECLARE @XML2 XML
SET @XML1 =
'<NewDataSet>
<Employee>
<EmpID>1005</EmpID>
<Name> keith </Name>
<DOB>12/02/1981</DOB>
<DeptID>ACC001</DeptID>
<Salary>10,500</Salary>
</Employee>
</NewDataSet>'
SET @XML2 =
'<NewDataSet>
<Employee>
<EmpID>1006</EmpID>
<Name> keith </Name>
<DOB>05/02/1981</DOB>
<DeptID>ACC002</DeptID>
<Salary>10,900</Salary>
</Employee>
</NewDataSet>'
我只需要像上面那样展示差异。因此,请指导我如何使用XQuery比较两个xml数据,并在SQL Server中仅以上述方式显示差异。请用代码片段指导我。谢谢我没有您想要的确切输出-但至少您可以很好地比较新旧值:
;WITH OldData AS
(
SELECT
@XML1.value('(/NewDataSet/Employee/EmpID)[1]', 'int') AS 'EmpID',
@XML1.value('(/NewDataSet/Employee/Name)[1]', 'varchar(50)') AS 'Name',
@XML1.value('(/NewDataSet/Employee/DOB)[1]', 'datetime') AS 'DOB',
@XML1.value('(/NewDataSet/Employee/DeptID)[1]', 'varchar(50)') AS 'DeptID',
@XML1.value('(/NewDataSet/Employee/Salary)[1]', 'varchar(25)') AS 'Salary'
),
NewData AS
(
SELECT
@XML2.value('(/NewDataSet/Employee/EmpID)[1]', 'int') AS 'EmpID',
@XML2.value('(/NewDataSet/Employee/Name)[1]', 'varchar(50)') AS 'Name',
@XML2.value('(/NewDataSet/Employee/DOB)[1]', 'datetime') AS 'DOB',
@XML2.value('(/NewDataSet/Employee/DeptID)[1]', 'varchar(50)') AS 'DeptID',
@XML2.value('(/NewDataSet/Employee/Salary)[1]', 'varchar(25)') AS 'Salary'
)
SELECT
'Old values', od.*
FROM OldData od
UNION
SELECT 'New values', nd.*
FROM NewData nd
为您提供以下输出:
EmpID Name DOB DeptID Salary
Old values 1005 keith 1981-12-02 00:00:00.000 ACC001 10,500
New values 1006 keith 1981-05-02 00:00:00.000 ACC002 10,900
SQL Server非常适合存储和操作数据,但这样的演示应该在前端应用程序(如ASP.NET应用程序)中完成,而不是在T-SQL中完成…我来晚了!!!但是,我发现,如果如上所示的EmployeesXML有多条记录,那么使用CTE的JOIN查询将返回不正确的结果
;with XML1 as
(
select T.N.value('local-name(.)', 'nvarchar(100)') as NodeName,
T.N.value('.', 'nvarchar(100)') as Value
from @XML1.nodes('/NewDataSet/Employee/*') as T(N)
),
XML2 as
(
select T.N.value('local-name(.)', 'nvarchar(100)') as NodeName,
T.N.value('.', 'nvarchar(100)') as Value
from @XML2.nodes('/NewDataSet/Employee/*') as T(N)
)
select coalesce(XML1.NodeName, XML2.NodeName) as NodeName,
XML1.Value as Value1,
XML2.Value as Value2
from XML1
full outer join XML2
on XML1.NodeName = XML2.NodeName
where coalesce(XML1.Value, '') <> coalesce(XML2.Value, '')
我有下面的XML输入
DECLARE @XML1 XML
DECLARE @XML2 XML
SET @XML1 =
'<NewDataSet>
<Employees>
<Employee>
<Name> keith </Name>
<EmpID> 1005 </EmpID>
<DOB>12/02/1981</DOB>
<DeptID>ACC001</DeptID>
<Salary>10,500</Salary>
</Employee>
<Employee>
<Name> keith </Name>
<EmpID> 1004 </EmpID>
<DOB>12/02/1981</DOB>
<DeptID>ACC001</DeptID>
<Salary>10,500</Salary>
</Employee>
</Employees>
</NewDataSet>'
SET @XML2 =
'<NewDataSet>
<Employees>
<Employee>
<Name> keith </Name>
<EmpID> 1005 </EmpID>
<DOB>12/02/1981</DOB>
<DeptID>ACC001</DeptID>
<Salary>10,500</Salary>
</Employee>
<Employee>
<Name> keith </Name>
<EmpID> 1004 </EmpID>
<DOB>12/02/1981</DOB>
<DeptID>ACC001</DeptID>
<Salary>10,501</Salary>
</Employee>
<Employee>
<Name> keith1 </Name>
<EmpID> 10040 </EmpID>
<DOB>12/02/1981</DOB>
<DeptID>ACC001</DeptID>
<Salary>10,501</Salary>
</Employee>
</Employees>
</NewDataSet>'
希望这有帮助 你的努力很好,但是你硬编码了我不想要的域名。感谢+1出色的工作-我一直在研究如何实现这一点,只是没有看到树木的森林!在你的代码中改变什么来显示数据marc_的数据是如何显示的,但我不想像marc_那样硬编码字段名。你能帮忙吗。感谢您需要使用pivot,当您需要可变的列数时,您需要动态地使用pivot。看看这里的动态轴心。将此查询的结果存储在一个表变量中,然后对该表变量执行文章中的动态透视操作。@Mikael“T.N.”内容从何而来?@Question\u Guy节点函数将XML分解到一个表中
T
是表别名,N
是列名从@XML1.nodes('/NewDataSet/Employee/*')作为T(N)`不必T(N)
,您可以决定要使用的别名和列名。
NodeName Value1 Value2
-------------------- -------------------- --------------------
EmpID 1005 1006
DOB 12/02/1981 05/02/1981
DeptID ACC001 ACC002
Salary 10,500 10,900
DECLARE @XML1 XML
DECLARE @XML2 XML
SET @XML1 =
'<NewDataSet>
<Employees>
<Employee>
<Name> keith </Name>
<EmpID> 1005 </EmpID>
<DOB>12/02/1981</DOB>
<DeptID>ACC001</DeptID>
<Salary>10,500</Salary>
</Employee>
<Employee>
<Name> keith </Name>
<EmpID> 1004 </EmpID>
<DOB>12/02/1981</DOB>
<DeptID>ACC001</DeptID>
<Salary>10,500</Salary>
</Employee>
</Employees>
</NewDataSet>'
SET @XML2 =
'<NewDataSet>
<Employees>
<Employee>
<Name> keith </Name>
<EmpID> 1005 </EmpID>
<DOB>12/02/1981</DOB>
<DeptID>ACC001</DeptID>
<Salary>10,500</Salary>
</Employee>
<Employee>
<Name> keith </Name>
<EmpID> 1004 </EmpID>
<DOB>12/02/1981</DOB>
<DeptID>ACC001</DeptID>
<Salary>10,501</Salary>
</Employee>
<Employee>
<Name> keith1 </Name>
<EmpID> 10040 </EmpID>
<DOB>12/02/1981</DOB>
<DeptID>ACC001</DeptID>
<Salary>10,501</Salary>
</Employee>
</Employees>
</NewDataSet>'
select T.N.value('local-name(.)', 'nvarchar(100)') as NodeName,
T.N.value('.', 'nvarchar(100)') as Value
from @XML2.nodes('/NewDataSet/Employees/Employee/*') as T(N)
EXCEPT
select T.N.value('local-name(.)', 'nvarchar(100)') as NodeName,
T.N.value('.', 'nvarchar(100)') as Value
from @XML1.nodes('/NewDataSet/Employees/Employee/*') as T(N)