SQL Server 2008 に次の XML を持つ 2 つの XML 変数があるとします。
DECLARE @FIRST XML = '<DBPerson>
<firstname>John</firstname>
<lastname>Bob</lastname>
</DBPerson>',
@Second XML = '<FromUI>
<lastname>New Bob</lastname>
<age>39</age>
</FromUI>';
次の出力が必要です。
<DBPerson>
<firstname>John</firstname>
<lastname>New Bob</lastname>
<age>39</age>
</DBPerson>
@Second
基本的に、2 つの XML 変数の内容を、変数が優先される 1 つにマージしたいと考えています( @First
&の両方にノードが存在する場合は@Second
、内部のノードを@Second
考慮する必要があります)。
私が取ったアプローチは、最初に次のように両方のルート要素内のすべての一意の要素のリストを取得することです。
WITH ALLFields AS
(
SELECT
x.y.value('local-name(.)','varchar(50)') As Element
FROM @Second.nodes('FromUI/*') AS x(y)
UNION
SELECT
x.y.value('local-name(.)','varchar(50)') As Element
FROM @FIRST.nodes('DBPerson/*') AS x(y)
)
SELECT * FROM ALLFields AF
しかし、私はここから先に進む方法がわかりません。sql:column
最初にノード名とその値(に基づく)を取得するためにどこかを使用してテーブルを作成する必要があることはわかっていますAllFields
。次にFOR XML PATH('DBPerson')
、最終的なxmlを形成するために使用できますが、sql:column
どんな助けでも大歓迎です。
UPDATE :次のクエリに要約しました。
DECLARE @FIRST XML = '<DBPerson><firstname>John</firstname><lastname>Bob</lastname></DBPerson>',
@Second XML = '<FromUI><lastname>New Bob</lastname><age>39</age></FromUI>';
WITH ALLFields AS
(
SELECT
x.y.value('local-name(.)','varchar(50)') As Element
FROM @Second.nodes('FromUI/*') AS x(y)
UNION
SELECT
x.y.value('local-name(.)','varchar(50)') As Element
FROM @FIRST.nodes('DBPerson/*') AS x(y)
), Filtered AS
(
SELECT
Element
, @FIRST.value('(DBPerson/*[local-name()=sql:column("Element")])[1]','varchar(max)') AS F
, @Second.value('(FromUI/*[local-name()=sql:column("Element")])[1]','varchar(max)') AS S
FROM ALLFields AF
), FinalValues AS
(
SELECT
Element
, CASE
WHEN S IS NULL THEN F
ELSE S
END AS V
FROM Filtered
)
SELECT * FROM FinalValues
このクエリにより、1 つの列にすべての要素が含まれ、別の列に要素のデータが含まれるテーブルが得られます。次のように最終的な XML を生成するにはどうすればよいですか。
<DBPerson><firstname>John</firstname><lastname>New Bob</lastname><age>39</age></DBPerson>