Use of xml.modify to insert parameters into specific element of an xml column

37,497

Solution 1

declare @XML xml = '
<Profile>
  <ID>20</ID>
  <User>
    <ID>BC4A18CA-AFB5-4268-BDA9-C990DAFE7783</ID>
    <Name>somename</Name>
    <Activities>
      <Activity>
         <Name>activity1</Name>
      </Activity>
    </Activities>
  </User>
</Profile>'

declare @user_id nvarchar(50) = '20'
declare @activity_name nvarchar(50) = 'activity1'
declare @display_name nvarchar(50) = 'displayname1'

set @xml.modify('insert <DisplayName>{sql:variable("@display_name")}</DisplayName>
                 into (/Profile[ID = sql:variable("@user_id")]
                       /User/Activities/
                       Activity[Name = sql:variable("@activity_name")])[1]')

Result:

<Profile>
  <ID>20</ID>
  <User>
    <ID>BC4A18CA-AFB5-4268-BDA9-C990DAFE7783</ID>
    <Name>somename</Name>
    <Activities>
      <Activity>
        <Name>activity1</Name>
        <DisplayName>displayname1</DisplayName>
      </Activity>
    </Activities>
  </User>
</Profile>

Solution 2

Try this

declare @ins xml 
    '<Activity><Name>'+
    @activity_name+
    '</Name><DisplayName>'
    +@display_name+
    '</DisplayName></Activity>'
SET @devices_xml.modify('
    insert sql:variable("@ins") into (/Profile[ID=sql:variable("@user_id")]/User/Activities)[1]')

Or

SET @devices_xml.modify('
      insert <Activity>
             <Name>{sql:variable("@activity_name")}</Name>
             <DisplayName>{sql:variable("@display_name")}</DisplayName>
             </Activity> 
      into (/Profile[ID=sql:variable("@user_id")]/User/Activities)[1]'    )

Solution 3

Not sure I fully understand your logic, but you can insert into xml using sql:variable with curly brackets eg

DECLARE @profiles_xml xml

set @profiles_xml = '<Profile>
  <ID>20</ID>
  <User>
    <ID>BC4A18CA-AFB5-4268-BDA9-C990DAFE7783</ID>
    <Name>somename</Name>
    <Activities>
      <Activity>
         <Name>activity1</Name>
      </Activity>
    </Activities>
  </User>
</Profile>'


SELECT 'before' s, DATALENGTH(@profiles_xml) dl, @profiles_xml

DECLARE @user_id CHAR(36), @activity_name NVARCHAR(MAX), @display_name NVARCHAR(MAX)
SELECT @user_id = 'BC4A18CA-AFB5-4268-BDA9-C990DAFE7783', @activity_name = 'TEST ACTIVITY NAME', @display_name = 'TEST DISPLAY NAME'

SET @profiles_xml.modify('
    insert <Activity><Name>{sql:variable("@activity_name")}</Name><DisplayName>{sql:variable("@display_name")}</DisplayName></Activity>
    as first
    into (/Profile/User/Activities)[1]')

SELECT 'after' s, DATALENGTH(@profiles_xml) dl, @profiles_xml
Share:
37,497
Christian
Author by

Christian

Updated on July 05, 2022

Comments

  • Christian
    Christian almost 2 years

    I would like to use a stored procedure to insert some values passed in as parameters into elements in the xml of a column. I have this so far The following parameters:

    @profile_id int,
    @user_id nvarchar(50),
    @activity_name nvarchar(50),
    @display_name nvarchar(50)
    

    Retrieve the desired xml:

    DECLARE @profiles_xml xml
    SET @profiles_xml = (SELECT profiles from tbl_applied_profiles WHERE profiles.value('(Profile/ID)[1]','int')= @profile_id)
    

    The xml from the column inside the @profiles_xml looks like this:

    <Profile>
      <ID>20</ID>
      <User>
        <ID>BC4A18CA-AFB5-4268-BDA9-C990DAFE7783</ID>
        <Name>somename</Name>
        <Activities>
          <Activity>
             <Name>activity1</Name>
          </Activity>
        </Activities>
      </User>
    </Profile>
    

    Attempt to Insert into User with specific ID the activity name and display name:

    SET @profiles_xml.modify('
        insert
        if(/Profile/User/ID=sql:variable("@user_id"))
        then Activity[Name=sql:variable("@activity_name")][DisplayName=sql:variable("@display_name")]
        else()
        as first
        into (/Profile/User/Activities)[1]')
    

    I have also tried this with no success:

     SET @devices_xml.modify('
        insert /Profile/User[ID=sql:variable("@user_id")]/Activity[Name=sql:variable("@activity_name")][DisplayName=sql:variable("@display_name")]
        into (/Profile/User/Activities)[1]')
    

    And this:

     SET @devices_xml.modify('
    insert
     /Profile/User[ID=sql:variable("@user_id")]/Activities/Activity[Name=sql:variable("@activity_name")][DisplayName=sql:variable("@display_name")]
        into (/Profile/User/Activities)[1]')
    

    What is the correct way to do this?