具有以下配置: 德尔福XE7 MS SQL Server 2008 使用FireDAC连接到SQL服务器
我使用存储过程检索表格,其中包含来自SQL服务器的所有详细记录,格式转换为nvarchar(max)。这是一个例子:
CREATE PROCEDURE uspUsers_GetAll
@ReturnData nvarchar(max) = NULL OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET @ReturnData = CONVERT(nvarchar(max),
(SELECT *, ( SELECT UserID, RightType
FROM UserRights
WHERE UserRights.UserID = Users.ID
FOR XML RAW('UserRight'),
ROOT('UserRights'), ELEMENTS, TYPE)
FROM Users
FOR XML RAW('Users'),
ROOT('root') , ELEMENTS));
END;
在Delphi方面,我调用这个存储过程,将其加载到XML中,我试图解析它以将其转换为本地对象列表。像这样:
procedure TUsers.LoadFromDatabase;
var
usersXML: String;
xmlDoc: IXMLDocument;
workNode: IXMLNode;
userObj: TUser;
begin
Items.Clear;
with dmApp.uspWork do
begin
Close;
if Prepared then
Prepared := False;
Params.Clear;
StoredProcName := 'uspUsers_GetAll';
Prepare;
ExecProc;
end;
usersXML := dmApp.uspWork.Params.ParamByName('@ReturnData').Value;
xmlDoc := TXMLDocument.Create(nil);
xmlDoc.LoadFromXML(usersXML);
workNode := xmlDoc.DocumentElement;
workNode := workNode.ChildNodes.FindNode('Users');
while (workNode <> nil) and (workNode.NodeName = 'Users') do
begin
userObj := TUser.Create;
userObj.LoadFromXMLNode(workNode);
Items.Add(userObj);
workNode := workNode.NextSibling;
end;
end;
在上面的代码中
workNode := workNode.ChildNodes.FindNode('Users');
行在Xml.XMLDoc单元的深处返回一个异常。不是我可以解决的特定问题的错误消息。尝试将xmlDoc保存到xml文件中并且看起来没问题(可以使用Firefox等所有类型的工具打开它)。
奇怪的是,如果我将@ReturnData更改为varchar(max),我就不会再出现此错误。
知道我做错了吗?
答案 0 :(得分:0)
对于XML,请避免使用*和未命名的列。此外,不要在嵌套XML中使用ROOT,而是将其声明为命名字段。例如:
CREATE PROCEDURE uspUsers_GetAll
@ReturnData nvarchar(max) = NULL OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET @ReturnData = CONVERT(nvarchar(max),
(SELECT givenname = Users.GivenName,surname = Users.Surname , emailaddress = Users.Email , userrights = ( SELECT userid = UserRights.UserID, righttype = UserRights.RightType
FROM UserRights
WHERE UserRights.UserID = Users.ID
FOR XML RAW('userrights'),
ELEMENTS, TYPE)
FROM Users
FOR XML RAW('user'),
ROOT('root') , ELEMENTS));
END;
BTW我总是避免使用大写的xml标签,叫我老式。另请注意行标记&#39;用户&#39;应该是&#39;用户&#39;因为这指的是单个用户。这应该给你
<root>
<user>
<givenname>Jo</givenname>
<surname>Shmo</surname>
<userrights>
<userid>12</userid>
<righttype>some_type</righttype>
</userrights>
<userrights>
<userid>12</userid>
<righttype>some_type</righttype>
</userrights>
</user>
<user>
....
</user>
</root>