使用仅具有可用记录的sp_send_dbmail发送报告的方法

时间:2017-07-27 04:17:48

标签: sql sql-server sql-server-2008

此SP由sp_send_dbmail调用,该日志在作业上每天执行。如果此报告中没有任何要显示的记录,我不希望发送带有' 0行的部分受影响'我仍然想报告有记录的部分。

这是我的sp它实际上有15个单独的select语句,但是为了节省空间我只显示2

------------------------------------------THIS IS FOR DEPARTMENT CODE [FS - FD]
DECLARE 
@Now2 DATETIME,
@EndReportDate2 DATETIME,
@StartReportDate2 DATETIME
SET @Now2 = GETDATE()
SET @EndReportDate2 = DATEADD(dd, DATEDIFF(dd, 0, @Now2), -1)
SET @StartReportDate2 = DATEADD(dd, DATEDIFF(dd, 0, @Now2), -1)
SELECT StatDate = TimeLog.EventDate 
,[ID#] = a.ID
,Codes = (a.DeptCode + '-' +  a.OpCode)
,TotalTime = convert(time(0),dateadd(second,sum(datediff(second,StartTime,FinishTime)),0))  
,Units = SUM(Units)
,UPH = cast(isnull(sum(Units) / nullif(sum(datediff(minute,StartTime,FinishTime))*1.0,0),0.0)*60  as decimal(10,0))
,[Goal%] = (convert(varchar,cast((isnull(sum(Units) / nullif(sum(datediff(minute,StartTime,FinishTime))*1.0,0),0.0)*60)/1552*100 as decimal(10,0))) + '%')
,AssociateName = (b.FirstName + ' ' + b.LastName)
FROM PTW.dbo.TimeLog a LEFT JOIN PTW.dbo.AssociateInfo b
ON a.ID = b.ID
WHERE EventDate BETWEEN @StartReportDate2  AND @EndReportDate2  AND DeptCode = 'FS' AND OpCode = 'FD'
GROUP BY a.EventDate, a.ID, a.DeptCode, a.OpCode, b.FirstName, b.LastName
ORDER BY   UPH DESC
------------------------------------------THIS IS FOR DEPARTMENT CODE [FS - FT]
DECLARE 
@Now3 DATETIME,
@EndReportDate3 DATETIME,
@StartReportDate3 DATETIME
SET @Now3 = GETDATE()
SET @EndReportDate3 = DATEADD(dd, DATEDIFF(dd, 0, @Now3), -1)
SET @StartReportDate3 = DATEADD(dd, DATEDIFF(dd, 0, @Now3), -1)
SELECT StatDate = a.EventDate 
,[ID#] = a.ID
,Codes = (a.DeptCode + '-' +  a.OpCode)
,TotalTime = convert(time(0),dateadd(second,sum(datediff(second,StartTime,FinishTime)),0))  
,Units = SUM(Units)
,UPH = cast(isnull(sum(Units) / nullif(sum(datediff(minute,StartTime,FinishTime))*1.0,0),0.0)*60  as decimal(10,0))
,[Goal%] = (convert(varchar,cast((isnull(sum(Units) / nullif(sum(datediff(minute,StartTime,FinishTime))*1.0,0),0.0)*60)/295*100 as decimal(10,0))) + '%')
,AssociateName = (b.FirstName + ' ' + b.LastName)
FROM PTW.dbo.TimeLog a LEFT JOIN PTW.dbo.AssociateInfo b 
ON a.ID = b.ID
WHERE EventDate BETWEEN @StartReportDate3  AND @EndReportDate3  AND DeptCode = 'FS' AND OpCode = 'FT'
GROUP BY a.EventDate, a.ID, a.DeptCode, a.OpCode, b.FirstName, b.LastName
ORDER BY  UPH DESC

我在这里使用sp_send_dbmail

调用它
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'DBMail,
@recipients = 'me@me.com',
@subject = 'FLAT_Daily',
@query = N'EXEC PTW.dbo.SP_FLAT_Daily',
@query_attachment_filename = 'FLAT_Daily.txt'

以下是我的结果

StatDate    ID#       Codes TotalTime   Units   UPH   Goal%  AssociateName
--------    ---       ----- ---------   -----   ---   -----  -------------
7/24/2017   1234567   FS-FD 03:40:00    0       0     0%     MY NAME

(1 rows affected)
StatDate    ID#       Codes TotalTime   Units   UPH  Goal%   AssociateName
--------    ---       ----- ---------   -----   ---  -----   -------------

(0 rows affected)

有些日子我都有记录,但是有时候只有一部分有记录。如何只发送有记录的内容?

----------------------------------------------- ------------------------

还要将结果集分组如下。仅显示所有部门associateName的相同codes个人在指定时间内工作。

StatDate   ID          Codes TotalTime Units       UPH     Goal   AssociateName
---------- ----------- ----- --------- ----------- ------- ------ ------------------
2017-07-26 2375935     fs-ft 03:44:00  263         70      24%    Druid Druid
2017-07-26 2375935     fs-fd 04:50:00  553         114     7%     Druid Druid
2017-07-26 2375935     fr-pk 04:50:00  553         114     7%     Druid Druid

(3 row(s) affected)

2 个答案:

答案 0 :(得分:1)

开始IF EXISTS中的每个选择。例如:

IF EXISTS (
    SELECT * FROM PTW.dbo.TimeLog
    WHERE EventDate BETWEEN @StartReportDate2  AND @EndReportDate2  
    AND DeptCode = 'FS' AND OpCode = 'FD'
    )

SELECT StatDate = TimeLog.EventDate 
,[ID#] = a.ID
,Codes = (a.DeptCode + '-' +  a.OpCode)
,TotalTime = convert(time(0),dateadd(second,sum(datediff(second,StartTime,FinishTime)),0))  
,Units = SUM(Units)
,UPH = cast(isnull(sum(Units) / nullif(sum(datediff(minute,StartTime,FinishTime))*1.0,0),0.0)*60  as decimal(10,0))
,AssociateName = (b.FirstName + ' ' + b.LastName)
FROM PTW.dbo.TimeLog a LEFT JOIN PTW.dbo.AssociateInfo b
ON a.ID = b.ID
WHERE EventDate BETWEEN @StartReportDate2  AND @EndReportDate2  AND DeptCode = 'FS' AND OpCode = 'FD'
GROUP BY a.EventDate, a.ID, a.DeptCode, a.OpCode, b.FirstName, b.LastName
ORDER BY   UPH DESC

IF EXISTS (SELECT * FROM query2)
SELECT column from query2

如果存在记录,则执行下一行

答案 1 :(得分:1)

解决此问题的一种方法是将可重用查询移动到自己的过程中,并从日常报告过程中执行该过程。

这仍然只是使用if exists()来确定是否按照Nick McDermaid的建议返回结果集,但它简化了代码。

create procedure dbo.SP_FLAT_Daily_Query (
    @StartReportDate datetime 
  , @EndReportDate   datetime 
  , @DeptCode        char(2) 
  , @OpCode          char(2)
  , @Goal            decimal(10,2)
) as 
begin;
  --set nocount on; /* removes (N row(s) affected message)
  if exists (
    select 1 
    from TimeLog t
    where t.EventDate >= @StartReportDate
      and t.EventDate <= @EndReportDate
      and t.DeptCode = @DeptCode
      and t.OpCode = @OpCode
    )
  begin;
    select 
        StatDate = convert(char(10),t.EventDate,120)
      , t.ID
      , Codes = (t.DeptCode + '-' +  t.OpCode)
      , TotalTime = right('0' + convert(varchar(9),(sum(datediff(second,StartTime,FinishTime)) / 3600 )),2) + ':' 
                  + right('0' + convert(varchar(2),(sum(datediff(second,StartTime,FinishTime)) / 60) % 60 ),2) + ':' 
                  + right('0' + convert(varchar(2),(sum(datediff(second,StartTime,FinishTime)) % 60 )),2)
      , Units = sum(Units)
      , UPH = cast(isnull(sum(Units) / nullif(sum(datediff(minute,StartTime,FinishTime))*1.0,0),0.0)*60  as decimal(10,0))
      , [Goal%] = (convert(varchar(30),cast((isnull(sum(Units) / nullif(sum(datediff(minute,StartTime,FinishTime))*1.0,0),0.0)*60)/nullif(@Goal,0)*100 as decimal(10,0))) + '%')
      , AssociateName = isnull(ai.FirstName + ' ','') + isnull(ai.LastName,'')
    from TimeLog t
      left join AssociateInfo ai
        on t.Id = ai.Id
    where t.EventDate >= @StartReportDate
      and t.EventDate <= @EndReportDate
      and t.DeptCode = @DeptCode
      and t.OpCode = @OpCode
    group by t.EventDate, t.id, t.DeptCode, t.OpCode, ai.FirstName, ai.LastName
    order by t.id desc;
  end;
end;
go

然后在您的日常过程中,重用您的变量并使用所需的每组变量执行查询过程。

以下示例中的代码是详细的,并为相同的变量重复相同的值赋值,但我这样做是为了让您可以轻松调整实际代码。

create procedure dbo.SP_Flat_Daily as 
begin;
  --set nocount on; /* removes (N row(s) affected message)
  declare 
      @Now             datetime
    , @StartReportDate datetime 
    , @EndReportDate   datetime 
    , @DeptCode        char(2) 
    , @OpCode          char(2)
    , @Goal            decimal(10,2);
  ------------------------------------------THIS IS FOR DEPARTMENT CODE [FS - FT]
  select 
      @Now = getdate()
    , @StartReportDate = dateadd(day, datediff(day, 0, getdate()), -1)
    , @EndReportDate   = dateadd(day, datediff(day, 0, getdate()), -1)
    , @DeptCode = 'fs'
    , @OpCode   = 'ft'
    , @Goal     = 295.0;
  exec dbo.SP_FLAT_Daily_Query @StartReportDate, @EndReportDate, @DeptCode, @OpCode, @Goal;  
  ------------------------------------------THIS IS FOR DEPARTMENT CODE [NA - NA]
  select 
      @Now = getdate()
    , @StartReportDate = dateadd(day, datediff(day, 0, getdate()), -1)
    , @EndReportDate   = dateadd(day, datediff(day, 0, getdate()), -1)
    , @DeptCode = 'na'
    , @OpCode   = 'na'
    , @Goal     = 0;
  exec dbo.SP_FLAT_Daily_Query @StartReportDate, @EndReportDate, @DeptCode, @OpCode, @Goal;
  ------------------------------------------THIS IS FOR DEPARTMENT CODE [FS - FD]
  select 
      @Now = getdate()
    , @StartReportDate = dateadd(day, datediff(day, 0, getdate()), -1)
    , @EndReportDate   = dateadd(day, datediff(day, 0, getdate()), -1)
    , @DeptCode = 'fs'
    , @OpCode   = 'fd'
    , @Goal     = 1552.0;
  exec dbo.SP_FLAT_Daily_Query @StartReportDate, @EndReportDate, @DeptCode, @OpCode, @Goal;
end;
go
exec dbo.SP_Flat_Daily;

dbfiddle.uk演示:http://dbfiddle.uk/?rdbms=sqlserver_2016&fiddle=72525c7478361b0df8171fd224f68f7e

返回:

StatDate   ID          Codes TotalTime Units       UPH     Goal   AssociateName
---------- ----------- ----- --------- ----------- ------- ------ ------------------
2017-07-26 2375935     fs-ft 03:44:00  263         70      24%    Druid Druid

(1 row(s) affected)

StatDate   ID          Codes TotalTime Units       UPH     Goal   AssociateName
---------- ----------- ----- --------- ----------- ------- ------ ------------------
2017-07-26 11259       fs-fd 04:50:00  553         114     7%     Sql Zim
2017-07-26 25          fs-fd 24:59:59  176         7       0%     Nick McDermaid

(2 row(s) affected)

如您所见,na-na没有消息或空结果集。