我在SQL Server 2008 R2数据库中生成了以下XML
<XMLData>
...
<Type>1</Type>
...
</XMLData>
我需要的最终输出是单个组合如下:
<AllMyData>
<XMLData>
...
<Type>1</Type>
...
</XMLData>
<XMLData>
...
<Type>2</Type>
...
</XMLData>
...
...
<XMLData>
...
<Type>n</Type>
...
</XMLData>
<AllMyData>
n
在查询运行之前是未知的。
现在我使用这种方法:
ALTER FUNCTION [dbo].[fn_GetErrorXML]
(
@DateFrom datetime,
@DateTo datetime,
@ResourceTypeID bigint,
@ServerID int
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE @ErrorDescription VARCHAR(MAX)
SET @ErrorDescription = '<root>';
WITH CTE AS
(
SELECT
d.GeneratedOnUtc,
ErrorDescription = cast(d.Data as nvarchar(max))
FROM dbo.AgentData d
INNER JOIN dbo.Agent a ON a.CheckID = d.CheckID
INNER JOIN dbo.Server s ON a.ServerID = s.ID
WHERE d.EventType = 'Result' AND
a.ResourceTypeID & @ResourceTypeID > 0 AND
s.ID = @ServerID AND
d.GeneratedOnUtc between @DateFrom AND @DateTo AND
d.Result = 0
)
SELECT @ErrorDescription = @ErrorDescription + cte.ErrorDescription
FROM CTE
ORDER BY cte.GeneratedOnUtc ASC
RETURN(@ErrorDescription + '</root>')
END
其中d.Data
数据类型为xml not null
但是XML强制转换+ UDF非常懒散,看起来很难看。
有没有更好的方法呢?
答案 0 :(得分:1)
with cte AS
(SELECT d.GeneratedOnUtc as gtime,
d.Data as xmlDat FROM dbo.AgentData d
INNER JOIN dbo.Agent a ON a.CheckID = d.CheckID
INNER JOIN dbo.Server s ON a.ServerID = s.ID
WHERE d.EventType = 'Result' AND
a.ResourceTypeID & @ResourceTypeID > 0 AND
s.ID = @ServerID AND
d.GeneratedOnUtc between @DateFrom AND @DateTo AND
d.Result = 0
)
select CAST(cte.xmlDat AS XML) from cte order by cte.gtime for xml path(''), root('root')
答案 1 :(得分:0)
这不能解决性能问题,这似乎与sql语句本身有关,或者在其他语句中使用函数。试试这个。这会在15秒内返回1.000.000记录的结果,我认为这非常好。
DECLARE @t TABLE ( x XML )
INSERT INTO @t
SELECT '<XMLData><Type>1</Type></XMLData>'
UNION
SELECT '<XMLData><Type>2</Type></XMLData>'
SELECT x.query('/XMLData/*')
FROM @t
FOR XML PATH('XMLData') ,
ROOT('AllMyData')
输出:
<AllMyData>
<XMLData>
<Type>1</Type>
</XMLData>
<XMLData>
<Type>2</Type>
</XMLData>
</AllMyData>
如果可以接受其他标签,则可以执行以下操作:
SELECT x
FROM @t
FOR XML PATH(''), ROOT('AllMyData')
此查询在3秒内完成1.000.000行,输出如下:
<AllMyData>
<x>
<XMLData>
<Type>1000000</Type>
</XMLData>
</x>
<x>
<XMLData>
<Type>999999</Type>
</XMLData>
</x>
</AllMyData>