【问题标题】:Visual Studio: How do you allow a blank value or not having to select a value which defaults to an ALL?Visual Studio:如何允许空白值或不必选择默认为 ALL 的值?
【发布时间】:2012-09-19 19:47:08
【问题描述】:

我通过 Visual Studio 设置了一个非常基本的 SSRS 报告。到目前为止,我设置的参数没有“允许空白值”、“允许空值”和“允许多个值”,但我尝试使用它们没有运气。允许空白值和允许空值似乎根本不起作用。

预览中还是弹出“请为参数‘xxxx’选择一个值。

我尝试在主数据集查询中处理“column = @column”与“column IN @column”查询。 我还搜索了谷歌并将额外的数据集查询设置为“从列不为空的表中选择不同的列” 我还尝试在查询中使用 UNION,它让我可以选择“NULL”作为选项,但 null 不包含所有内容,因此结果什么也没给我......

有谁知道解决方法或如何获取单个参数以在将其设置为全选的地方选择不需要的选项?

任何帮助将不胜感激!谢谢大家!

-编辑 这就是我的查询“SELECT DOCDATE, DOCID, CUSTNMBR, CUSTNAME, DOCAMNT FROM SOP30200 WHERE (DOCDATE BETWEEN @Fromdate AND @Todate) GROUP BY DOCDATE, DOCID, CUSTNMBR, CUSTNAME, DOCAMNT HAVING (CUSTNMBR = @Custnmbr OR @ Custnmbr IS NULL) AND (DOCID IN (@DocID) OR @DocID IS NULL)”,但我仍然无法将 docID 部分设为空白。上面那是什么,我还需要一个 SP 或者你下面的例子中的东西?

【问题讨论】:

  • 更改如果我的回答为您提供了足够的信息,请接受它。
  • 您需要在 where 子句中添加条件,而不是在 having 语句 WHERE CUSTNMBR = @CUSTNMBR OR @CUSTNUMBR IS NULL

标签: visual-studio-2010 visual-studio visual-studio-2008 reporting-services


【解决方案1】:

通过设置 allow null 值,您表示您的数据集看起来像这样:

CREATE PROCEDURE myRSStoredProcedure
 @MyParameter varchar(50)=NULL
 --more code
 SELECT * FROM MyTable WHERE (MyField=@MyParameter OR @MyParameter IS NULL)

END

也就是说,NULL 是一个有效值,并且在您的存储过程中的某处被引用,请注意 WHERE (MyField=@MyParameter OR @MyParameter IS NULL) 部分处理它的值或 NULL。如果您不包含OR @MyParameter IS NULL 而您所拥有的只是WHERE MyField=@MyParameter,那么考虑到您没有解决它们,您将如何期望RS“允许空值”。

对于允许多个值,这只是 Reporting Services 中允许进行多项选择的指示器。您仍然需要处理数据集中的逗号分隔值(您的存储过程),您不能只说:

SELECT * FROM MyTable WHERE ID IN (@MyParam)

这样不行。解决此问题的方法是创建一个表值函数,该函数接受一个 CSV 列表并返回一个整数表。这是一个例子:

CREATE Function [dbo].[CsvToInt] ( @Array varchar(1000)) 
returns @IntTable table 
    (IntValue int)
--Parse comma seperated value parameters
--To be used in SELECT blah WHERE blah IN (...)
--This function returns int, but may be modified to return any datatype
AS
begin

    declare @separator char(1)
    set @separator = ','

    declare @separator_position int 
    declare @array_value varchar(1000) 

    set @array = @array + ','

    while patindex('%,%' , @array) <> 0 
    begin

      select @separator_position =  patindex('%,%' , @array)
      select @array_value = left(@array, @separator_position - 1)

        Insert @IntTable
        Values (Cast(@array_value as int))

      select @array = stuff(@array, 1, @separator_position, '')
    end

    return
end

最后,包含“所有”数据而不是空选择的一种巧妙方法是创建两个数据集,这意味着给我所有数据。第一个数据集是您的参数,例如您可能拥有的客户:

SELECT
  1 As SortOrder
  CustomerID,
  Customer
