【问题标题】:create dataset in SSRS with inline function使用内联函数在 SSRS 中创建数据集
【发布时间】:2016-12-20 21:04:06
【问题描述】:

我有一个基于 SQL 的报表,我正在从 Crystal Reports 迁移到 SSRS。旧方法使用调用存储函数的存储过程。新方法的目的是将所有报表逻辑嵌入到 SSRS 报表中。这背后的原因是存储过程和函数不是目标数据库的一部分。我们不希望有一个仅包含一些存储函数和过程的额外数据库。

现在的基本结构是:

select (a bunch of fields)
from (a bunch of joins)
where (conditions)
    and specific_value in (select value
                           from stored_function(inputs)
                          )

存储的函数会做一些分隔符处理。我需要在 SSRS only 中运行它,而不在数据库中存储任何内容。我可以将存储过程转换为SSRS中的数据集,但我不知道如何处理stored_function。

-----edit ----- 这是问题中的代码:

CREATE FUNCTION [dbo].[fn_split] (
    @SourceString sql_variant,
    @Delimiter nvarchar(10) = N',')
    RETURNS @Values TABLE(Position smallint IDENTITY, cValue varchar(2000) , ncValue nvarchar(2000))
AS
BEGIN
    DECLARE @NormalString varchar(2000), @NationalString nvarchar(2000),
        @NormalDelimiter varchar(10), @NationalDelimiter nvarchar(10),
        @IsNationalChar bit, @Position int,
        @NormalValue varchar(2000), @NationalValue nvarchar(2000)
    SET @Delimiter = COALESCE(@Delimiter, N',')
    SET @IsNationalChar = CASE
                WHEN SQL_VARIANT_PROPERTY(@SourceString,'BaseType') IN ('char','varchar')
                THEN 0
                WHEN SQL_VARIANT_PROPERTY(@SourceString,'BaseType') IN ('nchar','nvarchar')
                THEN 1
                  END
    IF @IsNationalChar IS NULL RETURN
    IF @IsNationalChar = 0
    BEGIN
        SET @NormalDelimiter = @Delimiter
        SET @NormalString = CAST(@SourceString AS varchar(2000))
        IF LEFT(@NormalString,LEN(@NormalDelimiter)) = @NormalDelimiter
            SET @NormalString = SUBSTRING(@NormalString,LEN(@NormalDelimiter) + 1, 2000)
        IF RIGHT(@NormalString,LEN(@NormalDelimiter)) <> @NormalDelimiter
            SET @NormalString = @NormalString + @NormalDelimiter
        WHILE(1 = 1)
        BEGIN
            SET @Position = CHARINDEX(@NormalDelimiter,@NormalString) - 1
            IF @Position <= 0 BREAK
            SET @NormalValue = LEFT(@NormalString,@Position)
            SET @NormalString = STUFF(@NormalString,1,@Position + LEN(@NormalDelimiter),'')
            INSERT INTO @Values(cValue) VALUES(@NormalValue)
        END
    END
    ELSE IF @IsNationalChar = 1
    BEGIN
        SET @NationalDelimiter = @Delimiter
        SET @NationalString = CAST(@SourceString AS varchar(2000))
        IF LEFT(@NationalString,LEN(@NationalDelimiter)) = @NationalDelimiter
            SET @NationalString = SUBSTRING(@NationalString,LEN(@NationalDelimiter) + 1,2000)
        IF RIGHT(@NationalString,LEN(@NationalDelimiter)) <> @NationalDelimiter
            SET @NationalString = @NationalString + @NationalDelimiter
        WHILE(1 = 1)
        BEGIN
            SET @Position = CHARINDEX(@NationalDelimiter,@NationalString) - 1
            IF @Position <= 0 BREAK
            SET @NationalValue = LEFT(@NationalString,@Position)
            SET @NationalString = STUFF(@NationalString,1,@Position + LEN(@NationalDelimiter),'')
            INSERT INTO @Values (ncValue) VALUES(@NationalValue)
        END
    END
    RETURN
END

该函数在查询结束时被调用 (fn_split)。

select (a bunch of fields)
from (a bunch of joins)
where (conditions)
    and specific_value in (select value
                           from stored_function(input_value)
                          )

我试图在不使用数据库对象(函数或过程)的情况下重新创建它。我可以接受 SSRS 报告中的代码。

【问题讨论】:

  • 我不确定 MySQL,但是使用 SQL Server 和 Oracle,您可以将多个值传递给 in 语句,而无需数据库中的“拆分”功能。所以查询会说...where specific_value in (@parameter)
  • 使用动态 sql 在数据集中执行所有这些操作是什么意思?
  • 这是 MSSQL,不是 MYSQL,这是我在上面标签中的错误。存储的函数接受一个字符串参数,并对其进行一系列字符串操作,以创建一个可能与 specific_value 匹配的可能答案列表。我根本不能使用存储函数,所以我需要将该功能作为数据集查询的一部分或报告的代码。
  • 如果行数不多,将所有内容都带入报表并在那里进行过滤计算。如果您需要过滤查询以提高效率,则必须将其包含在查询中。除了“是的,你能做到!去争取”之外,我不确定你在寻找什么“答案”。
  • 您可以使用 CROSS APPLY 或 CTE,并将声明移至代码开头。

标签: sql-server stored-procedures reporting-services sql-function


【解决方案1】:

只是一个想法。您可以使用 2 个数据集:

select (a bunch of fields)
from (a bunch of joins)
where (conditions)
and specific_value in @Algo

select value 
from stored_function(inputs)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    相关资源
    最近更新 更多