Question : T-SQL merge two XML documents

Illustrated below are two sample XML documents that are received as parameters by a stored procedure. The goal is to produce a third XML document that represents a merge of the settings.  Specifically:

1) The "Language" and "TimeZone" values should be left as-is.
2) The "SortingLimitCount" value should end up as 2000, over-writing the 1000 value.
3) The "TestNewSetting" setting should be added.

Here is what I am doing with the .Query and .Modify methods, thinking there's a way to construct the merged set without resorting to a cursor.

  declare @NewSubset xml = @NewSettings.query('//Setting')

  declare @FullMerge xml = @ExistingSettings

  set @FullMerge.modify('
    insert sql:variable("@NewSubset")
    into (/Settings)[1]
  ')

  select @FullMerge

Thanks for considering this challenge!
Code Snippet:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
/* Baseline settings */
declare @ExistingSettings xml = ' 
  
  
  
'
 
 
/* Changes to baseline */
declare @NewSettings xml = ' 
  
  
'
 
 
/* List of settings that exist in both. 
   Change to NOT IN for additions.
*/
select 
     setting.value('@name','sysname')       as name 
    ,setting.value('@value','varchar(max)') as value
from @NewSettings.nodes('//Setting') as node(setting)
where setting.value('@name','sysname') in (
  select new.value('@name','sysname') 
  from @ExistingSettings.nodes('//Setting') as node(new)
)

Answer : T-SQL merge two XML documents

Try this:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
DECLARE @ExistingSettings xml = ' 
  
  
  
';
 
DECLARE @NewSettings xml = ' 
  
  
';
 
WITH CTE_Actual_Settings AS (
  SELECT  
    Settings.Setting.value('@name', 'nvarchar(100)') AS name,
    Settings.Setting.value('@value', 'nvarchar(100)') AS value
  FROM @ExistingSettings.nodes('/Settings/Setting') AS Settings(Setting)
), CTE_New_Settings AS (
  SELECT  
    Settings.Setting.value('@name', 'nvarchar(100)') AS name,
    Settings.Setting.value('@value', 'nvarchar(100)') AS value
  FROM @NewSettings.nodes('/Settings/Setting') AS Settings(Setting)
), CTE_Merged_Settings AS (
  SELECT
    CASE WHEN A.name IS NULL THEN N.name ELSE A.name END AS name,
    CASE WHEN N.name IS NOT NULL THEN N.value ELSE A.value END AS value
  FROM CTE_Actual_Settings AS A
  FULL OUTER JOIN CTE_New_Settings AS N
  ON A.name = N.name
)
SELECT 
  name AS '@name',
  value AS '@value'
FROM CTE_Merged_Settings
FOR XML PATH('Setting'), ROOT('Settings');
Random Solutions  
 
programming4us programming4us