Я изо всех сил пытался произвести то, что вам нужно, используя FOR XML EXPLICIT
. В конце концов я вернулся к использованию выражения XQuery FLWOR . Помните, что SQL Сервер XML тип данных не может содержать CDATA
разделы. Вам необходимо использовать тип данных NVARCHAR(MAX)
. Проверьте это здесь: Как использовать CDATA в SQL XML
SQL
-- DDL and sample data population, start
DECLARE @RepCar TABLE
(
[Name] VARCHAR(10),
[Make] VARCHAR(10),
[Model] VARCHAR(10),
[Price] MONEY,
[Type] VARCHAR(10),
[Series] VARCHAR(10),
[Class] VARCHAR(10)
);
INSERT INTO @RepCar
(
Name,
Make,
Model,
Price,
Type,
Series,
Class
)
VALUES
('Car1', 'Make1', 'Model1', 100, 'Type1', 'IS', 'Sedan'),
('Car1', 'Make1', 'Model1', 100, 'Type1', 'LS', 'Sport'),
('Car2', 'Make2', 'Model2', 200, 'Type2', 'M3', 'Sport'),
('Car3', 'Make3', 'Model3', 300, 'Type3', 'GS350', 'Sedan');
-- DDL and sample data population, end
--Declare Variables
DECLARE @TransactionId NVARCHAR(100) = CURRENT_TRANSACTION_ID();
DECLARE @TransactionDateTime DATETIME = GETDATE();
DECLARE @lt NCHAR(4) = '<'
, @gt NCHAR(4) = '>';
SELECT REPLACE(REPLACE(TRY_CAST((SELECT 'CollectSamplingData' AS [TransactionType]
, @TransactionId AS [TransactionID]
, @TransactionDateTime AS [TransactionDate]
, *
FROM @RepCar
FOR XML PATH('r'), TYPE, ROOT('root')).query('<Messages><Message>
{
for $x in /root/r[1]
return (<TransactionType>{concat("<![CDATA[", data($x/TransactionType[1]), "]]>")}</TransactionType>,
<TransactionID>{concat("<![CDATA[", data($x/TransactionID[1]), "]]>")}</TransactionID>,
<TransactionDate>{concat("<![CDATA[", data($x/TransactionDate[1]), "]]>")}</TransactionDate>,
<CName>{concat("<![CDATA[", data($x/Name[1]), "]]>")}</CName>,
<MakeCar>{concat("<![CDATA[", data($x/Make[1]), "]]>")}</MakeCar>,
<MakeModel>{concat("<![CDATA[", data($x/Model[1]), "]]>")}</MakeModel>,
<DataValue>{concat("<![CDATA[", data($x/Price[1]), "]]>")}</DataValue>,
<MakeType>{concat("<![CDATA[", data($x/Type[1]), "]]>")}
{
for $y in /root/r
return (
<Series>{concat("<![CDATA[", data($y/Series[1]), "]]>")}</Series>,
<Class>{concat("<![CDATA[", data($y/Class[1]), "]]>")}</Class>
)
}
</MakeType>)
}
</Message></Messages>') AS NVARCHAR(MAX)), @lt,'<'), @gt, '>') AS [XML with CDATA sections];
Вывод
<Messages>
<Message>
<TransactionType><![CDATA[CollectSamplingData]]></TransactionType>
<TransactionID><![CDATA[1149709]]></TransactionID>
<TransactionDate><![CDATA[2020-02-03T16:23:43.020]]></TransactionDate>
<CName><![CDATA[Car1]]></CName>
<MakeCar><![CDATA[Make1]]></MakeCar>
<MakeModel><![CDATA[Model1]]></MakeModel>
<DataValue><![CDATA[100.0000]]></DataValue>
<MakeType><![CDATA[Type1]]>
<Series><![CDATA[IS]]></Series>
<Class><![CDATA[Sedan]]></Class>
<Series><![CDATA[LS]]></Series>
<Class><![CDATA[Sport]]></Class>
<Series><![CDATA[M3]]></Series>
<Class><![CDATA[Sport]]></Class>
<Series><![CDATA[GS350]]></Series>
<Class><![CDATA[Sedan]]></Class>
</MakeType>
</Message>
</Messages>