【问题标题】:SQL Stored Procedure works fine in SQL Server Management Studio, but not in Reporting Services (SSRS)SQL 存储过程在 SQL Server Management Studio 中运行良好,但在 Reporting Services (SSRS) 中却不行
【发布时间】:2016-10-09 19:59:10
【问题描述】:

我有一个程序应该在 SSRS 中构建一份报告,其中包含人员列表的编号,其中 A 列是他们的姓名,B 列和 C 列是他们今年迄今为止的编号(从 1 月到例如 5 月) ),而 D 列和 E 列的数字与上一年相同的月份相同。下面是程序的样子。还;我在这里更改了名称和关键数据,以便您更容易理解,但这可能意味着这里和那里有一个我没有立即发现的轻微错字。参数数据可能是什么的示例在每个参数下方作为注释行放置。

ALTER PROCEDURE [dbo].[number_comparison]
    @resource AS int
    -- retrieves a specific employee, or NULL. NULL on this parameter will retrieve a list of all employees (or all within a given type if the employee_type parameter is set)
    ,@employee_Type AS nvarchar(20)
    -- type will retrieve all employees of a certain type. NULL on this will retrieve all employees regardless of type
    ,@time AS nvarchar(6)
    -- Comes in the form YYYYMM. Cannot be NULL.
AS 
BEGIN

DECLARE @time_last_year nvarchar(6) = CONVERT(nvarchar(6), @time-100);

SELECT 
    fk_resource
    ,SUM(amount) AS sum_amount_last_year
    ,AVG(amount) AS avg_amount_last_year
INTO 
    #lastyearsnumbers
FROM
    datamart.numbers_month
INNER JOIN 
  dvh.resources
  ON
    (resources.pk_resource = fk_resource)
  AND
    (resources.pk_ressurs != -1)
WHERE
  (fk_time LIKE LEFT(@time_last_year,4)+'%')
AND
  (@resource IS NULL OR fk_resource = @resource)
AND
  (@employee_Type IS NULL OR employee_Type = @employeeType)
AND
  (fk_time < ((@time_last_year)+1))
GROUP BY
  fk_resource

SELECT
  fk_resource
  ,name
  ,SUM(amount) AS sum_amount_this_year
  ,AVG(amount) AS avg_amount_this_year
  ,TEMP.sum_amount_last_year
  ,TEMP.avg_amount_last_year
FROM
  datamart.numbers_month 
INNER JOIN 
  dvh.resource
  ON
    (resource.pk_resource = fk_resource)
  AND
    (resource.pk_resource != -1)
LEFT OUTER JOIN
  #lastyearsnumbers TEMP
  ON TEMP.fk_resource = datamart.numbers_month.fk_resource
WHERE
  (fk_time LIKE (LEFT(@time,4))+'%')
AND
  (@resource IS NULL OR fk_resource = @resource)
AND
  (@employee_Type IS NULL OR employee_Type = @employee_Type)
AND
  (fk_time < (@time+1))
GROUP BY
  fk_resource, name, TEMP.sum_amount_last_year, TEMP.avg_amount_last_year

END;

此任务的重点是应该可以检索一年中给定月份的报告,查看从该年一月到所选月份的累计数字是多少,并将其与相同月份进行比较从前一年开始。

它使用左外连接,因为有些员工是新员工,没有去年的任何数字。

当我在 SQL Server Management Studio 中执行此过程时,它运行得非常好。我得到了所有正确的数据和一份员工名单,其中还包括去年没有数据的新员工。

当我在 SSRS 中执行该程序时,我得到一个员工列表,涵盖了拥有今年和去年数据的员工。几乎就像左外连接作为内连接运行一样。

这是什么原因造成的?

【问题讨论】:

  • 在较低的查询中,您在 WHERE GROUP BY 上使用不带别名的 fk_resource。这行得通吗?
  • @vercelli 你发现了我在重命名所有内容时犯的一些错误,以便让你们更容易理解。谢谢你指出。现在应该更正了。
  • 好的,但问题仍然存在:GROUP BY fk_resource, name, TEMP.sum_amount_last_year, TEMP.avg_amount_last_year
  • 据我所知;查询工作不需要别名。就像我说的;这在 SQL Server Management Studio 中运行良好。它在 SSRS 中也可以正常运行。只是连接的数据不正确。
  • 但在GROUP BY fk_resource 中属于#lastyearsnumbers 还是属于datamart.numbers_month

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


【解决方案1】:

我记得在某处读过它(我不记得了),报告向导不喜欢临时表。当我收到评论时,我会更新。但是,与此同时,您能否尝试使用 CTE(公共表表达式)而不是临时表或使用任何临时表来运行相同的查询?

我修改了您的脚本以使用 CTE,如下所示。

    ALTER PROCEDURE [dbo].[number_comparison]
        @resource AS int
        -- retrieves a specific employee, or NULL. NULL on this parameter will retrieve a list of all employees (or all within a given type if the employee_type parameter is set)
        ,@employee_Type AS nvarchar(20)
        -- type will retrieve all employees of a certain type. NULL on this will retrieve all employees regardless of type
        ,@time AS nvarchar(6)
        -- Comes in the form YYYYMM. Cannot be NULL.
    AS 
    BEGIN

    DECLARE @time_last_year nvarchar(6) = CONVERT(nvarchar(6), @time-100);

    WITH cte AS
    (
        SELECT 
            fk_resource
            ,SUM(amount) AS sum_amount_last_year
            ,AVG(amount) AS avg_amount_last_year
        FROM
            datamart.numbers_month
        INNER JOIN 
          dvh.resources
          ON
            (resources.pk_resource = fk_resource)
          AND
            (resources.pk_ressurs != -1)
        WHERE
          (fk_time LIKE LEFT(@time_last_year,4)+'%')
        AND
          (@resource IS NULL OR fk_resource = @resource)
        AND
          (@employee_Type IS NULL OR employee_Type = @employeeType)
        AND
          (fk_time < ((@time_last_year)+1))
        GROUP BY
          fk_resource
    )
    SELECT
      fk_resource
      ,name
      ,SUM(amount) AS sum_amount_this_year
      ,AVG(amount) AS avg_amount_this_year
      ,TEMP.sum_amount_last_year
      ,TEMP.avg_amount_last_year
    FROM
      datamart.numbers_month 
    INNER JOIN 
      dvh.resource
      ON
        (resource.pk_resource = fk_resource)
      AND
        (resource.pk_resource != -1)
    LEFT OUTER JOIN
      cte as TEMP
      ON TEMP.fk_resource = datamart.numbers_month.fk_resource
    WHERE
      (fk_time LIKE (LEFT(@time,4))+'%')
    AND
      (@resource IS NULL OR fk_resource = @resource)
    AND
      (@employee_Type IS NULL OR employee_Type = @employee_Type)
    AND
      (fk_time < (@time+1))
    GROUP BY
      fk_resource, name, TEMP.sum_amount_last_year, TEMP.avg_amount_last_year

    END;

【讨论】:

  • 你是对的; SSRS 不喜欢临时表,这就是使用存储过程完成此操作的原因。 @vercelli 对我最初的问题发表的评论有解决方案!
【解决方案2】:

感谢@vercelli 指出我没有准确指定group by 参数指向的表。 SQL Server Management Studio 本身就知道哪些表在正确的位置,但是当通过 SSRS 运行时,这似乎搞砸了。我给了表格别名,并使用别名在参数上指定了表格,这似乎解决了问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-21
    • 2016-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-12
    • 1970-01-01
    相关资源
    最近更新 更多