2016-04-06 2 views
3

Мой XML выглядит как фф:Looping через XML, то обновление переменной XML в 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» перед ним. Таким образом, результаты должны быть как ФФ:

<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 

Im возникли проблемы с этой линии:

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

Как я могу заменить [1] к переменной @i? Я получаю некоторую ошибку со строковыми литералами, когда пытаюсь использовать переменную sql:.

Любая помощь, которую вы могли бы предоставить, была бы весьма признательна. Спасибо

+0

Какой DBMS это? – jarlh

+0

sql server 2012 – ifallelsefailthenstackoverflow

+0

Hi Aedz Migraso. Совершенно нормально, что вы приняли ответ har07, поскольку он точно ответил на ваш вопрос. Есть только один крошечный намек, который я хотел бы рассказать вам о будущих проблемах: избегать циклов (google о 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');