2012-09-04 17 views
3

我在SQL Server 2008中有一個表,它將XML數據存儲在XML列中。一個典型的XML片段是:SQL - 使用INNER JOIN獲取XML,修改XML

<validation> 
    <Field1 author="56234" date="20120101" /> 
    <Field2 author="23232" date="20120101" /> 
     [...etc...] 
</validation> 

我正在試圖找出 - 我看不出怎麼辦呢 - 是與內選擇這個數據JOIN到另一個表並修改XML數據在結果集中,即,讓我得到這個:

<validation> 
    <Field1 author="56234" date="20120101" authorFullName="Bob Smith" /> 
    <Field2 author="23232" date="20120101" authorFullName="Jane Hill" /> 
     [...etc...] 
</validation> 

現在我知道我可以做一個CROSS APPLY將XML數據直接拉入一個記錄和內部聯接 - 例如使用:

select xmldata.a, people.personname 
    from xmldata 
     cross apply xmldata.x.nodes('/validation/node()') vdata(fielddata) 
     inner join people 
      on people.personid = vdata.fielddata.value('@author','NVARCHAR(20)') 

但我真的在做什麼lly想要做的是返回原始的XML,但添加了一個新屬性,將people.PersonName映射到新的@authorFullName屬性中。

我不能完全弄清楚語法(或者即使它確實有可能)。我假設我最好cross applymodifyinsert attribute - 基於

select xmldata.a, xmldata.x 
    from xmldata 
     cross apply xmldata.x.modify('insert attribute authorFullName {sql:column("people.personfullname")} into /validation/node()') 
     inner join people 
      on people.personid = [...what goes here?...] 

,但得到的語法權逃脫我的東西。我越來越認爲這是不可能的,而且我最好在兩個查詢中完成這項工作,並將結果合併到非SQL業務邏輯中。

回答

1

您不能在select語句中使用modify

modify() Method (xml Data Type)

只能UPDATE語句的SET 子句中使用的XML數據類型的修改()方法。

我想你有兩個選擇。

  1. 撕碎XML並使用for xml path以您想要的方式重建XML文檔,並在適當位置插入人名。
  2. 將XML解壓縮爲變量並使用set @XML.modify(insert...來插入人員名稱。

如果您選擇第二個選項,則必須使用while循環,因爲insert (XML DML)中的expression2必須是單個節點。

選項2的代碼可能看起來像這樣。

declare @XML xml 
declare @C int 
declare @PersonName varchar(50) 
declare @PersonID int 

-- Store your XML in a XML variable 
set @XML = 
'<validation> 
    <Field1 author="56234" date="20120101" /> 
    <Field2 author="23232" date="20120101" /> 
</validation>' 

-- Get number of nodes to be modified 
set @C = @XML.value('count(/validation/*)', 'int') 

-- For each node 
while @C > 0 
begin 
    -- Get person id from XML 
    set @PersonID = @XML.value('(/validation/*[sql:variable("@C")]/@author)[1]', 'int') 

    -- Get person name 
    select @PersonName = personname 
    from people 
    where personid = @PersonID 

    if @@rowcount = 1 
    begin 
    -- add person name to XML 
    set @XML.modify('insert attribute authorFullName {sql:variable("@PersonName")} 
         into (/validation/*[sql:variable("@C")])[1]') 
    end 

    -- next node 
    set @C = @C - 1 
end 
+0

我設法在文檔中錯過了。顯然很多時間盯着他們。儘管在處理XML方面,考慮到在SQL層面涉及的工作,我可能會更好地將單獨的數據集拉回到業務代碼中並在那裏合併。感謝您的反饋,雖然...! –