开发者

T-SQL Query to replace a symbol or character in one xml node value of XML data type column?

开发者 https://www.devze.com 2023-03-27 23:37 出处:网络
I want to replace plus symbol with underscore in the one xml node of a particular table. Example: In the below input, i want to replace plus symbol only in filepath node and NOT filename node.

I want to replace plus symbol with underscore in the one xml node of a particular table. Example: In the below input, i want to replace plus symbol only in filepath node and NOT filename node. Table column data type is XML and 开发者_StackOverflow中文版NOT varchar.

Input:

 <mediadata>
  <image>
    <FileName>BUF2011-450</FileName>
    <FilePath>/uploadedImages/Products/Indoor_Fun/Puzzles___Brain_Teasers/Puzzles/2000+_Pieces/BUF2011-450.jpg</FilePath>
    <Thumbnails>
      <Thumbnail>
        <FileName>BUF2011-450</FileName>
        <FilePath>/uploadedImages/Products/Indoor_Fun/Puzzles___Brain_Teasers/Puzzles/2000+_Pieces/thumb_BUF2011-450_Large.jpg</FilePath>
      </Thumbnail>
      <Thumbnail>
        <FileName>BUF2011-450</FileName>
        <FilePath>/uploadedImages/Products/Indoor_Fun/Puzzles___Brain_Teasers/Puzzles/2000+_Pieces/thumb_BUF2011-450_Small.jpg</FilePath>
      </Thumbnail>
    </Thumbnails>
  </image>
</mediadata>


declare @T table(XMLCol xml)

insert into @T values
('<image>
    <FileName>Tim+bottom</FileName>
    <FilePath>/Top+Bottom/AFX8995+450.jpg</FilePath>
  </image>')

update T set
  XMLCol.modify('replace value of (/image/FilePath[1]/text())[1] 
                 with sql:column("T2.FilePath")')
from @T as T
  cross apply (select replace(XMLCol.value('(/image/FilePath)[1]', 
                                           'varchar(100)'), 
                              '+', 
                              '_')
              ) as T2(FilePath)      

Edit

The table variable @T above is instead of your table. Assume that your table is named YourTable and you have one ID column and XMLCol column. The update statement could look like this to change the XML where ID is 1.

update T set
  XMLCol.modify('replace value of (/image/FilePath[1]/text())[1] 
                 with sql:column("T2.FilePath")')
from YourTable as T
  cross apply (select replace(XMLCol.value('(/image/FilePath)[1]', 
                                           'varchar(100)'), 
                              '+', 
                              '_')
              ) as T2(FilePath)      
where T.ID = 1

Edit

It is not possible to update more than one node at a time with .modify(). You have to do this in a loop. The script below uses @T as a test table. You should replace that with whatever your table is called. @T has an ID column and the script assumes that you only update one row at a time and that you know the ID for that row. There are some comments in the code that explains what I do. Don't hesitate to ask if there are something I should make clearer.

-- Test table
declare @T table(ID int, XMLCol xml)

-- Sample data
insert into @T values
(1,
 '<mediadata>
    <image>
      <FileName>BUF2011-450</FileName>
      <FilePath>1/uploadedImages/Products/Indoor_Fun/Puzzles___Brain_Teasers/Puzzles/2000+_Pieces/BUF2011-450.jpg</FilePath>
      <Thumbnails>
        <Thumbnail>
          <FileName>BUF2011-450</FileName>
          <FilePath>2/uploadedImages/Products/Indoor_Fun/Puzzles___Brain_Teasers/Puzzles/2000+_Pieces/thumb_BUF2011-450_Large.jpg</FilePath>
        </Thumbnail>
        <Thumbnail>
          <FileName>BUF2011-450</FileName>
          <FilePath>3/uploadedImages/Products/Indoor_Fun/Puzzles___Brain_Teasers/Puzzles/2000+_Pieces/thumb_BUF2011-450_Small.jpg</FilePath>
        </Thumbnail>
      </Thumbnails>
    </image>
  </mediadata>
')

-- ID for the row you need to update
declare @ID int
set @ID = 1

-- Loop variable, node to update
declare @Pos int
set @Pos = 1

-- The number of nodes to update
declare @Count int

-- Get the number of FilePath nodes
select @Count = XMLCol.query('count(//FilePath)').value('.', 'int')
from @T
where ID = @ID

while @Pos <= @Count
begin
  update T set
    XMLCol.modify('replace value of ((//FilePath)[sql:variable("@Pos")]/text())[1] 
                   with sql:column("T2.FilePath")')
  from @T as T
    cross apply (select replace(T.XMLCol.
                                  query('(//FilePath)[sql:variable("@Pos")]').
                                  value('.', 'varchar(100)'), 
                                '+', 
                                '_')
                ) as T2(FilePath)      
  where T.ID = @ID                 

  set @Pos += 1            
end
0

精彩评论

暂无评论...
验证码 换一张
取 消