我正在尝试编写动态参数存储过程以提供给SSRS报告。我在浏览了很多网站之后写了这篇文章,寻找方法让我的最终用户可以自定义他们想要使用的参数。在此过程中添加的扭结是,如果在范围上没有使用End参数,则假定最终用户仅对在“开始”字段中输入的值感兴趣。
这是我到目前为止所拥有的。我尝试运行报告时为什么要锁定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
答案 0 :(得分: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值的查询。