SQL: в выражении XML modify(), можете ли вы использовать переменную для имени тега?
Я пытаюсь сделать что-то вроде:
SET @ xml.modify ('insert <@x)>@y в (/ что-то)[ID="@id"][1]')
Я понял, когда я заменяю @y {sql:variable("@y")}, это сработало. Но это не работает для @x.
Есть ли способ заставить его работать?
1 ответ
Невозможно вставить элемент с динамическим именем. Посмотрите на эти примеры:
DECLARE @x XML=
N'<root>
<test>Some test value</test>
</root>';
Спокойно, все исправлено литералами
SET @x.modify('insert <blah>new element</blah> as first into (/root)[1]')
SELECT @x;
Результат
<root>
<blah>new element</blah>
<test>Some test value</test>
</root>
Динамический контент
DECLARE @content NVARCHAR(100)='dynamic content'
SET @x.modify('insert <blah>{sql:variable("@content")}</blah> as first into (/root)[1]');
SELECT @x;
Результат
<root>
<blah>dynamic content</blah>
<blah>new element</blah>
<test>Some test value</test>
</root>
Это не разрешено и приведет к ошибке
DECLARE @element NVARCHAR(100)='dynElement';
SET @x.modify('insert <{sql:variable("@element")}>{sql:variable("@content")}</{sql:variable("@element")}> as first into (/root)[1]');
SELECT @x;
Но вы можете создать полный XML-элемент извне и вставить его как есть.
DECLARE @new_element XML='<dynElement>Some dynamic content</dynElement>';
SET @x.modify('insert sql:variable("@new_element") as first into (/root)[1]');
SELECT @x;
Результат
<root>
<dynElement>Some dynamic content</dynElement>
<blah>dynamic content</blah>
<blah>new element</blah>
<test>Some test value</test>
</root>
Это привело бы к тому же результату
DECLARE @new_element XML=(SELECT 'Some dynamic content' FOR XML PATH('dynElement'));
SET @x.modify('insert sql:variable("@new_element") as first into (/root)[1]');
SELECT @x;
И это - полностью параметризованный - также вернет то же самое
DECLARE @element NVARCHAR(100)='dynElement';
DECLARE @content NVARCHAR(100)='dynamic content'
DECLARE @new_element XML='<' + @element +'>' + @content + '</' + @element + '>';
SET @x.modify('insert sql:variable("@new_element") as first into (/root)[1]');
SELECT @x;