我有一份按设计运行的旧SSRS报告 - 返回大量数据。
我创建了一个针对使用特定值的派生。
IOW,在旧版报告中,该值由用户选择,而在派生报告中,它是“烘焙”。
派生的报告经过大量的沙漏和仓鼠笼子的嘎嘎声后,终于举起手来说:“在本地报告处理期间发生了错误。缓冲XML内容所需的大小超过了缓冲区配额。”
相关问题是here。
两份报告之间的唯一区别是:
1)我删除了其中一个参数
2)在引用该参数的情况下,我将.rdl中的代码替换为文字值。
为什么这种改变会导致报告继续罢工/罢工?
更具体地说,以下是旧报告与派生报告之间的唯一区别:
1) 遗留:
<DataSetName>CPSData</DataSetName>
新:
<DataSetName>DataSetOldChicago</DataSetName>
2) 遗留:
<Value>=Parameters!Unit.value+", For Price Period: "+Parameters!BegDate.value+" - "+Parameters!EndDate.value</Value>
新:
<Value>="For Price Period: "+Parameters!BegDate.value+" - "+Parameters!EndDate.value</Value>
3) 遗留:
<DataSet Name="CPSData">
<Query>
<DataSourceName>CPSData</DataSourceName>
<QueryParameters>
<QueryParameter Name="@Unit">
<Value>=Parameters!Unit.Value</Value>
</QueryParameter>
<QueryParameter Name="@BegDate">
<Value>=Parameters!BegDate.Value</Value>
</QueryParameter>
<QueryParameter Name="@EndDate">
<Value>=Parameters!EndDate.Value</Value>
</QueryParameter>
<QueryParameter Name="@SortBy">
<Value>="Products"</Value>
</QueryParameter>
</QueryParameters>
<CommandType>StoredProcedure</CommandType>
<CommandText>sp_ViewPriceMatrix_Variance_RockBottom</CommandText>
<rd:UseGenericDesigner>true</rd:UseGenericDesigner>
</Query>
新:
<DataSet Name="DataSetOldChicago">
<Query>
<DataSourceName>CPSData</DataSourceName>
<QueryParameters>
<QueryParameter Name="@BegDate">
<Value>=Parameters!BegDate.Value</Value>
</QueryParameter>
<QueryParameter Name="@EndDate">
<Value>=Parameters!EndDate.Value</Value>
</QueryParameter>
<QueryParameter Name="@SortBy">
<Value>=Parameters!SortBy.Value</Value>
</QueryParameter>
</QueryParameters>
<CommandType>StoredProcedure</CommandType>
<CommandText>ViewPriceMatrix_CraftworksRollup_OldChicago</CommandText>
</Query>
由于某种原因,顺序略有不同 - 我不知道为什么会这样,但无法想象这会导致问题(字段列在哪个顺序)。
4) 遗留:
<DataSet Name="UnitDS">
<Query>
<DataSourceName>CPSData</DataSourceName>
<CommandText>select Unit from MasterUnits order by Unit</CommandText>
<rd:UseGenericDesigner>true</rd:UseGenericDesigner>
</Query>
<Fields>
<Field Name="Unit">
<DataField>Unit</DataField>
<rd:TypeName>System.String</rd:TypeName>
</Field>
</Fields>
</DataSet>
新:
缺少,因为用户不再选择单位
5) 遗留:
<ReportParameter Name="Unit">
<DataType>String</DataType>
<AllowBlank>true</AllowBlank>
<Prompt>Unit</Prompt>
<ValidValues>
<DataSetReference>
<DataSetName>UnitDS</DataSetName>
<ValueField>Unit</ValueField>
<LabelField>Unit</LabelField>
</DataSetReference>
</ValidValues>
</ReportParameter>
新:
失踪 - 现在按字面意思提供。
6) 遗留:
[这里没什么]
新:
<ReportParameter Name="SortBy">
<DataType>String</DataType>
<Prompt>Sort By</Prompt>
</ReportParameter>
- 所以新的/不工作的报告有这个“SortBy”参数,它被隐藏并提供了一个默认值。但是另一个派生报告具有相同的参数设置,并且没有问题。
关于为什么这个问题会引起类似食人魔的面貌的任何想法?
旧(工作)和派生(非工作)SP之间的差异是:
1)
旧:
ALTER Procedure [dbo].[sp_ViewPriceMatrix_Variance_test2]
@Unit varchar(4000),
@BegDate datetime,
@EndDate datetime,
@SortBy varchar(20)
新:
IF OBJECT_ID ( 'ViewPriceMatrix_CraftworksRollup_OldChicago', 'P' ) IS NOT NULL
DROP PROCEDURE ViewPriceMatrix_CraftworksRollup_OldChicago;
GO
CREATE PROCEDURE [dbo].[ViewPriceMatrix_CraftworksRollup_OldChicago]
@BegDate datetime,
@EndDate datetime
2)
旧:
where up.Unit = @Unit
新:
where up.Unit = 'OLD CHICAGO'
3)
- 同为2)
4)
旧:
Select @Statement = ('Update #TempContract Set [' + @PriceWeek + ']=''' + IsNull(@Price,'0.00') + ''' where ItemCode=''' + @ItemCode + ''' and Unit=''' + @Unit + ''' and [ShortName]=''' + @ShortName +'''')
新:
Select @Statement = ('Update #TempContract Set [' + @PriceWeek + ']=''' + IsNull(@Price,'0.00') + ''' where ItemCode=''' + @ItemCode + ''' and Unit=''''OLD CHICAGO'''' and [ShortName]=''' + @ShortName +'''')
5)
旧:
fetch next from SetPriceWeekSQL into @PriceWeek, @BegDate
while @@fetch_status = 0
begin
SET @Week = @Week + 1
IF(@SQLstring='')
Begin
SET @SQLstring = @SQLstring + 'Insert Into #Temp Select Unit, ShortName, ItemCode, Description, regionorder, Contractprice, IsNull('+
'['+@PriceWeek+'],''0.00'') as Price, (convert(decimal(10,3),''-0.001'')) as Variance,
'''+@PriceWeek+''' as PriceWeek, ''WK'+convert(varchar(2),@Week)+''' as Week From #TempContract'+@WherePriceWeek
IF(@SortBy='Members')
Begin
SET @SQLstring = @SQLstring + ' UNION Select Unit, ShortName, '''', ''zzzz'', '''', '''', ''0'' as Price, ''-0.001'' as Variance, '''' as PriceWeek, ''WK'+convert(varchar(2),@Week)+''' as Week From #TempContract'+@WherePriceWeek
End
Else
Begin
SET @SQLstring = @SQLstring + ' UNION Select Unit, '''', ItemCode, Description, ''1000'', Contractprice, ''0'' as Price, ''-0.001'' as Variance, '''' as PriceWeek, ''WK'+convert(varchar(2),@Week)+''' as Week From #TempContract'+@WherePriceWeek
End
End
ELSE
Begin
SET @SQLstring = @SQLstring + ' UNION '
SET @SQLstring = @SQLstring + 'Select Unit, ShortName, ItemCode, Description, regionorder, Contractprice, IsNull('+
'['+@PriceWeek+'],''0.00'') as Price, IsNull(convert(decimal(10,2),['+@PriceWeek+'])-convert(decimal(10,2),['+@LastPriceWeek+']),''0.00'') as Variance,
'''+@PriceWeek+''' as PriceWeek, ''WK'+convert(varchar(2),@Week)+''' as Week From #TempContract'+@WherePriceWeek
IF(@SortBy='Members')
Begin
SET @SQLstring = @SQLstring + ' UNION Select Unit, ShortName, '''', ''zzzz'', '''', '''', ''0'' as Price, ''0'' as Variance, '''' as PriceWeek, ''WK'+convert(varchar(2),@Week)+''' as Week From #TempContract Where IsNull(['+@LastPriceWeek+'],''0.00'')
<> ''0.00'' or IsNull(['+@PriceWeek+'],''0.00'') <> ''0.00'' '
End
Else
Begin
SET @SQLstring = @SQLstring + ' UNION Select Unit, '''', ItemCode, Description, ''1000'', Contractprice, ''0'' as Price, ''0'' as Variance, '''' as PriceWeek, ''WK'+convert(varchar(2),@Week)+''' as Week From #TempContract Where IsNull(['+@LastPriceWeek+'],''0.00'') <> ''0.00'' or IsNull(['+@PriceWeek+'],''0.00'') <> ''0.00'' '
End
End
新:
fetch next from SetPriceWeekSQL into @PriceWeek, @BegDate
while @@fetch_status = 0
begin
SET @Week = @Week + 1
IF(@SQLstring='')
Begin
SET @SQLstring = @SQLstring + 'Insert Into #Temp Select Unit, ShortName, ItemCode, Description, regionorder, Contractprice, IsNull('+
'['+@PriceWeek+'],''0.00'') as Price, (convert(decimal(10,3),''-0.001'')) as Variance,
'''+@PriceWeek+''' as PriceWeek, ''WK'+convert(varchar(2),@Week)+''' as Week From #TempContract'+@WherePriceWeek
SET @SQLstring = @SQLstring + ' UNION Select Unit, '''', ItemCode, Description, ''1000'', Contractprice, ''0'' as Price, ''-0.001'' as Variance, '''' as PriceWeek, ''WK'+convert(varchar(2),@Week)+''' as Week From #TempContract'+@WherePriceWeek
End
ELSE
Begin
SET @SQLstring = @SQLstring + ' UNION '
SET @SQLstring = @SQLstring + 'Select Unit, ShortName, ItemCode, Description, regionorder, Contractprice, IsNull('+
'['+@PriceWeek+'],''0.00'') as Price, IsNull(convert(decimal(10,2),['+@PriceWeek+'])-convert(decimal(10,2),['+@LastPriceWeek+']),''0.00'') as Variance,
'''+@PriceWeek+''' as PriceWeek, ''WK'+convert(varchar(2),@Week)+''' as Week From #TempContract'+@WherePriceWeek
SET @SQLstring = @SQLstring + ' UNION Select Unit, '''', ItemCode, Description, ''1000'', Contractprice, ''0'' as Price, ''0'' as Variance, '''' as PriceWeek, ''WK'+convert(varchar(2),@Week)+''' as Week From #TempContract Where IsNull(['+@LastPriceWeek+'],''0.00'') <> ''0.00'' or IsNull(['+@PriceWeek+'],''0.00'') <> ''0.00'' '
End
SET @LastPriceWeek = @PriceWeek
fetch next from SetPriceWeekSQL into @PriceWeek, @BegDate
end
6)
旧:
IF(@SortBy='Members')
Begin
Select
Unit,
ShortName,
ItemCode,
Description,
regionorder,
Contractprice,
convert(varchar(20),convert(decimal(10,2),Price)) as Price,
sum(convert(money,Variance)) as Variance,
VarianceAverage = convert(varchar(25),convert(decimal(10,2),(Select sum(convert(money,Variance)) From #Temp Where ShortName=T.ShortName and Week=T.Week) / Replace(((Select count(regionorder) From #Temp Where ShortName=T.ShortName and Week=T.Week)-count(
Variance)),'0','1'))),
PriceWeek,Week
From #Temp T
Group By
Unit,
ShortName,
ItemCode,
Description,
regionorder,
Contractprice,
Price,
PriceWeek,Week
Order By Week,ShortName,Description
End
ELSE
Begin
Select
Unit,
ShortName,
ItemCode,
Description,
regionorder,
Contractprice,
convert(varchar(20),convert(decimal(10,2),Price)) as Price,
sum(convert(money,Variance)) as Variance,
VarianceAverage = convert(varchar(25),convert(decimal(10,2),(Select sum(convert(money,Variance)) From #Temp Where ItemCode=T.ItemCode and Week=T.Week) / Replace(((Select count(regionorder) From #Temp Where ItemCode=T.ItemCode and Week=T.Week)-count(Variance)),'0','1'))),
PriceWeek,Week
From #Temp T
Group By
Unit,
ShortName,
ItemCode,
Description,
regionorder,
Contractprice,
Price,
PriceWeek,Week
Order By Week,Description,regionorder
End
新:
Select
Unit,
ShortName,
ItemCode,
Description,
regionorder,
Contractprice,
convert(varchar(20),convert(decimal(10,2),Price)) as Price,
sum(convert(money,Variance)) as Variance,
VarianceAverage = convert(varchar(25),convert(decimal(10,2),(Select sum(convert(money,Variance)) From #Temp Where ItemCode=T.ItemCode and Week=T.Week) / Replace(((Select count(regionorder) From #Temp Where ItemCode=T.ItemCode and Week=T.Week)-count(Variance)),'0','1'))),
PriceWeek,Week
From #Temp T
Group By
Unit,
ShortName,
ItemCode,
Description,
regionorder,
Contractprice,
Price,
PriceWeek,Week
Order By Week,Description,regionorder
答案 0 :(得分:1)
SQL中的参数在如何确定特定语句的执行计划方面起着重要作用。例如,如果查询具有变量vs硬编码的文字,则SQL可能会为此创建两个完全不同的计划。在WHERE子句中添加/删除搜索参数也很可能会导致更改索引。同样,如果一个计划已经使用多年,然后你改变它,甚至稍微改变它,现在需要经历建立新计划,优化它,缓存它(如果可行)等的额外开销...... / p>
简而言之,这个看似很小的变化很可能完全改变了您的执行计划。在性能方面,这可能会产生各种意想不到的结果。我建议运行你的两个不同的版本,删除所有输出(PRINT / SELECT)(我希望这会降低内存使用量并允许你的第二个版本完成?)并看看你是否可以捕获实际执行计划。它可能会对它的不同做法有所了解,以及为什么它会突然耗尽并最终失败。
答案 1 :(得分:1)
您似乎正在调用两个完全独立的存储过程sp_ViewPriceMatrix_Variance_RockBottom和ViewPriceMatrix_CraftworksRollup_OldChicago。无论您在SSRS定义中所做的更改,您需要查看的基础数据查询之间的差异。我怀疑他们非常不同。