FROM
  MyCustomers
UNION ALL
SELECT
  0 As SortOrder
  0 As CustomerID,
  'All' As Customer
ORDER BY
  SortOrder,
  Customer

这将列出顶部带有单词 All 的所有客户(注意 SortOrder)。 然后您的 RS 报告参数可以将默认值指定为 0(如果您使用 CustomerID)或All(如果您使用实际客户名称)。然后,您的报告数据集将执行以下操作:

CREATE PROCEDURE rsp_MainReport
@CustomerID int = 0  --this could also be @CustomerID varchar(50)='All'
--more code
SELECT Blah FROM MyTable WHERE (CustomerID = @CustomerID OR @CustomerID=0) 
--or you could of done WHERE (Customer = @Customer OR @Customer='All')

我将发布一个我为您完成的示例,这是一个参数数据集:

SELECT 
                    1 as SortOrder,
                    FacilityID,
                    Facility
                FROM
                    Facility
                UNION ALL
                SELECT
                    0 as SortOrder,
                    0 as FacilityID,
                    'All' as Facility
                ORDER BY 
                    SortOrder,
                    Facility

结果如下:

然后你可以在你的主数据集(你的报告的数据集)中使用它:

CREATE PROCEDURE rsp_QuikFixStats_ByFacilityCategory
    -- Add the parameters for the stored procedure here
    @FacilityID bigint=0,
    @StartDate datetime=NULL,
    @EndDate datetime=NULL

AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    SELECT 
        f.Facility,
        c.Category, 
        COUNT(t.TicketID) AS TotalNumberOfTickets,
        SUM(CASE WHEN ClosedDate IS NULL AND TargetDate IS NOT NULL THEN 1 ELSE 0 END) AS TotalNumberOfOpenTickets,
        SUM(CASE WHEN ClosedDate IS NOT NULL THEN 1 ELSE 0 END) AS TotalNumberOfClosedTickets,
        SUM(CASE WHEN TargetDate IS NULL AND ClosedDate IS NULL THEN 1 ELSE 0 END) AS TotalNumberOfWaitForTickets,
        SUM(CASE WHEN TargetDate IS NOT NULL AND ClosedDate IS NULL AND TargetDate < GetDate() THEN 1 ELSE 0 END) AS TotalNumberOfOverdueTickets
    FROM 
        Ticket t
    INNER JOIN
        Facility f
    ON
        f.FacilityID = t.FacilityID
    INNER JOIN
        Category c
    ON
        c.CategoryID = t.CategoryID
    WHERE 
        (f.Inactive=0)
        AND (f.FacilityID = @FacilityID OR @FacilityID=0)
        AND (t.OpenDate >= @StartDate OR @StartDate IS NULL)
        AND (t.OpenDate <= @EndDate OR @EndDate IS NULL)
    GROUP BY
        f.Facility,
        c.Category
    ORDER BY
        f.Facility,
        COUNT(t.TicketID) DESC,
        c.Category      
END
GO

报告参数如下所示:

【讨论】:

  • 感谢 JonH 的快速回复。我对 SQL 还是很陌生。我只知道如何四处查询。我不知道 T-SQL 或如何创建存储过程。 “允许空白值”选项怎么样?我尝试使用它,但它根本不起作用......仍然需要我选择一个值。
  • @JaeChang - 在不知道存储过程的情况下如何创建数据集?在这种情况下,您将直接在报告服务中创建表直接查询以显示数据。我个人不建议这样做...即使您使用直接表,您的查询也可以是SELECT blah FROM MyTable WHERE MyField=@MyParam OR MyParam IS NULL
  • 是的,我在 Visual Studio Reporting(称为报告服务?)中使用直接查询来创建我的数据集。你有什么不推荐的理由吗?
  • 我个人认为存储过程层允许额外的安全性和灵活性,例如为不同的报表甚至该报表上的对象重用相同的存储过程。直接表变得复杂,因为您最终会直接从 RS 中获得一堆直接连接和数据选择。我喜欢将其抽象到数据库级别。所有 RS 都知道存在一个存储过程(有点像黑盒子)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多