我想使用sp_send_dbmail为结果集的每一行发送一封电子邮件。
在不使用循环的情况下完成此操作的适当方法是什么?
编辑:我不是坚持循环不适合这里,但有没有基于设置的方法来做到这一点。我试过创建一个函数,但函数不能在其中调用存储过程。只有另一个函数或扩展的sp(我不想这样做)。
答案 0 :(得分:3)
这种情况正是环路适合(和设计用于)。
由于您执行的操作超出了数据库范围,因此为它们使用循环是完全合法的。
数据库旨在存储数据并对这些数据执行查询,这些数据以最便捷的方式返回。
关系数据库可以以行集的形式返回数据。
游标(以及使用它们的循环)旨在保持稳定的行集,以便可以完成每行的某些操作。
这里的“事物”我的意思不是纯粹的数据库技巧,而是影响外部世界的真实事物,数据库的设计目的,是在网页上显示表格,生成财务报告或发送电子邮件。
将游标用于纯数据库任务(例如将一个行集转换为另一个行集)是不好的,但将它们用于您所描述的那些行为非常好。
基于集合的方法旨在在单个事务中工作。
如果您的set-base查询由于某种原因失败,您的数据库将恢复到之前的状态,但您无法“回滚”已发送的电子邮件。如果发生错误,您将无法跟踪您的消息。
答案 1 :(得分:0)
不是最好的做法,但如果你想避免循环:
你可以创建一个“SendMails”表,在Insert
上有一个触发器从触发器
中调用sp_send_dbmail然后你做:
Truncate Table SendMails
insert into SendMails (From, To, Subject,text) Select field1,field2,field3,field4 from MyTable
答案 2 :(得分:0)
如果每行需要一封电子邮件,则必须是逐行操作。这不是基于标准集的行动。
您可以在SQL中使用它,也可以在客户端语言中使用“for each”
我不会从触发器BTW发送电子邮件:您的交易在触发器执行时打开
答案 3 :(得分:0)
在SQL Server Reporting Services中设置数据驱动的订阅:-D
对我来说听起来像SSRS的要求 - TSQL并非真正用于报告本身。
答案 4 :(得分:0)
实现此目的的最佳方法是将您的电子邮件发送逻辑放在用户定义的函数中。
然后你只需要调用SELECT MyEmailFunc(emailaddress)FROM MyTable
它避免了循环,您甚至可以在更新语句中使用它来显示电子邮件已发送。例如:
UDPATE MyTable SET SENT = MyEmailFunc(emailaddress)WHERE sent = 0