2009-05-20 3 views
3

Я бы хотел отправить электронное письмо для каждой строки набора результатов, используя sp_send_dbmail.Отправить электронное письмо для каждой строки в результирующем наборе

Каков подходящий способ для этого без использования петель?

Редактировать: Я не настаиваю на том, что цикл здесь не подходит, но существует ли способ, основанный на множестве. Я попытался создать функцию, но функция не может вызвать хранимую процедуру внутри нее. Только другой func или extended sp (который я бы тоже не сделал).

+1

Петли, кажется, идеально подходит для этого. Не могли бы вы объяснить, почему вы хотели бы избежать их? –

+0

Петли - плохая идея для этого типа вещей. См. Ниже – NotMe

+0

Мне не нравятся пишущие петли и предпочитаю использовать метод, основанный на наборе. – Sam

ответ

0

Лучший способ добиться этого - поместить логику отправки электронной почты в определенную пользователем функцию.

Тогда вы просто вызвать ВЫБЕРИТЕ MyEmailFunc (EMAILADDRESS) FROM MyTable

Это позволяет избежать петель, и вы можете даже использовать его в операторе обновления, чтобы показать, что сообщение было отправлено. Например:

UDPATE MyTable SET SENT = MyEmailFunc (EmailAddress) где отправленного = 0

+0

Что делать, если запрос не удался между ними? Вы потеряете свой набор результатов и даже не узнаете, каково ваше последнее электронное письмо, которое преуспело. – Quassnoi

+1

Функции и расширенные хранимые процедуры могут выполняться внутри функции. – Sam

+0

Просто используйте инструкцию UPDATE. Функция должна иметь код ошибки и отправить соответствующий результат. – NotMe

3

Этот случай точно подходит для петель (и предназначен для).

Поскольку вы делаете то, что выпадает из области базы данных, вполне законно использовать для них циклы.

Базы данных предназначены для хранения данных и выполнения запросов к этим данным, которые возвращают их наиболее удобным образом.

Реляционные базы данных могут возвращать данные в виде наборов строк.

Курсоры (и их циклы) предназначены для сохранения стабильного набора строк, чтобы можно было выполнить некоторые вещи с каждой из его строк.

Под «вещами» здесь я имею в виду не чистые трюки базы данных, а реальные вещи, которые влияют на внешний мир, на которые предназначена база данных, будь то отображение таблицы на веб-странице, создание финансового отчета или отправка по электронной почте ,

Плохо использовать курсоры для чистых задач базы данных (например, преобразование одного набора строк в другое), но совершенно приятно использовать их для таких вещей, которые вы описали.

Наборы основанных методов предназначены для работы в рамках одной транзакции.

Если ваш запрос на базовую базу по какой-то причине не удастся, ваша база данных вернется к состоянию, указанному ранее, но вы не сможете «откат» отправленного сообщения. Вы не сможете отслеживать свои сообщения в случае ошибки.

+0

Я знаю, что это нормально использовать цикл для этого типа вещей, но было интересно, есть ли другой способ. Надеюсь, кто-то найдет ваш обширный текст полезным: P – Sam

+0

Наборы основанные на операции просто не подходят для этого. Я попытался сделать то, что вы описываете в PostgreSQL около 10 лет назад (печать счетов в ресторане), и это оказалось кошмаром по причинам, которые я описал, и многим другим. Просто используйте циклы :) – Quassnoi

0

Не лучшая практика, но если вы хотите, чтобы избежать петли:

Вы можете создать «SendMails» таблицу с триггером на Insert

sp_send_dbmail называется внутри триггера

то вы делаете:

Truncate Table SendMails 

insert into SendMails (From, To, Subject,text) Select field1,field2,field3,field4 from MyTable 
0

Это должно быть строка за строкой, если вам нужна электронная почта для каждой строки. Это не стандартное действие на основе набора.

Либо вы ПОКА через него в SQL или «для каждого» на языке клиента

Я бы не отправлять электронные письма от триггеров BTW: транзакция открыта в то время как триггер выполняет

+0

Новое электронное письмо в sql-сервере на самом деле не ожидает отправки электронной почты. Он помещается в очередь и обрабатывается отдельным .exe – Sam

+0

Я все еще не делал бы этого в триггере, и я бы не зацикливался на триггере – gbn

0

Настройка данных -driven в службах SQL Server Reporting Services :-D

Звучит как требование SSRS для меня - TSQL не предназначен для самостоятельной отчетности.

Смежные вопросы