【问题标题】:Trying to write dynamic parameter stored procedure尝试编写动态参数存储过程
【发布时间】:2016-06-22 19:02:16
【问题描述】:

我正在尝试编写一个动态参数存储过程来输入 SSRS 报告。我在浏览了很多网站后写了这篇文章,寻找允许我的最终用户自定义选择他们想要使用的参数的方法。该过程中的一个额外问题是,如果没有在范围上使用 End 参数,则假定最终用户只对 Start 字段中输入的值感兴趣。

这是我目前所拥有的。为什么我在尝试运行报告时会锁定 SSRS?

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[BrowseCODA] 
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @DocList TABLE ([DocumentID] varchar(32) ) 

    DECLARE @GLAccountStart int = NULL
    DECLARE @GLAccountEnd int = NULL
    DECLARE @CustomerID int = NULL
    DECLARE @VendorID int = NULL
    DECLARE @StoreID nvarchar(2) = NULL
    DECLARE @DocDateStart date = NULL
    DECLARE @DocDateEnd date = NULL
    DECLARE @InputDateStart date = NULL
    DECLARE @InputDateEnd date = NULL
    DECLARE @AcctPeriodStart int = NULL
    DECLARE @AcctPeriodEnd int = NULL
    DECLARE @AcctYearStart int = NULL
    DECLARE @AcctYearEnd int = NULL
    DECLARE @PaymentID int = NULL
    DECLARE @ExtRef1 nvarchar(30) = NULL
    DECLARE @ExtRef2 nvarchar(30) = NULL
    DECLARE @ExtRef3 nvarchar(30) = NULL
    DECLARE @ExtRef4 nvarchar(30) = NULL
    DECLARE @ExtRef5 nvarchar(30) = NULL
    DECLARE @ExtRef6 nvarchar(30) = NULL

    INSERT INTO @DocList( [DocumentID] )
       SELECT
           company + '-' + FullDocNumber
       FROM 
           [DataWarehouse].[dbo].[VDocDetails]
       WHERE 
           ([GLAccount] >= @GLAccountStart OR @GLAccountStart IS NULL) 
           AND ((@GLAccountEnd IS NULL AND @GLAccountStart IS NOT NULL 
                 AND [GLAccount]=@GLAccountStart) 
                 OR (@GLAccountEnd IS NOT NULL AND [GLAccount] <= @GLAccountEnd) 
                 OR (@GLAccountEnd IS NULL))
           AND ([CustomerNumber] = @CustomerID OR @CustomerID IS NULL)
           AND ([Vendor] = @VendorID OR @VendorID IS NULL)
           AND ([Store] LIKE @StoreID+'%' OR @StoreID IS NULL)
           AND ([Doc_Date] >= @DocDateStart OR @DocDateStart IS NULL)
           AND ((@DocDateEnd IS NULL AND @DocDateStart IS NOT NULL 
                 AND [Doc_Date] = @DocDateStart) 
                OR (@DocDateEnd IS NOT NULL AND [Doc_Date] <= @DocDateEnd) 
                OR (@DocDateEnd IS NULL))
           AND ([Input_Date] >= @InputDateStart OR @InputDateStart IS NULL)
           AND ((@InputDateEnd IS NULL AND @InputDateStart IS NOT NULL
                 AND [Input_Date] = @InputDateStart) 
                OR (@InputDateEnd IS NOT NULL AND [Input_Date] <= @InputDateEnd)
                OR (@InputDateEnd IS NULL))
          AND ([period] >= @AcctPeriodStart OR @AcctPeriodStart IS NULL)
          AND ((@AcctPeriodEnd IS NULL AND @AcctPeriodStart IS NOT NULL 
                AND [period] = @AcctPeriodStart) 
               OR (@AcctPeriodEnd IS NOT NULL AND [period] <= @AcctPeriodEnd) 
               OR (@AcctPeriodEnd IS NULL))
          AND ([Year] >= @AcctYearStart OR @AcctYearStart IS NULL)
          AND ((@AcctYearEnd IS NULL AND @AcctYearStart IS NOT NULL 
                AND [Year] = @AcctYearStart) 
               OR (@AcctYearEnd IS NOT NULL AND [Year] <= @AcctYearEnd) 
               OR (@AcctYearEnd IS NULL))
          AND ([PaymentID] = @PaymentID OR @PaymentID IS NULL)
          AND ([Reference1] LIKE @ExtRef1+'%' OR @ExtRef1 IS NULL)
          AND ([Reference2] LIKE @ExtRef2+'%' OR @ExtRef2 IS NULL)
          AND ([Reference3] LIKE @ExtRef3+'%' OR @ExtRef3 IS NULL)
          AND ([Reference4] LIKE @ExtRef4+'%' OR @ExtRef4 IS NULL)
          AND ([Reference5] LIKE @ExtRef5+'%' OR @ExtRef5 IS NULL)
          AND ([Reference6] LIKE @ExtRef6+'%' OR @ExtRef6 IS NULL)

    SELECT
        *
    FROM 
        [DataWarehouse].[dbo].[VDocDetails]
    WHERE  
        company + '-' + FullDocNumber IN (SELECT DocumentID FROM @DocList)
END
GO

【问题讨论】:

  • 不确定为什么它被锁定,但存储过程的参数通常会在 CREATE/ALTER 和 AS BEGIN 之间显示为逗号分隔的列表,没有 DECLARE。
  • 这个存储过程是如何使用的?我的意思是,您如何设置变量的值?您没有在过程级别声明它们,因此所有变量都为 NULL。

标签: sql-server tsql reporting-services


【解决方案1】:

回答您的问题:
因为您没有向存储过程提供任何变量,所以所有内部变量都是 NULL。这意味着必须提取表中的所有记录。这会导致使用临时变量对可能非常大的表 + 内存问题进行双重扫描。 起初,您可能会编写如下代码:

CREATE PROCEDURE [dbo].[BrowseCODA] 
@GLAccountStart int = NULL
, @GLAccountEnd int = NULL
, @CustomerID int = NULL
, @VendorID int = NULL
, @StoreID nvarchar(2) = NULL
, @DocDateStart date = NULL
, @DocDateEnd date = NULL
, @InputDateStart date = NULL
, @InputDateEnd date = NULL
, @AcctPeriodStart int = NULL
, @AcctPeriodEnd int = NULL
, @AcctYearStart int = NULL
, @AcctYearEnd int = NULL
, @PaymentID int = NULL
, @ExtRef1 nvarchar(30) = NULL
, @ExtRef2 nvarchar(30) = NULL
, @ExtRef3 nvarchar(30) = NULL
, @ExtRef4 nvarchar(30) = NULL
, @ExtRef5 nvarchar(30) = NULL
, @ExtRef6 nvarchar(30) = NULL

AS
BEGIN
SET NOCOUNT ON;

其次,不要使用临时表变量,直接从表中报告。 第三,最好使用动态 SQL 来构建仅使用 OPTION RECOMPILE 的非 NULL 值的查询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-11
    • 1970-01-01
    • 2017-08-22
    • 2015-04-24
    • 2018-01-27
    相关资源
    最近更新 更多