2011-08-11 16 views
0

特定のテーブルの1つのXMLノードで、プラス記号をアンダースコアに置き換えたいとします。 例:以下の入力では、ファイルパスノードとファイル名ノードではプラスシンボルを置き換えたいとします。 テーブルの列データ型はXMLであり、varcharではありません。T-SQL XMLデータ型列の1つのXMLノード値のシンボルまたは文字を置き換えるクエリ?

入力:

<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> 
+0

@Mitch Wheat @Mitch Wheat xmlファイルパスノードは、さまざまな欠点を抱えて複数回あります。私はそれらのすべてを更新するクエリを把握することができません – DotNetDeveloper

+0

@Mitch Wheat私はすべて設定されており、XML内の異なるxpathsをサポートするために、同じ更新ステートメントをスクリプトに3回貼り付けました。 – DotNetDeveloper

答えて

4
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)  

編集

上記テーブル変数@Tではなく、あなたのテーブルです。テーブルの名前がYourTableで、IDの列とXMLColの列があるとします。 ID編集.modify()と一度に複数のノードを更新することはできません

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 

です更新ステートメントは、XMLを変更するには、このようになります。これをループで行う必要があります。以下のスクリプトは、@Tをテストテーブルとして使用しています。あなたはあなたのテーブルが呼び出されているもので置き換える必要があります。 @TにはIDの列があり、このスクリプトでは、一度に1つの行のみを更新し、その行のIDを知っていることを前提としています。コードには、私が何をしているのかを説明するコメントがいくつかあります。私が何かを明確にすべきかどうか尋ねることをためらってください。

-- 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

+1をvarchar(最大)にキャストすることで「不正行為」しないようにしてください! –

+0

@Mikael Eriksson ..私は100万レコードしかないので、混乱しています。問題は少ないレコードしかないので、where節なしでレコードを更新するにはどうしたらいいですか?あなたは簡単に理解するためにテーブルと列がupdate table_name set column_name = '_'などのようにデータベースに既に存在するかのように構文を書いてください。 – DotNetDeveloper

+1

Mikaelのコードは基本的に次のようにしています: 'UPDATE TABLE set filepath = REPLACE(filepath、 '+ '、' _ ') 'それはXMLでも違った働きをします。 XMLメソッドは多くのtsqlを許可していないので、基本的にその値を列として公開する(クロス適用)、置換を実行するTSQL関数を適用して、古い値を新しい値に置き換えるクエリに参加していますxmlCol.modify())。 –

関連する問題