【问题标题】:How to return xml from a stored procedure using T-SQL如何使用 T-SQL 从存储过程中返回 xml
【发布时间】:2014-06-23 06:19:00
【问题描述】:

我调用了一个存储过程来在我的 c# 应用程序中返回我的数据。我的问题是我在这个存储过程中有 3 个 SELECT 语句。我需要从列中获取所有值。从我的post 昨天我得出结论,xml 是要走的路,所以我可以得到我的结果。我唯一的问题是我不确定这在example 中是如何工作的,我发现他只是声明了@xml xml。那没有任何作用。该示例使用 xml 作为输出参数。那么如何使用存储过程中的 xml 输出参数返回我的值呢?我在下面发布了代码。提前谢谢您,我会尽力回答您的所有问题。如果您对如何实现能够在 c# 中读取所有 3 条 SELECT 语句的目标有任何其他建议,我愿意接受输入。

ALTER PROCEDURE [dbo].[L_DownTimeByLine]

@startTime datetime,
@endTime datetime,
@line int,
@xml xml output

DECLARE @QueryA nvarchar(MAX);
DECLARE @QueryB nvarchar(MAX);
DECLARE @ParamsA nvarchar(500);
DECLARE @ParamsB nvarchar(500);

SET @QueryA = N'
select min(DateAndTime) as FaultStart, max(DateAndTime) as FaultEnd, cast(max(DateAndTime) - min(DateAndTime) as time) as DownTime
from (select pt.*,
         sum(case when datediff(second, prevdt, DateAndTime) <= 1 then 0 else 1 end) over 
             (order by DateAndTime) as grp
  from (select pt.*, lag(DateAndTime) over (order by DateAndTime) as prevdt
        from IncomingProductTracker pt
        where ' + @lineAvariable + ' = 1 and
             DateAndTime > @startTime1 and
              DateAndTime < @endTime1
       ) pt
 ) pt
 group by grp
having cast(max(DateAndTime) - min(DateAndTime) as time) < @breakAllowance1
order by FaultStart';

SET @ParamsA = N'@startTime1 datetime, @endTime1 datetime, @breakAllowance1 time(0)';

SET @QueryB = N'
select min(DateAndTime) as FaultStart, max(DateAndTime) as FaultEnd,  cast(max(DateAndTime) - min(DateAndTime) as time) as DownTime
from (select pt.*,
         sum(case when datediff(second, prevdt, DateAndTime) <= 1 then 0 else 1 end) over 
             (order by DateAndTime) as grp
  from (select pt.*, lag(DateAndTime) over (order by DateAndTime) as prevdt
        from IncomingProductTracker pt
        where ' + @lineBvariable + ' = 1 and
             DateAndTime > @startTime1 and
              DateAndTime < @endTime1
       ) pt
 ) pt
 group by grp
having cast(max(DateAndTime) - min(DateAndTime) as time) < @breakAllowance1
order by FaultStart';

SET @ParamsB = N'@startTime1 datetime, @endTime1 datetime, @breakAllowance1 time(0)';

declare @tempA table (
FaultStart datetime,
FaultEnd datetime,
DownTime time(0))

declare @tempB table (
FaultStart datetime,
FaultEnd datetime,
DownTime time(0))

insert into @tempA (FaultStart, FaultEnd, DownTime)
EXEC sp_executesql @QueryA, @ParamsA, @startTime1 = @startTime, @endTime1 = @endTime, @breakAllowance1 = @breakAllowance;

insert into @tempB (FaultStart, FaultEnd, DownTime)
EXEC sp_executesql @QueryB, @ParamsB, @startTime1 = @startTime, @endTime1 = @endTime, @breakAllowance1 = @breakAllowance;

declare @tempAXml xml = (
select FaultStart, FaultEnd, DownTime 
from @tempA as A
for xml auto)

declare @tempBXml xml = (
select FaultStart, FaultEnd, DownTime 
from @tempB as B
for xml auto)

-- here you build a single XML with all the data required
set @xml = 
cast(@tempAXml as nvarchar(max)) + 
cast(@tempBXml as nvarchar(max))


select @aLineDownTime as [A Line Down Time], convert(nvarchar, @aLinePercentage) + '%' as [A Line Percentage], @bLineDownTime as [B Line Down Time], convert(nvarchar,  @bLinePercentage) + '%' as [B Line Percentage], @totalDownTime as [Total Down Time],  convert(nvarchar, @totalPercentage) + '%' as [Total Percentage]

select *
FROM @tempA

select *
FROM @tempB

【问题讨论】:

  • 是什么让您相信 XML 是实现此目的的方法?为什么不直接合并您的数据,或者使用三个独立的存储过程?
  • @AdmiralAdama 我的帖子附有链接,昨天在我的问题中,该人也引用了我。我会合并数据,但我的三个中的两个是同一类型,另一个不是。我考虑了三个不同的存储过程,但一个答案我会有 12 个不同的存储过程。这不是很有效。
  • 好的,当您在服务器上运行 SQL 时,@XML 中是否有任何内容或者它是空的?
  • @AdmiralAdama 我认为在您返回输出值之前它会是空的。
  • 你能在 SQL Server 上运行 SQL 吗?并测试一下 XML 是否包含任何内容?您可能必须使用ExecuteXmlReader

标签: c# sql xml stored-procedures sql-server-2012


【解决方案1】:

我认为您需要删除这些最后几行

select @aLineDownTime as [A Line Down Time], convert(nvarchar, @aLinePercentage) + '%' as [A Line Percentage], @bLineDownTime as [B Line Down Time], convert(nvarchar,  @bLinePercentage) + '%' as [B Line Percentage], @totalDownTime as [Total Down Time],  convert(nvarchar, @totalPercentage) + '%' as [Total Percentage]

select *
FROM @tempA

select *
FROM @tempB

如果您的输出参数有效,那么它可能有效,否则您可能需要这样做:

select @xml

结束存储过程。

然后使用ExecuteXmlReader,这是StackOverflow上的示例

【讨论】:

  • 我很感激这个答案,我稍后会回去重试,但现在只是拆分存储过程。没时间玩了。
猜你喜欢
  • 2017-08-24
  • 1970-01-01
  • 1970-01-01
  • 2016-11-03
  • 1970-01-01
  • 2011-05-04
  • 1970-01-01
  • 2014-06-07
  • 2011-01-31
相关资源
最近更新 更多