当 table 更新时从 MySQL 触发发送电子邮件

Send email from MySQL trigger when a table updated

考虑一个table为table2,我想在这个table上加一个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;

评论的地方有什么简单的写法吗?向从 table users.

检索到的所有电子邮件 ID 发送电子邮件

我在 XAMPP(phpmyadmin) 中使用 MySQL。

你问,"is there a simple method to ... send a email"来自触发器?

答案是,不符合标准MySQL。

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

或者,您可以考虑使用 user-defined MySQL function。但是大多数生产应用程序不太喜欢构建网络功能,比如将电子邮件发送到他们的数据库中,因为性能可能是不可预测的table。

我反对那个解决方案。将发送电子邮件的负载放在数据库服务器中可能会很糟糕。

在我看来,您应该做的是创建一个 table 来对您要发送的电子邮件进行排队,并有一个过程来检查是否有要发送的电子邮件,如果是则发送它们。

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

有几种方法可以解决您的问题,我喜欢一种方法:使用 table 来排队您的 notifications/emails 和使用客户端程序来发送电子邮件。

在你继续之前,你应该确保你有一个电子邮件帐户或服务可以用来发送电子邮件。它可以是 SMTP 或任何其他服务。

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

在您的数据库中创建一个 table

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;

此 table 将保留您的所有通知和电子邮件。您的 Table 触发器或尝试发送电子邮件的事件将在 table 上方添加一条记录。然后,您的客户将按照您指定的时间间隔接收和发送电子邮件。

这是 .NET 上的示例控制台应用程序,只是为了让您了解客户端的外观。您可以根据需要进行修改。 (我使用 Entity-framework 因为它更容易和更简单)

  1. 在 Visual Studio 中创建新的控制台项目。
  2. 在包管理器控制台中,安装以下包(安装包 EntityFramework、安装包 MySQL.Data.Entity)
  3. 添加对 System.Configuration
  4. 的引用
  5. 现在打开 "App.Config" 文件并将连接字符串添加到 MySQL 数据库。
  6. 在同一个 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>
    

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

  8. 添加新项目 -> ADO.NET 实体数据模型 -> 来自数据库的 EF 设计器
  9. Select 您的连接字符串 -> 勾选 App.Config 中的保存连接设置 -> 命名您的数据库。
  10. 下一步 -> Select 仅从您的数据库中获取上述 table 并完成向导。

现在您已经连接到您的数据库和电子邮件配置。是时候阅读并发送电子邮件了。

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

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 table 中插入一条记录。大约 1 分钟后,您将收到一封发送给您指定的发件人的电子邮件。

希望这对某人有所帮助。