スクリプトを実行してXML列を更新しようとしています。
UPDATE DataImpTable
SET serviceData.modify('replace value of (/SMObjInfo/CentralData/SMData/CentralSDItem/ControlData/text())[1] with "9876"')
WHERE identifier=5
<SMObjInfo xmlns="DataService/1.0.0.0" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<CentralData>
<SMData>
<CentralSDItem>
<ControlData>1234</ControlData>
</CentralSDItem>
</SMData>
</CentralData>
</SMObjInfo>
ControlData
の値を9876に変更しますが、/SMObjInfo/CentralData/SMData/CentralSDItem/ControlData
値のXMLで値が変更されていないようです。
型付きXMLと型なしXMLは関係ありますか?
modify
関数で名前空間を宣言する必要があります。
このようなもの:
DECLARE @xml xml = N'<SMObjInfo xmlns="DataService/1.0.0.0" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<CentralData>
<SMData>
<CentralSDItem>
<ControlData>1234</ControlData>
</CentralSDItem>
</SMData>
</CentralData>
</SMObjInfo>';
SET @xml.modify('
declare default element namespace "DataService/1.0.0.0";
replace value of (/SMObjInfo/CentralData/SMData/CentralSDItem/ControlData/text())[1]
with "6789"
');
PRINT CONVERT(nvarchar(max), @xml);
元のxmlフラグメントで、使用されない次の名前空間を宣言しています。
xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
実際のxmlドキュメントがこの名前空間を使用していて、それらの要素を変更する場合は、次の宣言を@xml.modify
関数に追加する必要があります。
declare namespace i="http://www.w3.org/2001/XMLSchema-instance";
結果(読みやすいようにフォーマットされています):
<SMObjInfo xmlns="DataService/1.0.0.0" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<CentralData>
<SMData>
<CentralSDItem>
<ControlData>6789</ControlData>
</CentralSDItem>
</SMData>
</CentralData>
</SMObjInfo>
SQLServerScience.com で、modify関数に関するブログ記事をいくつかの例とともに書きました。
テーブルにXMLがある場合は、SETの代わりにUPDATEを使用する必要があり、 WITH XMLNAMESPACES を使用してXML_DML式の外に名前空間宣言を置くことができます。
with xmlnamespaces(default 'DataService/1.0.0.0')
update DataImpTable
set serviceData.modify('replace value of (/SMObjInfo/CentralData/SMData/CentralSDItem
/ControlData/text())[1] with "9876"')
where identifier=5