试图弄清楚为什么这个代码段不起作用。
DECLARE @changeStatus XML, @changeSet XML
SELECT @changeSet = TOP 1 ChangeSet
FROM MyTable
SET @changeStatus = '<change id="' + CAST(NEWID() AS NVARCHAR(36)) + '" by="' + @authorizingUserName + '" byAccountId="' + CAST(@authorizingUserId AS NVARCHAR(36)) + '" when="' + CONVERT(NVARCHAR(50),GETUTCDATE(),127) + 'Z">'
+ '<property id="Status" name="Status" old="' + @status + '" new="Closed" />'
+ '<collections />'
+ '</change>'
-- THIS DOES NOT ERROR OUT AND DOES NOT DO ANYTHING!!
SET @changeSet.modify('insert sql:variable("@changeStatus") as last into (/changes)[1]')
XML的整体结构是:
<changes>
<change id="" by="" byAccountId="" when="">
<property />
<collections />
</change>
</changes>
当我运行脚本并在处理之前和之后检查@changeSet时,它们是相同的。即:@changeStatus从未添加到@changeSet中包含的XML中。
如果原件是:
<changes>
<change id="change01" by="" byAccountId="" when="">
<property ... />
<collections />
</change>
<change id="change02" by="" byAccountId="" when="">
<property ... />
<collections />
</change>
</changes>
我希望看到:
<changes>
<change id="change01" by="" byAccountId="" when="">
<property ... />
<collections />
</change>
<change id="change02" by="" byAccountId="" when="">
<property ... />
<collections />
</change>
<change id="82ECB3C5-D3BA-4CD2-B62C-89C083E4BAA1" by="me@mydomain.com" byAccountId="1E910737-D78C-E711-9C04-00090FFE0001" when="2018-01-17T00:12:33.700Z">
<property id="Status" name="Status" old="In Review" new="Closed" />
<collections />
</change>
</changes>
有谁看到可能出错的地方?
答案 0 :(得分:0)
您发布的查询一般都有效。我跑了以下测试:
但是,如果任何注入的参数为null,则不会插入更改,并且在您尝试插入NULL
时也不会抛出任何错误。
答案 1 :(得分:0)
您永远不应该在字符串级别创建XML!
这有各种副作用。
NULL
,则整个字符串将为NULL
SELECT '<x>' + NULL + '</x>';
FOR XML
肯定会! - 创建有效的XML。现在假设你的一个字符串包含禁用字符... SELECT '<x>' + 'The arrow "->" might appear in normal text' + '</x>';
FOR XML
将使用 - 当然! - 正确的格式输入和输出。您可以在XML中编写任何内容,但在另一个系统上可能无法读取它。以这种方式尝试:
DECLARE @changeSet XML = N'<changes/>';
DECLARE @changeStatus XML;
SET @changeStatus=
(
SELECT NEWID() AS [@id]
,'SomeAuthor' AS [@by]
,'SomeAuthorId' AS [@byAccountId]
,GETUTCDATE() AS [@when]
,'Status' AS [property/@id]
,'Status' AS [property/@name]
,'In Review' AS [property/@old]
,'Closed' AS [property/@new]
,'' AS [collections]
FOR XML PATH('change')
);
--your code works fine
SET @changeSet.modify(N'insert sql:variable("@changeStatus") as last into (/changes)[1]');
--you see the first change integrated
SELECT @changeSet;
- 现在让我们再创建一个元素
SET @changeStatus=
(
SELECT NEWID() AS [@id]
,'Another' AS [@by]
,'OneMore' AS [@byAccountId]
,GETUTCDATE() AS [@when]
,'Status' AS [property/@id]
,'Status' AS [property/@name]
,'In Review' AS [property/@old]
,'Closed' AS [property/@new]
,'' AS [collections]
FOR XML PATH('change')
);
--and insert it
SET @changeSet.modify(N'insert sql:variable("@changeStatus") as last into (/changes)[1]');
--yeah, worked!
SELECT @changeSet;