Объяснение:
Я предполагаю, что код, который вы на самом деле используете, немного отличается от кода, который вы разместили здесь, потому что когда я беру ваш код и следующие данные в тестебаза данных, все работает отлично.
create table email_archive
(
id int,
emailed_to nvarchar(255)
)
insert into email_archive values
( 1, 'one@helpme.com'), ( 2, 'two@helpme.com'), ( 3, 'three@helpme.com'),
( 4, 'four@helpme.com'), ( 5, 'one@helpme.com'), ( 6, 'two@helpme.com'),
( 7, 'three@helpme.com'), ( 8, 'four@helpme.com'), ( 9, 'one@helpme.com'),
(10, 'two@helpme.com'), (11, 'three@helpme.com'), (12, 'four@helpme.com'),
(13, 'one@helpme.com'), (14, 'two@helpme.com'), (15, 'three@helpme.com'),
(16, 'four@helpme.com'), (17, 'one@helpme.com'), (18, 'one@helpme.com'),
(19, 'one@helpme.com'), (20, 'three@helpme.com'), (21, 'three@helpme.com')
Я думаю, что вы, возможно, столкнулись с проблемой, обсуждаемой здесь: http://bit.ly/cMlnjt
Поскольку я не уверен, я предлагаю вам две альтернативырешения, которые определенно выполнят свою работу, даже если как уже упоминали другие , эта совокупная конкатенация должна работать без проблем.
Альтернативы:
Чтобы получить то, что вы ищете, я предпочитаю один из следующих двух вариантов
1) Просто заставьте sp_send_dbmail сделать всю работу за вас.
2) Идите срешение курсора
Опция 1:
EXEC msdb..sp_send_dbmail @profile_name = 'MyMailProfile',
@recipients = 'my_email@domain.com',
@subject = 'Runaway Email Monitor',
@body = 'Runaway emails found',
@query = 'SELECT COUNT(*), emailed_to FROM mydb.dbo.email_archive GROUP BY emailed_to HAVING COUNT(*) > 5 ORDER BY COUNT(*) DESC'
Примечание. При условии, что в этом разделе отображаются только те строки, число которых превышает 5.
Вариант 2:
USE test
IF EXISTS ( SELECT name FROM test.sys.sysobjects WHERE type = 'P' AND name = 'usp_MonitorEmails' )
BEGIN
DROP PROCEDURE dbo.usp_MonitorEmails
END
GO
CREATE PROCEDURE usp_MonitorEmails
@Subject nvarchar(255) = '',
@Importance varchar(6) = 'NORMAL',
@Sensitivity varchar(12) = 'NORMAL',
@Recipients varchar(MAX) = NULL,
@MinimumCount int = 0
AS
BEGIN
SET NOCOUNT ON
IF UPPER(@Importance) NOT IN ('LOW', 'NORMAL', 'HIGH') SET @Importance = 'NORMAL'
IF UPPER(@Sensitivity) NOT IN ('NORMAL', 'PERSONAL', 'PRIVATE', 'CONFIDENTIAL') SET @Sensitivity = 'NORMAL'
DECLARE @run bit,
@message nvarchar(MAX)
SELECT @run = 0,
@subject = 'Run Away Email Monitor',
@message = 'Run away emails found' + CHAR(13)+CHAR(10) +
'Count Email Address' + CHAR(13)+CHAR(10) +
'----------- ------------------------------------------------------------------------------' + CHAR(13)+CHAR(10)
DECLARE @count int,
@email nvarchar(255)
DECLARE BodyCursor CURSOR STATIC FOR
SELECT COUNT(*), emailed_to FROM email_archive GROUP BY emailed_to HAVING COUNT(*) > @MinimumCount ORDER BY COUNT(*) DESC
OPEN BodyCursor
FETCH NEXT FROM BodyCursor
INTO @count, @email
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @message = @message + REPLICATE(N' ', 11-LEN(CAST(@count AS nvarchar(22)))) + CAST(@count AS nvarchar(22)) + ' ' + @email + CHAR(13)+CHAR(10), @run = 1
FETCH NEXT FROM BodyCursor
INTO @count, @email
END
CLOSE BodyCursor
DEALLOCATE BodyCursor
IF @run = 1 AND LEN(@Recipients) > 0
BEGIN
EXEC msdb..sp_send_dbmail @profile_name = 'MyMailProfile',
@recipients = @Recipients,
@subject = @Subject,
@body = @Message,
@body_format = 'TEXT',
@importance = @Importance,
@sensitivity = @Sensitivity
END
END
GO
Примечание: Я предпочитаю этот метод из-за гибкости, которую я имею в способе форматирования сообщений.Это также только отправит электронное письмо, если будут возвращены строки, в которых достигнуто минимальное количество.