在xmls到table-SQL之间插入Delta

时间:2013-05-22 07:16:47

标签: sql sql-server xml

我有2个xmls赞(标签是动态的):

Declare @OldXml xml = <Data><testId>BE7F2CDE-0D31-4E47-AA07-CE179F1E47C2</testId><description>Test1</description><Name>aaaa</Name><createdBy>1111</createdBy><updatedBy>1111</updatedBy></Data>

Declare @NewXml xml = '<Data><testId>BE7F2CDE-0D31-4E47-AA07-CE179F1E47C2</testId><description>Test2</description><Name>bbbb</Name><createdBy>1111</createdBy><updatedBy>2222</updatedBy></Data>'

我想将它们之间的区别输入到另一个表格中:

  entity                                        Field              OldValue      NewValue  
  -----------------------------------------------------------------------------------------
  BE7F2CDE-0D31-4E47-AA07-CE179F1E47C2        description           Test1         Test2  
  BE7F2CDE-0D31-4E47-AA07-CE179F1E47C2           Name                aaaa          bbbb

我该怎么做?

嗨,经过长时间的搜索,我找到了答案

 SELECT DISTINCT
    foo.bar.value('local-name(.)','VARCHAR(14)') as FieldName,  
    foo.bar.value('./.','VARCHAR(14)')  as OldValue ,
    foo1.bar1.value('./.','VARCHAR(14)')  as NewValue ,
    FROM
    @OldXml.nodes('/Data/*') AS foo(bar) 
    INNER JOIN @NewXml.nodes('/Data/*') AS foo1(bar1) ON foo.bar.value('local-name(.)','VARCHAR(14)') = foo1.bar1.value('local-name(.)','VARCHAR(14)')
                                                                                                        AND foo.bar.value('./.','VARCHAR(14)') <> foo1.bar1.value('./.','VARCHAR(14)')

我将单独获得实体。
谢谢大家

2 个答案:

答案 0 :(得分:1)

SQL Fiddle

declare @OldXml xml = '
<Data>
  <testId>BE7F2CDE-0D31-4E47-AA07-CE179F1E47C2</testId>
  <description>Test1</description>
  <Name>aaaa</Name>
  <createdBy>1111</createdBy>
  <updatedBy>1111</updatedBy>
</Data>
'
declare @NewXml XML = '
<Data>
  <testId>BE7F2CDE-0D31-4E47-AA07-CE179F1E47C2</testId>
  <description>Test2</description>
  <Name>bbbb</Name>
  <createdBy>1111</createdBy>
  <updatedBy>2222</updatedBy>
</Data>'

select @OldXml.value('(Data/testId/text())[1]', 'uniqueidentifier') as entity,
       T.Field,
       @OldXml.value('(/Data/*[local-name(.) = sql:column("T.Field")]/text())[1]', 'nvarchar(max)') as OldValue,
       @NewXml.value('(/Data/*[local-name(.) = sql:column("T.Field")]/text())[1]', 'nvarchar(max)') as NewValue
from (
     select T.X.value('local-name(.)', 'nvarchar(max)') as Field
     from @OldXml.nodes('/Data/*') as T(X)
     ) as T

<强> Results

|                               ENTITY |       FIELD |                             OLDVALUE |                             NEWVALUE |
------------------------------------------------------------------------------------------------------------------------------------
| BE7F2CDE-0D31-4E47-AA07-CE179F1E47C2 |      testId | BE7F2CDE-0D31-4E47-AA07-CE179F1E47C2 | BE7F2CDE-0D31-4E47-AA07-CE179F1E47C2 |
| BE7F2CDE-0D31-4E47-AA07-CE179F1E47C2 | description |                                Test1 |                                Test2 |
| BE7F2CDE-0D31-4E47-AA07-CE179F1E47C2 |        Name |                                 aaaa |                                 bbbb |
| BE7F2CDE-0D31-4E47-AA07-CE179F1E47C2 |   createdBy |                                 1111 |                                 1111 |
| BE7F2CDE-0D31-4E47-AA07-CE179F1E47C2 |   updatedBy |                                 1111 |                                 2222 |

答案 1 :(得分:0)

试试这个 -

DECLARE 
      @OldXml XML = '<Data><testId>BE7F2CDE-0D31-4E47-AA07-CE179F1E47C2</testId><description>Test1</description><Name>aaaa</Name><createdBy>1111</createdBy><updatedBy>1111</updatedBy></Data>'
    , @NewXml XML = '<Data><testId>BE7F2CDE-0D31-4E47-AA07-CE179F1E47C2</testId><description>Test2</description><Name>bbbb</Name><createdBy>1111</createdBy><updatedBy>2222</updatedBy></Data>'

SELECT id = 'NEW'
      , testId = t.c.value('(./testId)[1]', 'UNIQUEIDENTIFIER')
      , [description] = t.c.value('(./description)[1]', 'NVARCHAR(100)')
      , createdBy = t.c.value('(./createdBy)[1]', 'INT')
      , updatedBy = t.c.value('(./updatedBy)[1]', 'INT')
FROM @NewXml.nodes('/Data') t(c)

UNION ALL

SELECT id = 'OLD'
    , t.c.value('(./testId)[1]', 'UNIQUEIDENTIFIER')
    , t.c.value('(./description)[1]', 'NVARCHAR(100)')
    , t.c.value('(./createdBy)[1]', 'INT')
    , t.c.value('(./updatedBy)[1]', 'INT')
FROM @OldXml.nodes('/Data') t(c)