از SQL server 2005 به بعد، پشتيباني كاملي از XML توسط اين محصول صورت ميگيرد. در ادامه مروري خواهيم داشت بر نحوهي به روز رساني مقادير فيلدهايي از نوع XML در SQL Server .
در ابتدا جدول موقتي زير را كه شامل يك ركورد از نوع XML است، در نظر بگيريد:
DECLARE @tblTest AS TABLE (xmlField XML)
INSERT INTO @tblTest
(
xmlField
)
VALUES
(
'<Sample>
<Node1>Value1</Node1>
<Node2>Value2</Node2>
<Node3>OldValue</Node3>
</Sample>'
)
سعي اول:
DECLARE @newValue VARCHAR(50)
SELECT @newValue = 'NewValue'
UPDATE @tblTest
SET xmlField.modify('replace value of (/Sample/Node3)[1] with ' + @newValue)
The argument 1 of the XML data type method "modify" must be a string literal.
سعي دوم:
DECLARE @newValue VARCHAR(50)
SELECT @newValue = 'NewValue'
UPDATE @tblTest
SET xmlField.modify(
'replace value of (/Sample/Node3)[1] with sql:variable("@newValue")'
)
XQuery [@tblTest.xmlField.modify()]: The target of 'replace value of' must be a non-metadata attribute or an element with simple typed content, found 'element(NodeThree,xdt:untyped) ?'
سعي سوم:
DECLARE @newValue VARCHAR(50)
SELECT @newValue = 'NewValue'
UPDATE @tblTest
SET xmlField.modify(
'replace value of (/Sample/Node3/text())[1]
with sql:variable("@newValue")'
)
SELECT xmlField.value('(/Sample/Node3)[1]','varchar(50)') FROM @tblTest
و بله. كار ميكنه!
XML ايي را كه در ابتدا استفاده كرديم از نوع un-typed XML محسوب شده و هيچ schema ايي را براي آن در نظر نگرفتهايم، به همين جهت بايد دقيقا مشخص كنيم كه قصد داريم text اين node را ويرايش نمائيم.
مشكل بعدي!
در ابتدا مثال زير را در نظر بگيريد:
DECLARE @tblTest AS TABLE (xmlField XML)
INSERT INTO @tblTest
(
xmlField
)
VALUES
(
'<Sample>
<Node1>Value1</Node1>
<Node2>Value2</Node2>
<Node3></Node3>
</Sample>'
)
DECLARE @newValue VARCHAR(50)
SELECT @newValue = 'NewValue'
UPDATE @tblTest
SET xmlField.modify(
'replace value of (/Sample/Node3/text())[1]
with sql:variable("@newValue")'
)
SELECT xmlField.value('(/Sample/Node3)[1]','varchar(50)') FROM @tblTest
اين عبارات T-SQL ، خلاصه بحث ما تا به اينجا هستند اما با يك تفاوت. نود 3 در اينجا خالي است.
اگر اسكريپت را اجرا كنيد، هيچ تغييري را مشاهده نخواهيد كرد. به عبارت ديگر به روز رساني صورت نميگيرد. در اينجا چون text اين نود خالي است ، فرض SQL Server بر اين خواهد بود كه وجود ندارد، بنابراين اين نود را به روز رساني نخواهد كرد. به همين منظور بايد براي به روز رساني اين نود، عبارت جديد را در جايي كه text ندارد insert كرد (و نه replace).
DECLARE @newValue VARCHAR(50)
SELECT @newValue = 'NewValue'
UPDATE @tblTest
SET xmlField.modify(
'replace value of (/Sample/Node3/text())[1]
with sql:variable("@newValue")'
)
UPDATE @tblTest
SET xmlField.modify(
'insert text{sql:variable("@newValue")} into
(/Sample/Node3)[1] [not(text())]'
)
SELECT xmlField.value('(/Sample/Node3)[1]','varchar(50)') FROM @tblTest