Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
Author |
Topic |
geo039
Starting Member
8 Posts |
Posted - 2011-03-30 : 19:02:38
|
All, I have a query I created to send an html table to email, however what I need is to send emails to users in the table but not one email at a time per row. Supervisors may have multiple employees with evaluations due. How do I extract each supervisors group of employees and email them that portion of the table. I'm trying to figure out from my query below the cleanest way to get recipient info. Do I need another "cursor query" just containing the list of recipents and match them to the dataset in the unioned query?DECLARE @FirstDayCurrentMonth DateTimeDECLARE @LastDayNextMonth DateTimeDECLARE @LastDayPreviousMonth DateTimeDECLARE @TodaysDate VARCHAR(20) SET @TodaysDate = DateAdd(day, datediff(day,0, GETDATE()), 0)SET @FirstDayCurrentMonth = (SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(@TodaysDate)-1),@TodaysDate),101))SET @LastDayNextMonth = (SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+2,0)))SET @LastDayPreviousMonth = (SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0))) DECLARE @tableHTML NVARCHAR(MAX); with CTE as E(SELECT descSection as 'SECTION', COSTCENTER, dbo.fncEmployeeName(v.ESPN) as EMPLOYEE, dbo.fncEmployeeName(v.supvEspn) as SUPERVISOR, v.supvusername as 'SUPVUSERNAME', dbo.fncEmployeeName(v.cc_sup_espn) as COSTCENTERSUPV, 'EVALDATE' = dbo.fncGetEvaluationDate(v.espn), descEmpStatus as 'EMPLOYEESTATUS', 'EVALTYPE' = CASE WHEN descEmpStatus = 'Permanent' THEN 'Annual' END FROM dbo.vCEDEmployees vJOIN CodesCostCenters cON v.cdcstcntr = c.cdcstcntrJOIN CodesSections sON c.cdSection = s.cdSectionWHERE DateAdd(day, datediff(day,0, dbo.fncGetEvaluationDate(v.espn)), 0) BETWEEN @FirstDayCurrentMonth AND @LastDayNextMonthAND descEmpStatus = 'Permanent'AND cdEmpStatus IN (1, 2)AND cdEmpType = 1UNION ALLSELECT descSection as 'SECTION', COSTCENTER, dbo.fncEmployeeName(v.ESPN) as EMPLOYEE, dbo.fncEmployeeName(v.supvEspn) as SUPERVISOR, v.supvusername as 'SUPVUSERNAME', dbo.fncEmployeeName(v.cc_sup_espn) as COSTCENTERSUPV, 'EVALDATE' = dbo.fncGetEvaluationDate(v.espn), descEmpStatus as 'EMPLOYEESTATUS', 'EVALTYPE' = CASE WHEN descEmpStatus = 'Probation' THEN 'Probation' END FROM dbo.vCEDEmployees v JOIN CodesCostCenters cON v.cdcstcntr = c.cdcstcntrJOIN CodesSections sON c.cdSection = s.cdSectionWHERE DateAdd(day, datediff(day,0, dbo.fncGetEvaluationDate(v.espn)), 0) BETWEEN @TodaysDate AND @LastDayNextMonthAND descEmpStatus = 'Probation'AND cdEmpStatus IN (1, 2)) Select @tableHTML = N'<H1>Employee Evaluations Due</H1>' + N'<table border="1">' + N'<tr><th>SECTION</th><th>COST CENTER</th><th>COST CENTER SUPV</th><th>SUPERVISOR</th><th>EMPLOYEE</th><th>STATUS</th><th>EVAL TYPE</th>' + N'<th>EVAL DATE</th>' + N'</tr>' +CAST ( ( select TD = SECTION, '', TD = COSTCENTER, '', TD = COSTCENTERSUPV, '', TD = SUPERVISOR, '', TD = EMPLOYEE, '', TD = EMPLOYEESTATUS, '', TD = EVALTYPE, '', TD = Convert(Varchar,EVALDATE,101), '' from CTEORDER BY 'EVALTYPE' DESC FOR XML PATH('tr'), TYPE ) AS NVARCHAR(MAX) ) + N'</table>' ; EXEC msdb.dbo.sp_send_dbmail @profile_name = 'something',@recipients='email', @subject = 'Evaluations Due', @body = @tableHTML, @body_format = 'HTML' ; |
|
sunitabeck
Master Smack Fu Yak Hacker
5155 Posts |
Posted - 2011-03-31 : 10:25:19
|
Since you have to send the same attachments or message body to all recipients, I think it is a given that you will need to run the EXEC msdb.dbo.sp_send_dbmail multiple times. If that is true, then one way to make it more readable/maintainable might be to wrap it in a stored proc and pass in the query conditions as stored proc parameters, something like this:create procedure dbo.SendStatusNoticeToSupervisor @supervisor_name varchar(255)asDECLARE @FirstDayCurrentMonth DateTimeDECLARE @LastDayNextMonth DateTimeDECLARE @LastDayPreviousMonth DateTimeDECLARE @TodaysDate VARCHAR(20) SET @TodaysDate = DateAdd(day, datediff(day,0, GETDATE()), 0)SET @FirstDayCurrentMonth = (SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(@TodaysDate)-1),@TodaysDate),101))SET @LastDayNextMonth = (SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+2,0)))SET @LastDayPreviousMonth = (SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0))) DECLARE @tableHTML NVARCHAR(MAX); with CTE as E(SELECT descSection as 'SECTION', COSTCENTER, dbo.fncEmployeeName(v.ESPN) as EMPLOYEE, dbo.fncEmployeeName(v.supvEspn) as SUPERVISOR, v.supvusername as 'SUPVUSERNAME', dbo.fncEmployeeName(v.cc_sup_espn) as COSTCENTERSUPV, 'EVALDATE' = dbo.fncGetEvaluationDate(v.espn), descEmpStatus as 'EMPLOYEESTATUS', 'EVALTYPE' = CASE WHEN descEmpStatus = 'Permanent' THEN 'Annual' END FROM dbo.vCEDEmployees vJOIN CodesCostCenters cON v.cdcstcntr = c.cdcstcntrJOIN CodesSections sON c.cdSection = s.cdSectionWHERE DateAdd(day, datediff(day,0, dbo.fncGetEvaluationDate(v.espn)), 0) BETWEEN @FirstDayCurrentMonth AND @LastDayNextMonthAND descEmpStatus = 'Permanent'AND cdEmpStatus IN (1, 2)AND cdEmpType = 1AND v.supvusername = @supervisor_nameUNION ALLSELECT descSection as 'SECTION', COSTCENTER, dbo.fncEmployeeName(v.ESPN) as EMPLOYEE, dbo.fncEmployeeName(v.supvEspn) as SUPERVISOR, v.supvusername as 'SUPVUSERNAME', dbo.fncEmployeeName(v.cc_sup_espn) as COSTCENTERSUPV, 'EVALDATE' = dbo.fncGetEvaluationDate(v.espn), descEmpStatus as 'EMPLOYEESTATUS', 'EVALTYPE' = CASE WHEN descEmpStatus = 'Probation' THEN 'Probation' END FROM dbo.vCEDEmployees v JOIN CodesCostCenters cON v.cdcstcntr = c.cdcstcntrJOIN CodesSections sON c.cdSection = s.cdSectionWHERE DateAdd(day, datediff(day,0, dbo.fncGetEvaluationDate(v.espn)), 0) BETWEEN @TodaysDate AND @LastDayNextMonthAND descEmpStatus = 'Probation'AND cdEmpStatus IN (1, 2)AND v.supvusername = @supervisor_name) Select @tableHTML = N'<H1>Employee Evaluations Due</H1>' + N'<table border="1">' + N'<tr><th>SECTION</th><th>COST CENTER</th><th>COST CENTER SUPV</th><th>SUPERVISOR</th><th>EMPLOYEE</th><th>STATUS</th><th>EVAL TYPE</th>' + N'<th>EVAL DATE</th>' + N'</tr>' +CAST ( ( select TD = SECTION, '', TD = COSTCENTER, '', TD = COSTCENTERSUPV, '', TD = SUPERVISOR, '', TD = EMPLOYEE, '', TD = EMPLOYEESTATUS, '', TD = EVALTYPE, '', TD = Convert(Varchar,EVALDATE,101), '' from CTEORDER BY 'EVALTYPE' DESC FOR XML PATH('tr'), TYPE ) AS NVARCHAR(MAX) ) + N'</table>' ; EXEC msdb.dbo.sp_send_dbmail @profile_name = 'something',@recipients='email', @subject = 'Evaluations Due', @body = @tableHTML, @body_format = 'HTML' ; You would need to specify that supervisor's e-mail as the only recipient.Once you have this correctly working for one supervisor, then you will need call the stored proc for each supervisor.Of course, the usual disclaimer that I have only a very limited understanding of your business rules, and hence this may be completely off-base still applies :) |
 |
