I have a table called Rules
that has a numeric column RuleID
and an XML column XMLData
.
Here is the contents of XMLData
for RuleID = 1
:
<EP Name="C3EPIC" ReturnVar="AUTOMDWG">
<Parameters>
<Parameter Key="Server" Value='="Rules.MyRules"'
Description="Server"/>
<Parameter Key="EPICLIBRARY" Value='="DEVPGM10"' Description="Library"/>
<Parameter Key="Library" Value='="DEVPGM10"' Description=""/>
<Parameter Key="ProgramName" Value='="MyProgram"' Description=""/>
<Parameter Key="Function" Value="=HDWEFUNCA"
Description="Hardware MFG MODEL #"/>
<Parameter Key="Trim" Value="=HDWETRIMA" Description="Hardware Trim"/>
</Parameters>
<OutputVariables/>
</EP>
I have 2 tasks:
- Find every
ruleID
where the parameter keyEPICLIBRARY
is="DEVPGM10"
- Change
DEVPGM10
toQAPGM10
in those rules
What I have started with so far, just to see if I could query into the XML, is this:
DECLARE @xml XML = (SELECT XMLData
FROM Rules
WHERE ruleid = 1
FOR XML AUTO, ELEMENTS, ROOT('TopLevel'))
SELECT
epic.value('@key', 'nvarchar(255)') as AttrKey,
epic.value('@value', 'nvarchar(255)') as AttrVal
FROM
@xml.nodes('TopLevel/Rules/XMLData/EP/Parameters/Parameter') A(epic)
The good news is that it returns exactly 6 rows, however, for all 6 records, AttrKey
and AttrVal
are NULL
.
I was expecting/hoping for AttrKey
values of
Server
EPICLIBRARY
Library
ProgramName
Function
Trim
Thanks in advance for any guidance
I have a table called Rules
that has a numeric column RuleID
and an XML column XMLData
.
Here is the contents of XMLData
for RuleID = 1
:
<EP Name="C3EPIC" ReturnVar="AUTOMDWG">
<Parameters>
<Parameter Key="Server" Value='="Rules.MyRules.com"'
Description="Server"/>
<Parameter Key="EPICLIBRARY" Value='="DEVPGM10"' Description="Library"/>
<Parameter Key="Library" Value='="DEVPGM10"' Description=""/>
<Parameter Key="ProgramName" Value='="MyProgram"' Description=""/>
<Parameter Key="Function" Value="=HDWEFUNCA"
Description="Hardware MFG MODEL #"/>
<Parameter Key="Trim" Value="=HDWETRIMA" Description="Hardware Trim"/>
</Parameters>
<OutputVariables/>
</EP>
I have 2 tasks:
- Find every
ruleID
where the parameter keyEPICLIBRARY
is="DEVPGM10"
- Change
DEVPGM10
toQAPGM10
in those rules
What I have started with so far, just to see if I could query into the XML, is this:
DECLARE @xml XML = (SELECT XMLData
FROM Rules
WHERE ruleid = 1
FOR XML AUTO, ELEMENTS, ROOT('TopLevel'))
SELECT
epic.value('@key', 'nvarchar(255)') as AttrKey,
epic.value('@value', 'nvarchar(255)') as AttrVal
FROM
@xml.nodes('TopLevel/Rules/XMLData/EP/Parameters/Parameter') A(epic)
The good news is that it returns exactly 6 rows, however, for all 6 records, AttrKey
and AttrVal
are NULL
.
I was expecting/hoping for AttrKey
values of
Server
EPICLIBRARY
Library
ProgramName
Function
Trim
Thanks in advance for any guidance
Share Improve this question edited yesterday Yitzhak Khabinsky 22.2k2 gold badges19 silver badges23 bronze badges asked 2 days ago Rich KenyonRich Kenyon 11 silver badge3 bronze badges New contributor Rich Kenyon is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 1- While asking a question, you need to provide a minimal reproducible example: (1) DDL and sample data population, i.e. CREATE table(s) plus INSERT T-SQL statements. (2) What you need to do, i.e. logic and your code attempt implementation of it in T-SQL. (3) Desired output, based on the sample data in the #1 above. (4) Your SQL Server version (SELECT @@version;). – Yitzhak Khabinsky Commented 2 days ago
1 Answer
Reset to default 1Please try the following solution.
The SQL Server XQuery's .modify()
method has limitation that it is capable to update one single value only!
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (RuleID INT IDENTITY PRIMARY KEY, XMLData XML);
INSERT INTO @tbl (XMLData) VALUES
(N'<EP Name="C3EPIC" ReturnVar="AUTOMDWG">
<Parameters>
<Parameter Key="Server" Value=''="Rules.MyRules.com"''
Description="Server"/>
<Parameter Key="EPICLIBRARY" Value=''="DEVPGM10"'' Description="Library"/>
<Parameter Key="Library" Value=''="DEVPGM10"'' Description=""/>
<Parameter Key="ProgramName" Value=''="MyProgram"'' Description=""/>
<Parameter Key="Function" Value="=HDWEFUNCA"
Description="Hardware MFG MODEL #"/>
<Parameter Key="Trim" Value="=HDWETRIMA" Description="Hardware Trim"/>
</Parameters>
<OutputVariables/>
</EP>');
-- DDL and sample data population, end
-- before
SELECT * FROM @tbl;
DECLARE @replaceWith VARCHAR(30) = '="QAPGM10"';
UPDATE @tbl
SET XMLData.modify('replace value of (/EP/Parameters/Parameter[@Key="EPICLIBRARY" and @Value=''="DEVPGM10"'']/@Value)[1]
with sql:variable("@replaceWith")');
-- after
SELECT * FROM @tbl;
SELECT RuleID
, c.value('@Key','nvarchar(255)') AS AttrKey
, c.value('@Value', 'nvarchar(255)') AS AttrVal
FROM @tbl
CROSS APPLY XMLData.nodes('/EP/Parameters/Parameter') AS t(c);
Output
RuleID | AttrKey | AttrVal |
---|---|---|
1 | Server | ="Rules.MyRules.com" |
1 | EPICLIBRARY | ="QAPGM10" |
1 | Library | ="DEVPGM10" |
1 | ProgramName | ="MyProgram" |
1 | Function | =HDWEFUNCA |
1 | Trim | =HDWETRIMA |