【问题标题】:Issue with result set from stored procedure report generation存储过程报告生成的结果集问题
【发布时间】:2017-02-23 23:34:01
【问题描述】:

我有一个基于 Visual Studio 的存储过程,可为每月审计过程生成报告。在被查询的数据库中,每个月的所有数据都存在于它自己的单独表中(Contacts_month_1、Contacts_month_2 等)

此报告生成中使用的 SQL 包含一些次要逻辑,以使其能够动态工作,而不是使用硬编码日期。问题出现在 2017 年 1 月开始,当时我不仅开始收到上个月的结果,还收到上一年的结果。具体而言,2016 年 12 月的审计报告包括 2016 年 12 月和 2015 年 12 月的数据。最初,我认为这是基于年初的某种侥幸,我们还没有在转年期间进行这种自动化流程。不幸的是,当我今天进入办公室时,在 2017 年 1 月的输出文件中,我也收到了 2016 年 1 月的结果。

我尝试在流程中包含一年检查,但我仍然得到相同的结果输出。任何想法将不胜感激。

Declare @GetMonth TinyInt
,@SessionTable varchar(50)
,@ContactTable varchar(50)
,@TableVersion varchar(2)
Declare @GetYear SmallInt
,@SessionTable_year varchar(50)
,@ContactTable_year varchar(50)
,@TableVersion_year varchar(4)

Set @GetMonth=MONTH(cast(GetDate() as Datetime))-1 
Set @GetYear=YEAR(cast(GetDate() as Datetime))

If (@getmonth=0) Set @GetMonth=12 + (@GetYear-1)

Set @TableVersion=CAST(@getMonth as varchar(2)) 
Set @SessionTable='[CentralDWH].[dbo].[Sessions_month_' +@tableversion +']'
Set @ContactTable ='[CentralDWH].[dbo].[Contacts_month_' +@tableversion +']'

-- Select @GetMonth,@GetYear (DEBUGGING STATEMENT)
-- Select @SessionTable,@ContactTable (DEBUGGING STATEMENT)


Exec('SELECT [PBX_id] as AgentID 
            ,[p22_value] as Skill
            ,''Athens'' as Location
            ,Convert(varchar(20),c.[local_start_time],120) as local_start_time
            ,convert(varchar(20),c.[local_end_time],120) as local_end_time
            ,U.[USER_NAME] 
            ,call_id
      FROM '+@SessionTable +' S
           Inner join dbo.Users U on S.user_key=U.user_key 
           inner Join '+ @ContactTable+'  C on S.contact_key=C.contact_key
      Where is_screen > 0 
            And Unit_Num between 398003 and 398005 
            and P22_value is not null 
            and c.[local_start_time] > ' + @GetYear 
      + ' order by local_start_time')

【问题讨论】:

    标签: sql sql-server-2008


    【解决方案1】:

    据我了解,@GetMonth 变量用于返回上个月

    Set @GetMonth = MONTH(CAST(GetDate() AS Datetime)) - 1 
    

    在您处理完程序后,我的第一个问题是这行代码:

    IF (@getmonth = 0) 
       SET @GetMonth = 12 + (@GetYear - 1)
    

    我不明白您为什么要将 @GetMonth 变量设置为 12 + 当前年份 -1,我认为这是问题的原因。

    当当前月份为 1(1 月)时,您是否想获得上一年的第 12 个月?如果是,那么您可以轻松地将 If 块更改为

    If @GetMonth = 0 
    Begin
         Set @GetMonth = 12
         Set @GetYear = @GetYear - 1
    End
    

    其他问题:

    • 建议保持变量@GetMonth@getmonth的名称一致,如果数据库排序区分大小写会导致错误。

    • @GetMonth 被声明为TinyInt,如果您尝试存储年份,这将导致算术溢出

    我建议您使用一些硬编码值测试您在此处编写的动态 SQL 语句,以检查返回的结果,您可以使用 January 和 2016 来检查您的过程中的实际问题还是查询中的问题。

    希望对你有帮助

    【讨论】:

    • 这确实是我试图指定 GetYear-1 更改背后的想法。我绝不是一个经验丰富的查询作者,我正试图根据我在过去 4 年中没有尝试过的知识将所有这些拼凑在一起。更令人困惑的一点是,如果您删除所有 @GetYear 引用,它仍会在结果集中提供 2 年的数据。我会对此做更多的挖掘,看看我能做到什么。感谢您提供的指导。
    • 在这种情况下,我建议在 WHERE 子句中检查您的联接和条件,问题一定出在某个地方。很高兴我能提供帮助,如果您找到原因,请告诉我。
    【解决方案2】:

    感谢您的帮助,我找到了问题的根源,这是因为我在尝试运行 T-SQL 语句时没有将 GetYear 转换为 varchar。这反过来又导致变量被完全忽略。在意识到我很努力地搞砸之后,我还稍微清理了查询。

    以下是清理后的功能查询,以便将来对某人有所帮助:

    Declare @GetMonth SmallInt,
    @SessionTable varchar(50),
    @ContactTable varchar(50),
    @TableVersion varchar(2),
    @GetYear SmallInt,
    @YearCheck varchar(4)
    
    Set @GetMonth=MONTH(cast(GetDate() as Datetime))-1
    Set @GetYear=YEAR(cast(GetDate() as Datetime))-1
    
    If (@GetMonth=0) 
    Begin
        Set @GetMonth =12
        Set @GetYear =@GetYear - 1
    End
    
    Set @TableVersion=CAST(@GetMonth as varchar(2))
    Set @SessionTable='[CentralDWH].[dbo].[Sessions_month_' +@tableversion +']'
    Set @ContactTable ='[CentralDWH].[dbo].[Contacts_month_' +@tableversion +']'
    Set @YearCheck=CAST(@GetYear as varchar(4))
    
    --Select @GetMonth,@GetYear,@YearCheck (DEBUGGING STATEMENT)
    -- Select @SessionTable,@ContactTable (DEBUGGING STATEMENT)
    
    
    Exec('SELECT 
    [PBX_id] as AgentID,
    [p22_value] as Skill,
    ''Athens'' as Location,
    Convert(varchar(20),c.[local_start_time],120) as local_start_time,
    convert(varchar(20),c.[local_end_time],120) as local_end_time,
    U.[USER_NAME],
    call_id
    
    
    
    FROM '+@SessionTable +' S
    Inner join dbo.Users U on S.user_key=U.user_key 
    inner Join '+ @ContactTable+'  C on S.contact_key=C.contact_key
    
    Where is_screen>0 
    And  Unit_Num between 398003 and 398005 
    And P22_value is not null 
    And year(c.[local_start_time]) > '+@YearCheck+'
       order by local_start_time')
    

    一旦我清理了所有这些并记得正确地投射年份,一切就都到位了。

    【讨论】:

      猜你喜欢
      • 2012-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-27
      • 1970-01-01
      • 2011-06-07
      相关资源
      最近更新 更多