更新表时从MySQL触发器发送电子邮件

时间:2015-03-07 16:54:30

标签: mysql sql email triggers sendmail

将表格视为table2,我想在此表trigger上添加update

select Num into num from table1 where ID=new.id;
BEGIN
DECLARE done int default false;
DECLARE cur1 CURSOR FOR select EmailId from users where Num=num;
DECLARE continue handler for not found set done = true;
OPEN cur1;
my_loop: loop
    fetch cur1 into email_id;
    if done then
        leave my_loop;
    end if;
    //send mail to all email id.
end loop my_loop;
close cur1;
END;

在评论的地方有没有简单的方法?向从表users检索到的所有电子邮件ID发送电子邮件。

我在XAMPP(phpmyadmin)中使用MySQL。

3 个答案:

答案 0 :(得分:4)

我反对这个解决方案。在数据库服务器中发送电子邮件的负担可能会非常糟糕。

在我看来,您应该做的是创建一个表格,对您要发送的电子邮件进行排队,并设置一个流程来检查是否有要发送的电子邮件,如果是肯定的,则发送这些电子邮件。

答案 1 :(得分:2)

正如大家所说,让您的数据库处理电子邮件是一个坏主意。使数据库编写外部文件是另一个坏主意,因为与数据库操作相比,IO操作非常耗时。

有几种方法可以解决您的问题,我喜欢的方法是:有一个表来排队通知/电子邮件,还有一个客户端程序来发送电子邮件。

在继续之前,您应确保拥有可用于发送电子邮件的电子邮件帐户或服务。它可以是SMTP或任何其他服务。

如果你在.NET上,你可以复制它,如果没有你知道如何在你的平台上重写

在数据库中创建一个表

CREATE TABLE `tbl_system_mail_pickup` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `mFrom` varchar(128) NOT NULL DEFAULT 'noreplyccms@YourDomain.co.uk',
  `mTo` varchar(128) NOT NULL,
  `mCC` varchar(128) DEFAULT NULL,
  `mBCC` varchar(128) DEFAULT NULL,
  `mSubject` varchar(254) DEFAULT NULL,
  `mBody` longtext,
  `added_by` varchar(36) DEFAULT NULL,
  `updated_by` varchar(36) DEFAULT NULL,
  `added_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `email_sent` bit(1) DEFAULT b'0',
  `send_tried` int(11) DEFAULT '0',
  `send_result` text,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

此表格将包含您的所有通知和电子邮件。您的表触发器或尝试发送电子邮件的事件将向上表添加记录。然后,您的客户将以您指定的间隔提取电子邮件并发送。

以下是.NET上的示例控制台应用程序,旨在让您了解客户端的外观。您可以根据需要进行修改。 (我使用实体框架更简单,更简单)

  1. 在Visual Studio中创建新的控制台项目。
  2. 在软件包管理器控制台中,安装以下软件包(install-package EntityFramework,install-package MySQL.Data.Entity)
  3. 添加对System.Configuration的引用
  4. 现在打开“App.Config”文件并将连接字符串添加到MySQL数据库中。
  5. 在同一个App.Config文件中,添加您的SMTP电子邮件设置。 检查您的端口和ssl选项

      <system.net>
    <mailSettings>
      <smtp from="Noreplyccms@youractualEmailAccount.co.uk">
        <network host="smtp.office365.com(your host)" port="587" enableSsl="true" password="dingDong" userName="YourUsername@YourDomain" />
      </smtp>
    </mailSettings>
    

  6. 在项目树中创建名为Models的新文件夹。

  7. 添加新项目 - &gt; ADO.NET实体数据模型 - &gt;来自数据库的EF Designer
  8. 选择您的连接字符串 - &gt;勾选App.Config中的保存连接设置 - &gt;命名您的数据库。
  9. 下一步 - &gt;从数据库中仅选择上表并完成向导。
  10. 现在,您已建立了与数据库和电子邮件配置的连接。是时候阅读电子邮件并发送它们了。

    这是一个完整的程序来理解这个概念。如果你有win应用程序,或者web应用程序合作这个想法,你可以修改它。 此控制台应用程序将检查每个分钟的新电子邮件记录并分发它们。您可以扩展上表和此脚本以便能够添加附件。

    using System;
    using System.Linq;
    using System.Timers;
    using System.Data;
    using System.Net.Mail;
    using ccms_email_sender_console.Models;
    
    namespace ccms_email_sender_console
    {
        class Program
        {
    
           static Timer aTimer = new Timer();
            static void Main(string[] args)
            {
    
                aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);// add event to timer
                aTimer.Interval = 60000; // timer interval 
                aTimer.Enabled = true;
    
                Console.WriteLine("Press \'q\' to exit");
                while (Console.Read() != 'q');
    
            }
    
            private static void OnTimedEvent(object source, ElapsedEventArgs e)
            {
                var db_ccms_common = new DB_CCMS_COMMON(); // the database name you entered when creating ADO.NET Entity model
                Console.WriteLine(DateTime.Now+"> Checking server for emails:");
                aTimer.Stop(); /// stop the timer until we process current queue
    
                var query = from T1 in db_ccms_common.tbl_system_mail_pickup where T1.email_sent == false select T1; // select everything that hasn't been sent or marked as sent.
    
                try
                {
                    foreach (var mRow in query)
                    {
                        MailMessage mail = new MailMessage();
                        mail.To.Add(mRow.mTo.ToString());
                        if (mRow.mCC != null && !mRow.mCC.ToString().Equals(""))
                        {
                            mail.CC.Add(mRow.mCC.ToString());
    
                        }
                        if (mRow.mBCC != null && !mRow.mBCC.ToString().Equals(""))
                        {
                            mail.CC.Add(mRow.mBCC.ToString());
    
                        }
                        mail.From = new MailAddress(mRow.mFrom.ToString());
                        mail.Subject = mRow.mSubject.ToString();
                        mail.Body = mRow.mBody.ToString();
                        mail.IsBodyHtml = true;
    
                        SmtpClient smtp = new SmtpClient();
    
                        smtp.Send(mail);
    
                        mRow.email_sent = true;
                        Console.WriteLine(DateTime.Now + "> email sent to: " + mRow.mTo.ToString());
                    }
    
                    db_ccms_common.SaveChanges(); // mark all sent emails as sent. or you can also delete the record.
    
                    aTimer.Start(); // start the timer for next batch
                }
                catch (Exception ex)
                {
    
                    Console.WriteLine(DateTime.Now + "> Error:" + ex.Message.ToString());
                    // you can restart the timer here if you want
    
                }
    
            }
    
        }
    }
    

    测试:运行上面的代码并将记录插入到tbl_system_mail_pickup表中。大约1分钟后,您将收到一封发送给您指定的发件人的电子邮件。

    希望这有助于某人。

答案 2 :(得分:1)

你问,“是否有一种简单的方法可以从触发器发送电子邮件?”

答案是没有,而不是标准的MySQL。

这通常是通过创建某种pending_message表并编写客户端程序来定期轮询该表并发送消息来完成的。

或者,您可以考虑使用user-defined MySQL function。但是大多数生产应用程序并不像将电子邮件发送到数据库中那样构建网络功能,因为性能可能无法预测。