June 19, 2018 at 12:49 pm
----I have the following xml structure
----I need to replace the entire <select> node IN @option_xml
----with entirely new values for each child node within it by matching on bn_id value FROM TABLE @opt_xml
----Prepopulate table
DECLARE @opt_xml TABLE (bn_id INT, select_t varchar(max), select_k varchar(max))
INSERT INTO @opt_xml (bn_id , select_t , select_k)
SELECT 11,'L','T'
UNION
SELECT 12,'X','M'
SELECT * FROM @opt_xml
DECLARE @option_xml XML='<bd>
<cat>
<grp>
<ben>
<bn_id>11</bn_id>
<select>
<select_t />
<select_k>F</select_k>
</select>
</ben>
<ben>
<bn_id>12</bn_id>
<select>
<select_t>G</select_t>
<select_k>F</select_k>
</select>
</ben>
</grp>
</cat>
</bd>'
SELECT @option_xml AS BEFORE
DECLARE @bn_id INT ,@select_t xml, @select_k xml
DECLARE db_cursor CURSOR FOR
SELECT bn_id, CONVERT(XML,(SELECT ISNULL(select_t,''))), CONVERT(XML,(SELECT ISNULL(select_k,''))) FROM @opt_xml
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @bn_id ,@select_t , @select_k
WHILE @@FETCH_STATUS = 0
BEGIN
--Try to delete each child attribute/node and add it back
SET @option_xml.modify( 'delete (/bd/cat/grp/ben/select/select_t)' )
--Add a new attribute/node based on @bn_id
SET @option_xml.modify('insert sql:variable("@select_t")
after (/bd/cat/grp/ben/select/select_t/text()[. >> (/bd/cat/grp/ben/ben_id[.=sql:variable("@bn_id")])[1]])[1]')
FETCH NEXT FROM db_cursor INTO @bn_id ,@select_t , @select_k
END
CLOSE db_cursor;
DEALLOCATE db_cursor;
SELECT @option_xml AS AFTER
----THE END RESULTS SHOULD BE
'<bd>
<cat>
<grp>
<ben>
<bn_id>11</bn_id>
<select>
<select_t>L</select_t>
<select_k>T</select_k>
</select>
</ben>
<ben>
<bn_id>12</bn_id>
<select>
<select_t>X</select_t>
<select_k>M</select_k>
</select>
</ben>
</grp>
</cat>
</bd>'
June 20, 2018 at 1:47 am
The XML DML is a little cumbersome but this examples should get you going
Before<bd>
<cat>
<grp>
<ben>
<bn_id>11</bn_id>
<select>
<select_t />
<select_k>F</select_k>
</select>
</ben>
<ben>
<bn_id>12</bn_id>
<select>
<select_t>G</select_t>
<select_k>F</select_k>
</select>
</ben>
</grp>
</cat>
</bd>
USE TEEST;
GO
SET NOCOUNT ON;
DECLARE @opt_xml TABLE
(
bn_id INT
,select_t varchar(max)
,select_k varchar(max)
);
INSERT INTO @opt_xml (bn_id , select_t , select_k)
SELECT 11,'L','T'
UNION
SELECT 12,'X','M';
DECLARE @TXML XML = '<bd>
<cat>
<grp>
<ben>
<bn_id>11</bn_id>
<select>
<select_t />
<select_k>F</select_k>
</select>
</ben>
<ben>
<bn_id>12</bn_id>
<select>
<select_t>G</select_t>
<select_k>F</select_k>
</select>
</ben>
</grp>
</cat>
</bd>';
-- INSPECT THE OLD AND THE NEW VALUES
SELECT
SEL.DATA.value('(bn_id/text())[1]','INT') AS bn_id
,SEL.DATA.value('(select/select_t/text())[1]','VARCHAR(MAX)') AS select_t
,SEL.DATA.value('(select/select_k/text())[1]','VARCHAR(MAX)') AS select_k
,OX.select_k
,OX.select_t
FROM @TXML.nodes('bd/cat/grp/ben') SEL(DATA)
CROSS APPLY @opt_xml OX
WHERE OX.bn_id = SEL.DATA.value('(bn_id/text())[1]','INT');
-- REPLACE AN EXISTING VALUE
DECLARE @BN_ID INT = 11;
DECLARE @neval VARCHAR(10) = (SELECT X.select_k FROM @opt_xml X WHERE X.bn_id = @BN_ID);
SET @TXML.modify('
replace value of (bd/cat/grp/ben[bn_id/text()=sql:variable("@BN_ID")]/select/select_k/text())[1]
with sql:variable("@NEVAL")');
-- INSERT A VALUE AS AN EMPTY VALUE CANNOT BE REPLACED
SET @TXML.modify('
insert text {sql:variable("@NEVAL")}
as first into (bd/cat/grp/ben[bn_id/text()=sql:variable("@BN_ID")]/select/select_t)[1]
');
SELECT @TXML;
After<bd>
<cat>
<grp>
<ben>
<bn_id>11</bn_id>
<select>
<select_t>L</select_t>
<select_k>F</select_k>
</select>
</ben>
<ben>
<bn_id>12</bn_id>
<select>
<select_t>G</select_t>
<select_k>F</select_k>
</select>
</ben>
</grp>
</cat>
</bd>
To clear all the node values, one can use a traversing // delete modification
SET @TXML.modify('
delete //select_t/text()
');
SET @TXML.modify('
delete //select_k/text()
');
Viewing 2 posts - 1 through 1 (of 1 total)
You must be logged in to reply to this topic. Login to reply
This website stores cookies on your computer.
These cookies are used to improve your website experience and provide more personalized services to you, both on this website and through other media.
To find out more about the cookies we use, see our Privacy Policy