|
ajthepoolman
Constraint Violating Yak Guru
384 Posts |
Posted - 2011-03-31 : 10:27:20
|
Am I understanding you that you want to email a single supervisor and let them know which evals are due?So something like:Supervisor: ajthepoolmanEvals due for: Ben Washington, Ben Jefferson, George Lincolnthen another email:Supervisor: geo039Evals due for: Taco John, Ronald McDonald, Wendy PopeyeHey, it compiles. |
 |
|
geo039
Starting Member
8 Posts |
Posted - 2011-03-31 : 17:13:36
|
Currently, I have the unioned query (CTE) sending emails to the the cursor recipient query (see modified query below) so each of the 44 supervisors are getting the entire list of evals due. What I want it to do is send only each supervisor their employees due. So each of the 44 supervisor emails would be different.DECLARE @SECTION VARCHAR(100) DECLARE @COSTCENTER VARCHAR(100)DECLARE @COSTCENTERSUPV VARCHAR(100) DECLARE @SUPERVISOR VARCHAR(100) DECLARE @SUPVUSERNAME VARCHAR(100) DECLARE @LINESPACE VARCHAR(1000) DECLARE @E_ADDRESS VARCHAR(50) DECLARE @E_RECIPIENTS VARCHAR(500) DECLARE @CC_RECIPIENTS VARCHAR(500) DECLARE @SRWTPPERSONNEL VARCHAR(500) DECLARE @E_SUBJECT VARCHAR(50) DECLARE @MESSAGE_1 VARCHAR(50) DECLARE @MESSAGE_1A VARCHAR(50) DECLARE @MESSAGE_2 VARCHAR(50) DECLARE @MESSAGE_3 VARCHAR(50) DECLARE @MESSAGE_4 VARCHAR(400) DECLARE @MESSAGE_5 VARCHAR(400) DECLARE @HYPERLINK VARCHAR(200) DECLARE @FirstDayCurrentMonth DateTimeDECLARE @LastDayNextMonth DateTimeDECLARE @LastDayPreviousMonth DateTimeDECLARE @TodaysDate VARCHAR(20) SET @TodaysDate = DateAdd(day, datediff(day,0, GETDATE()), 0)SET @FirstDayCurrentMonth = (SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(@TodaysDate)-1),@TodaysDate),101))SET @LastDayNextMonth = (SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+2,0)))SET @LastDayPreviousMonth = (SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0))) DECLARE @tableHTML NVARCHAR(MAX); with CTE as (SELECT descSection as 'SECTION', COSTCENTER, dbo.fncEmployeeName(v.ESPN) as EMPLOYEE, dbo.fncEmployeeName(v.supvEspn) as SUPERVISOR, v.supvusername as 'SUPVUSERNAME', dbo.fncEmployeeName(v.cc_sup_espn) as COSTCENTERSUPV, 'EVALDATE' = dbo.fncGetEvaluationDate(v.espn), descEmpStatus as 'EMPLOYEESTATUS', 'EVALTYPE' = CASE WHEN descEmpStatus = 'Permanent' THEN 'Annual' END FROM dbo.vCEDEmployees vJOIN CodesCostCenters cON v.cdcstcntr = c.cdcstcntrJOIN CodesSections sON c.cdSection = s.cdSectionWHERE DateAdd(day, datediff(day,0, dbo.fncGetEvaluationDate(v.espn)), 0) BETWEEN @FirstDayCurrentMonth AND @LastDayNextMonthAND descEmpStatus = 'Permanent'AND cdEmpStatus IN (1, 2)AND cdEmpType = 1UNION ALLSELECT descSection as 'SECTION', COSTCENTER, dbo.fncEmployeeName(v.ESPN) as EMPLOYEE, dbo.fncEmployeeName(v.supvEspn) as SUPERVISOR, v.supvusername as 'SUPVUSERNAME', dbo.fncEmployeeName(v.cc_sup_espn) as COSTCENTERSUPV, 'EVALDATE' = dbo.fncGetEvaluationDate(v.espn), descEmpStatus as 'EMPLOYEESTATUS', 'EVALTYPE' = CASE WHEN descEmpStatus = 'Probation' THEN 'Probation' END FROM dbo.vCEDEmployees v JOIN CodesCostCenters cON v.cdcstcntr = c.cdcstcntrJOIN CodesSections sON c.cdSection = s.cdSectionWHERE DateAdd(day, datediff(day,0, dbo.fncGetEvaluationDate(v.espn)), 0) BETWEEN @TodaysDate AND @LastDayNextMonthAND descEmpStatus = 'Probation'AND cdEmpStatus IN (1, 2)) Select @tableHTML = N'<H1>Employee Evaluations Due</H1>' + N'<table border="1">' + N'<tr><th>SECTION</th><th>COST CENTER</th><th>COST CENTER SUPV</th><th>SUPERVISOR</th><th>EMPLOYEE</th><th>STATUS</th><th>EVAL TYPE</th>' + N'<th>EVAL DATE</th>' + N'</tr>' +CAST ( ( select TD = SECTION, '', TD = COSTCENTER, '', TD = COSTCENTERSUPV, '', TD = SUPERVISOR, '', TD = EMPLOYEE, '', TD = EMPLOYEESTATUS, '', TD = EVALTYPE, '', TD = Convert(Varchar,EVALDATE,101), '' from CTE ORDER BY 'EVALTYPE' DESC FOR XML PATH('tr'), TYPE ) AS NVARCHAR(MAX) ) + N'</table>' ;DECLARE CursorForEmail CURSOR FOR SELECT distinct dbo.fncEmployeeName(v.supvEspn) as SUPERVISOR, descSection as 'SECTION', COSTCENTER, v.supvusername as 'SUPVUSERNAME', dbo.fncEmployeeName(v.cc_sup_espn) as COSTCENTERSUPVFROM dbo.vCEDEmployees vJOIN CodesCostCenters cON v.cdcstcntr = c.cdcstcntrJOIN CodesSections sON c.cdSection = s.cdSectionWHERE DateAdd(day, datediff(day,0, dbo.fncGetEvaluationDate(v.espn)), 0) BETWEEN @FirstDayCurrentMonth AND @LastDayNextMonthAND descEmpStatus = 'Permanent'AND cdEmpStatus IN (1, 2)AND cdEmpType = 1UNION ALLSELECT distinct dbo.fncEmployeeName(v.supvEspn) as SUPERVISOR, descSection as 'SECTION', COSTCENTER, v.supvusername as 'SUPVUSERNAME', dbo.fncEmployeeName(v.cc_sup_espn) as COSTCENTERSUPVFROM dbo.vCEDEmployees v JOIN CodesCostCenters cON v.cdcstcntr = c.cdcstcntrJOIN CodesSections sON c.cdSection = s.cdSectionWHERE DateAdd(day, datediff(day,0, dbo.fncGetEvaluationDate(v.espn)), 0) BETWEEN @TodaysDate AND @LastDayNextMonthAND descEmpStatus = 'Probation'AND cdEmpStatus IN (1, 2)AND cdEmpType = 1ORDER BY 'Supervisor' DESCOPEN CursorForEmail FETCH NEXT FROM CursorForEmail INTO @SUPERVISOR,@SECTION,@COSTCENTER,@SUPVUSERNAME,@COSTCENTERSUPVWHILE @@Fetch_Status >= 0 BEGIN EXEC msdb.dbo.sp_send_dbmail @profile_name = 'profile',@recipients='email', @subject = 'Evaluations Due', @body = @tableHTML, @body_format = 'HTML' ; FETCH NEXT FROM CursorForEmail INTO @SUPERVISOR,@SECTION,@COSTCENTER,@SUPVUSERNAME,@COSTCENTERSUPV END CLOSE CursorForEmail DEALLOCATE CursorForEmail |
 |
|
geo039
Starting Member
8 Posts |
Posted - 2011-03-31 : 17:41:59
|
quote: Originally posted by ajthepoolman Am I understanding you that you want to email a single supervisor and let them know which evals are due?So something like:Supervisor: ajthepoolmanEvals due for: Ben Washington, Ben Jefferson, George Lincolnthen another email:Supervisor: geo039Evals due for: Taco John, Ronald McDonald, Wendy PopeyeHey, it compiles.
Yes pretty much thats what i need it to do |
 |
|
|
|
|
|
|