Sql server 为什么SQL Where子句值是由用户提供还是嵌入到代码中很重要?

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中的代码 为什么这一变化会导致报告罢工/擅离职守 更具体地说,以下是遗留报告和派生报

我有一个传统的SSRS报告,它按设计工作-返回大量数据

我创建了它的派生,目标是使用特定的值

在旧报表中,值由用户选择,而在派生报表中,值是“烘焙”的

经过多次沙漏和仓鼠笼的叮当声后,派生的报告终于举手说:“在本地报告处理过程中发生了错误。缓冲XML内容所需的大小超过了缓冲区配额。”

一个相关的问题是

这两份报告之间的唯一区别是:

1) 我删除了其中一个参数

2) 在引用该参数的地方,我用一个文本值替换了.rdl中的代码

为什么这一变化会导致报告罢工/擅离职守

更具体地说,以下是遗留报告和派生报告之间的唯一区别:

(一) 遗产:

新的:

(二)

旧的:

新的:

(三)

-与第2条相同)

(四)

旧的:

新的:

(五)

旧的:

新的:


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