Sql server 为什么SQL Where子句值是由用户提供还是嵌入到代码中很重要?
我有一个传统的SSRS报告,它按设计工作-返回大量数据 我创建了它的派生,目标是使用特定的值 在旧报表中,值由用户选择,而在派生报表中,值是“烘焙”的 经过多次沙漏和仓鼠笼的叮当声后,派生的报告终于举手说:“在本地报告处理过程中发生了错误。缓冲XML内容所需的大小超过了缓冲区配额。” 一个相关的问题是 这两份报告之间的唯一区别是: 1) 我删除了其中一个参数 2) 在引用该参数的地方,我用一个文本值替换了.rdl中的代码 为什么这一变化会导致报告罢工/擅离职守 更具体地说,以下是遗留报告和派生报告之间的唯一区别: (一) 遗产: 新的: (二) 旧的: 新的: (三) -与第2条相同) (四) 旧的: 新的: (五) 旧的: 新的:Sql server 为什么SQL Where子句值是由用户提供还是嵌入到代码中很重要?,sql-server,tsql,stored-procedures,reporting-services,rdl,Sql Server,Tsql,Stored Procedures,Reporting Services,Rdl,我有一个传统的SSRS报告,它按设计工作-返回大量数据 我创建了它的派生,目标是使用特定的值 在旧报表中,值由用户选择,而在派生报表中,值是“烘焙”的 经过多次沙漏和仓鼠笼的叮当声后,派生的报告终于举手说:“在本地报告处理过程中发生了错误。缓冲XML内容所需的大小超过了缓冲区配额。” 一个相关的问题是 这两份报告之间的唯一区别是: 1) 我删除了其中一个参数 2) 在引用该参数的地方,我用一个文本值替换了.rdl中的代码 为什么这一变化会导致报告罢工/擅离职守 更具体地说,以下是遗留报告和派生报
SQL中的参数在确定特定语句的执行计划方面起着重要作用。例如,如果一个查询有一个变量和一个硬编码的文本,SQL可能会为此创建两个完全不同的计划。在WHERE子句中添加/删除搜索参数也很可能会导致更改使用的索引。同样,如果一个计划已经使用了很长时间,然后您对其进行了更改,即使是很小的更改,它现在也需要经历构建新计划、优化计划、缓存计划(如果可行)等额外开销
简言之,这一看似微小的变化很可能完全改变了你的执行计划。这可能会在性能方面产生各种意想不到的结果。我建议在删除所有输出(打印/选择)的情况下运行两个不同的版本(我希望这将降低内存使用并允许第二个版本完成?),并查看是否可以捕获实际的执行计划。它可能会揭示出它的不同之处,以及为什么它会突然花费很长时间,最终失败。您似乎在调用两个完全独立的存储过程sp_ViewPriceMatrix_Variance_RockBottom和ViewPriceMatrix_CraftworksRollup_oldchago。无论您在SSRS定义中做了哪些更改,都是您需要查看的基础数据查询之间的差异。我怀疑它们非常不同。你应该看看这两份报告的执行计划。这很诱人,但我真的只想执行其中一份;问题是:断头台,或绞索。更新中有两点:1)删除并重新创建查询的事实有点问题。我的理解是,每次这种情况发生时,它都会破坏您相关的执行计划以及手动授予此过程的任何权限。这意味着每次重新创建Proc时,它都必须重新生成计划。另一件事是,您的
WHERE Unit='OLD CHICAGO'
意味着过程没有参数化。它将尝试并优化“老芝加哥”;任何其他值都将创建一个全新的计划。对于我上面的评论:删除和重新创建可能是一个问题。在很多情况下,让it检查其执行计划并重新优化是一件好事,但可能会导致一些意外的结果。如果您所做的只是创建一个硬编码为“Old Chicago”的版本,那么您是否可以重用现有的存储过程?制作RDL的副本。在新的RDL中,将Unit参数设置为Old Chicago的默认值,然后将其设置为“Internal”,这样就不会向用户公开。不,它们几乎相同,只是其中一个允许用户选择单位,而另一个是硬编码的。我看到您的编辑现在有了它。通过将其作为文本包含,您可能会更改整个查询计划。我建议您将这两个存储过程调用放入SQL Server Management Studio,并对它们执行查询执行计划—我怀疑它们的查询计划可能非常不同。我不相信你的问题是SSRS-我认为你的问题是SQL Server的效率。我不得不说,我真的很怀疑游标循环会生成动态SQL——我知道SSRS经常这样做,但对于选择不当的SQL代码来说,这真是一个叫嚣。
<DataSetName>CPSData</DataSetName>
<DataSetName>DataSetOldChicago</DataSetName>
<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>
<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>
<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>
<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>
<ReportParameter Name="SortBy">
<DataType>String</DataType>
<Prompt>Sort By</Prompt>
</ReportParameter>
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
where up.Unit = @Unit
where up.Unit = 'OLD CHICAGO'
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 +'''')
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
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