Динамическая отправка электронной почты нескольким получателям с помощью сообщения sp_send_dbmail
На самом деле я собираюсь отправить поздравления с днем рождения участникам. Список получателей я получаю динамически. С помощью следующего запроса я могу отправить приветствия членам.
DECLARE @emails VARCHAR(500) DECLARE @bodycontent VARCHAR(500) SET @emails = '' SET @bodycontent = '' use dnname SELECT @emails = @emails + cm.PersonalEmail + ';' FROM tblIndividualMst im inner join tblContactMst cm on cm.ContactID = im.ContactID where im.GroupID = 4673 and im.DateOfBirth = CONVERT(VARCHAR(10),GETDATE(),110) DECLARE @recipList VARCHAR(500) SET @recipList = (select SUBSTRING(@emails, 0, LEN(@emails))) SELECT @bodycontent = 'Happy BirthDay to'+ ' ' + + @bodycontent + im.FullName + '' FROM tblIndividualMst im inner join tblContactMst cm on cm.ContactID = im.ContactID where im.GroupID = 4673 and im.DateOfBirth = CONVERT(VARCHAR(10),GETDATE(),110) use msdb EXEC sp_send_dbmail @profile_name='eMail Profile', @[email protected], @subject='Happy Birthday', @[email protected], @body_format = 'text'
Итак, если у @emails есть несколько получателей, как я могу отправить сообщение каждому члену.
DECLARE @emails VARCHAR(500) DECLARE @bodycontent VARCHAR(500) SET @emails = '' SET @bodycontent = '' use dnname SELECT @emails = @emails + cm.PersonalEmail + ';' FROM tblIndividualMst im inner join tblContactMst cm on cm.ContactID = im.ContactID where im.GroupID = 4673 and im.DateOfBirth = CONVERT(VARCHAR(10),GETDATE(),110) DECLARE @recipList VARCHAR(500) SET @recipList = (select SUBSTRING(@emails, 0, LEN(@emails))) SELECT @Count = @Count + Count(cm.PersonalEmail) FROM tblIndividualMst im inner join tblContactMst cm on cm.ContactID = im.ContactID where im.GroupID = 4673 and im.DateOfBirth = CONVERT(VARCHAR(10),GETDATE(),110) Declare @i int set @i = 0 while @i <= @Count begin SELECT @bodycontent = 'Happy BirthDay to'+ ' ' + + @bodycontent + im.FullName + '' FROM tblIndividualMst im inner join tblContactMst cm on cm.ContactID = im.ContactID where im.GroupID = 4673 and im.DateOfBirth = CONVERT(VARCHAR(10),GETDATE(),110) use msdb EXEC sp_send_dbmail @profile_name='eMail Profile', @[email protected], @subject='Happy Birthday', @[email protected], @body_format = 'text' end
Итак, как я могу изменить свой запрос. Любая помощь оценили, спасибо !!!
- Существуют ли какие-либо различия / ограничения в хранимых процедурах при использовании базы данных SQL Azure
- Как определить, завершает ли SQL-сервер результат, если используется TOP?
- Проблемы с созданием полного текстового индекса в представлении
- Выберите верхние даты, сгруппированные по идентификаторам
- ВЛЕВОЕ СОЕДИНИТЕЛЬНОЕ СОЕДИНЕНИЕ 3 стола
- Какие новые функции доступны в службах Reporting Services SQL Server Denali?
- System.ComponentModel.Win32Exception: сетевой путь не найден Ошибка
- как вернуть результат выбора при попытке безопасной общей хранимой процедуры, используя sp_executesql
- Как импортировать Microsoft.SqlServer.Types в Microsoft SQL Server 2012?
- Общий набор данных не поддерживается службами отчетов sql server 2012
- Ошибка развертывания с помощью службы SSIS 2012 при развертывании проекта в каталог DB
- Случайный порядок на SQL Server
- sql (beginner) - значение использования, вычисленное по вышеуказанной ячейке
Вот некоторые наблюдения …
- Вы не
@Count
в своем коде где угодно. Он должен быть объявлен какINT
и установлен в0
- В вашем
WHILE LOOP
вы не увеличиваете@Count
так что этот цикл бесконечен - Я бы сделал
@emails varchar(max)
чтобы избежать усечения списка получателей -
@recipList
бессмысленна, насколько я могу сказать … вы устанавливаете его вsubstring
начинающуюся с 0 и проходящую по всей длине всех писем … это то же самое, что иset @recipList = @emails
- Ваш цикл while не построен логически с тем, как вы хотите, чтобы это работало. Кажется, что вы намерены отправить одно электронное письмо со всеми именами, у которых есть день рождения. Во-первых, я бы разделил эти имена на @body. Во-вторых, вам вообще не нужен цикл. Удалите цикл
WHILE
так как все, что вам нужно сделать, это отправить электронное письмо один раз, в список@recipList
вы создали, с@bodycontent
, с@bodycontent
вы конкатенируете.
С этим все сказано … ваш код может быть упрощен до нижнего, который должен работать.
use dnname DECLARE @emails VARCHAR(max) DECLARE @bodycontent VARCHAR(max) DECLARE @people varchar(max) SET @emails = '' SET @people = '' SET @bodycontent = '' SELECT @emails = @emails + cm.PersonalEmail + ';' FROM tblIndividualMst im inner join tblContactMst cm on cm.ContactID = im.ContactID where im.GroupID = 4673 and im.DateOfBirth = CONVERT(VARCHAR(10),GETDATE(),110) SELECT @people = @people + im.FullName + ', ' FROM tblIndividualMst im inner join tblContactMst cm on cm.ContactID = im.ContactID where im.GroupID = 4673 and im.DateOfBirth = CONVERT(VARCHAR(10),GETDATE(),110) SELECT @bodycontent = 'Happy BirthDay to '+ @people EXEC msdb.dbo.sp_send_dbmail @profile_name='eMail Profile', @[email protected], @subject='Happy Birthday', @[email protected], @body_format = 'text'
Если вы хотите отправить одну персонализированную электронную почту для каждого человека … вы можете использовать курсор
use dnname DECLARE @emails VARCHAR(4000) DECLARE @bodycontent VARCHAR(max) DECLARE @people varchar(4000) SET @emails = '' SET @people = '' SET @bodycontent = '' DECLARE emailCursor CURSOR FOR SELECT cm.PersonalEmail,im.FullName FROM tblIndividualMst im inner join tblContactMst cm on cm.ContactID = im.ContactID where im.GroupID = 4673 and im.DateOfBirth = CONVERT(VARCHAR(10),GETDATE(),110) OPEN emailCursor FETCH NEXT FROM emailCursor INTO @emails, @people WHILE @@FETCH_STATUS = 0 BEGIN SET @bodycontent = 'Happy BirthDay to '+ @people EXEC msdb.dbo.sp_send_dbmail @profile_name='eMail Profile', @[email protected], @subject='Happy Birthday', @[email protected], @body_format = 'text' FETCH NEXT FROM emailCursor INTO @emails, @people END CLOSE emailCursor DEALLOCATE emailCursor
Лично я против использования циклов в SQL и поэтому стараюсь избегать их как можно больше. Идея этого заключается в том, чтобы выполнять как можно меньше заявлений. В этом случае я бы сгенерировал кусок динамического SQL и выполнил его.
DECLARE @SQL NVARCHAR(MAX); SELECT @SQL = CAST(( SELECT [text()] = REPLACE(REPLACE(' EXEC msdb.dbo.sp_send_dbmail @profile_name=''eMail Profile'', @recipients=''{email}'', @subject=''Happy Birthday'', @body=''Happy BirthDay to {fullname}'', @body_format = ''text''; ' ,'{fullname}',im.FullName) ,'{email}',cm.PersonalEmail) FROM tblIndividualMst im INNER JOIN tblContactMst cm ON cm.ContactID = im.ContactID WHERE im.GroupID = 4673 AND im.DateOfBirth = CAST(GETDATE() AS DATE) FOR XML PATH('') ) AS NVARCHAR(max)); EXEC sp_executesql @SQL;
Позвольте мне объяснить, что я здесь делаю:
Объявите @SQL и назначьте результат запроса, переданного в NVARCHAR (макс.).
DECLARE @SQL NVARCHAR(MAX); SELECT @SQL = CAST((
XML-движок используется для concat-строк, что намного быстрее, чем при использовании обычного contattenation, [text ()] гарантирует, что никакие теги XML не будут окружать код SQL.
SELECT [text()] = REPLACE(REPLACE('
Это шаблон кода SQL, который будет сгенерирован с помощью заполнителей, которые будут заменены.
EXEC msdb.dbo.sp_send_dbmail @profile_name=''eMail Profile'', @recipients=''{email}'', @subject=''Happy Birthday'', @body=''Happy BirthDay to {fullname}'', @body_format = ''text''; '
Замена заполнителей, '{fullname}', im.FullName), '{email}', cm.PersonalEmail) Запрос, который определит, сколько итераций необходимо.
FROM tblIndividualMst im INNER JOIN tblContactMst cm ON cm.ContactID = im.ContactID WHERE im.GroupID = 4673 AND im.DateOfBirth = CAST(GETDATE() AS DATE)
Скажите SQL для генерации XML для этого запроса, но, воспользовавшись пустой строкой и используя [text ()], мы убедились, что в результат не включены никакие теги.
FOR XML PATH('')
Передача XML в NVARCHAR (макс.)
) AS NVARCHAR(max));
И, наконец, казнь!
EXEC sp_executesql @SQL;