2016-04-06 64 views
3

更新XML可變我的XML看起來像FF:循環直通X​​ML,然後在SQL

<root> 
    <TemplateQuestion> 
    <Row rfqID="1" rftID="1" questionDesc="Question 1" responseType="1" rfqDisplayOrder="1" deletedBit="0" /> 
    <Row rfqID="2" rftID="1" questionDesc="Question 2" responseType="2" rfqDisplayOrder="2" deletedBit="0" /> 
    <Row rfqID="3" rftID="1" questionDesc="Question 3" responseType="3" rfqDisplayOrder="3" deletedBit="0" /> 
    </TemplateQuestion> 
</root> 

現在我的目標是使rfqID它面前有字母「Q」。所以結果應該像FF:

<root> 
    <TemplateQuestion> 
    <Row rfqID="q1" rftID="1" questionDesc="Question 1" responseType="1" rfqDisplayOrder="1" deletedBit="0" /> 
    <Row rfqID="q2" rftID="1" questionDesc="Question 2" responseType="2" rfqDisplayOrder="2" deletedBit="0" /> 
    <Row rfqID="q3" rftID="1" questionDesc="Question 3" responseType="3" rfqDisplayOrder="3" deletedBit="0" /> 
    </TemplateQuestion> 
</root> 

我實現,通過這樣做:

declare @xml XML 
    set @xml = (select dbo.udfGetXMLVal(1)) 

    declare @nodeCount int 
    declare @i int 
    declare @qid nvarchar(20) 

    set @i = 1 
    select @nodeCount = @xml.value('count(/root/TemplateQuestion/Row/@rfqID)','int') 
    while(@i <= @nodeCount) 
    begin 
    select @qid = x.value('@rfqID[1]', 'VARCHAR(20)') 
    from @xml.nodes('/root/TemplateQuestion/Row[position()=sql:variable("@i")]') e(x) 
    set @qid = 'q' + @qid 
    select @qid 

    Set @xml.modify('replace value of (/root/TemplateQuestion/Row/@rfqID)[1] with sql:variable("@qid")') 

    set @i = @i + 1 
end 

林有這個線路問題:

Set @xml.modify('replace value of (/root/TemplateQuestion/Row/@rfqID)[1] with sql:variable("@qid")') 

我怎樣才能更換[1]給變量@i?當我嘗試使用sql:variable時,我得到了一些字符串文字的錯誤。

任何幫助你可以提供將不勝感激。謝謝

+0

哪個DBMS是什麼? – jarlh

+0

sql server 2012 – ifallelsefailthenstackoverflow

+0

嗨Aedz Migraso。你完全接受har07的回答,因爲它完全回答了你的問題。我只想給你一些小問題以避免將來的問題:避免循環(谷歌關於RBAR,程序思維和基於行/集的思考)! – Shnugo

回答

3

「我怎麼能代替[1]給變量@i我得到一些當我嘗試使用字符串文字時出錯sql:variable

你可以做這樣的(測試和SQL Server 2008R2作品):

Set @xml.modify(' 
    replace value of ((/root/TemplateQuestion/Row/@rfqID)[sql:variable("@i")])[1] 
    with sql:variable("@qid") 
') 
3

快速和骯髒的:-)

SELECT CAST(REPLACE(CAST(@x AS VARCHAR(MAX)),' rftID="',' rftID="q') AS XML); 

而這裏的清潔方法:

DECLARE @x XML='<root> 
    <TemplateQuestion> 
    <Row rfqID="1" rftID="1" questionDesc="Question 1" responseType="1" rfqDisplayOrder="1" deletedBit="0" /> 
    <Row rfqID="2" rftID="1" questionDesc="Question 2" responseType="2" rfqDisplayOrder="2" deletedBit="0" /> 
    <Row rfqID="3" rftID="1" questionDesc="Question 3" responseType="3" rfqDisplayOrder="3" deletedBit="0" /> 
    </TemplateQuestion> 
</root>'; 

SELECT 
(
    SELECT 'q' + R.value('@rfqID','varchar(max)') AS [@rfqID] 
      ,R.value('@rftID','int') AS [@rftID] 
      ,R.value('@questionDesc','varchar(max)') AS [@questionDesc] 
      --other attributes similar  
    FROM @x.nodes('/root/TemplateQuestion/Row') AS A(R) 
    FOR XML PATH('Row'),ROOT('TemplateQuestion'),TYPE 
) 
FOR XML PATH('root');