I have a SQL Statement that works as I want.
select COUNT(*), MIN(emailed_to)from email.email_archive
group by emailed_to
order by COUNT(*) desc
The output looks like this.
13 deadlockIE12388nnhy32@hepmeplease.com;
8 deadlockIE1277yhygt@hepmeplease.com;
4 deadlockFF17uyt9xx967@hepmeplease.com;
...
...
...
1 deadlockFF17uytsdfa7@hepmeplease.com;
This is simple enough, but then I would have to remember to run the select every day and make sure things are ok. I want to have the stored procedure email me once in a while and I can decide if I have an issue. So I have hacked together the following from many resources:
use MYDB;
go
IF SCHEMA_ID('monitors') IS NULL EXECUTE('CREATE SCHEMA monitors AUTHORIZATION dbo')
GO
if object_id('monitors.email_abuse') is null
exec('create procedure monitors.email_abuse as print ''stub'' return');
GO
alter procedure monitors.email_abuse
(@to varchar(max) = 'itops@hepmeplease.com',
@sendemail tinyint = 1)
as
set nocount on ;
set transaction isolation level read uncommitted ;
begin try
declare @errmsg varchar(max) = '',
@subject nvarchar(255);
select @subject = 'Run Away Email Monitor';
select @errmsg = REPLICATE(char(10),1)+
'# of Emails'+
REPLICATE(char(9),1)+
'Email Address'+
REPLICATE(CHAR(10),1);
select @errmsg = @errmsg +REPLICATE(char(9),1)+
CAST(COUNT(*) as CHAR(10))+
REPLICATE(char(9),1)+
CAST(MIN(emailed_to) as CHAR(45))
from
email.email_archive
group by
emailed_to
order by
COUNT(*) desc;
print @errmsg;
if @sendemail = 1
begin
exec master.dbo.sp_email
@to = @to,
@subject = @subject,
@body = @errmsg;
end
end try
begin catch
-- unexpected errors
exec sp_raise_error @rethrow = 1, @textdata = N'Error in monitors.email_abuse', @emailTo = N'itops@hepmeplease.com'
end catch
go
But it then emails me the following output that is just one line. I know that there are many lines but for some reason when I put the COUNT(*), MIN(emailed_to) into the CAST statement this no longer works. I get a email that has the header and one line. If I just print the output of @errmsg I exactly what I get in the email, the header and the one line. just like below.
# of Emails Email Address
1 y@y.com;
I am not sure what I am doing wrong with my cast statement.
Explanation:
My guess is that the code you are actually using is slightly different from the code you have posted here because when I take your code and the following data in a test database, things work out fine.
I am thinking you may have hit upon an issue discussed here: http://bit.ly/cMlnjt
Since I can’t be sure I offer you two alternative solutions that will definitely get the job done, even though as others have mentioned this aggregate concatenation should work without an issue.
Alternatives:
To get what you are looking for, I prefer one of the following two options
1) Just make sp_send_dbmail do the work for you.
2) Go with a cursor solution
Option 1:
Note: The having clause makes this only display rows where the count is greater than 5.
Option 2:
Note: I prefer this method because of the flexibility I have in the way the messages are formatted. This will also only send the email if there are rows returned where the minimum count is reached.