SSIS-向不同的收件人发送电子邮件的不同数据

时间:2018-11-01 13:38:49

标签: sql-server ssis

我是SSIS的新手。

我有一个包含1500行的表,我需要从该表发送电子邮件,但是每个收件人都有来自该表的15行。

所以我需要从同一查询向不同的电子邮件发送不同的数据。

你们能帮我吗?

谢谢。

狮子座

-------------------更新------------------------

伙计们,我可以创建一个SSIS包以向不同的收件人发送电子邮件,问题是:样本:2个不同的用户正在接收有关数据库中行数的电子邮件...这太可怕了,每个客户都有15行是15封电子邮件,我只能发送一封电子邮件给客户,其中包含全部数据吗?

预先感谢...

2 个答案:

答案 0 :(得分:1)

这将根据查询和其他规范而有所不同,但是在较高的层次上,您可能需要遵循以下步骤来使用SSIS发送电子邮件。本示例假定电子邮件存储在此表的一列中。正如其他人指出的那样,使用sp_send_dbmail可能是您的最佳选择。

  • 创建两个字符串变量。一个将保存电子邮件地址,另一个将用于sp_send_dbmail的SQL地址(有关更多信息,请参见下文)。创建一个对象类型的附加变量,该变量将在执行期间保存电子邮件列表。
  • 使用带有电子邮件名称的变量,将保留sp_send_dbmail的SQL的字符串变量修改为表达式。根据查询,您可能需要为此查询中的其他参数添加其他变量。该变量的一个示例位于本文的结尾。
  • 具有一个初始的执行SQL任务,该任务可查询表并检索电子邮件地址。确保获取每个电子邮件的所有行。将ResultSet属性设置为full,然后在“结果集”窗格上,添加对象变量,并将0作为结果名称。
  • 接下来添加一个Foreach循环,使用Foreach ADO枚举器类型,并从最后一个执行SQL任务中为源变量选择对​​象变量。枚举模式可以保留为“第一个表中的行”选项。
  • 在“变量映射”窗格上,添加字符串变量(用于电子邮件地址),并将索引设置为0。这将保存每次执行sp_send_dbmail的电子邮件地址。

  • 在Foreach循环中,添加一个Execute SQL Task。为此,您需要将SQLSourceType设置为变量,并使用包含sp_send_dbmail的SQL变量。

  • 确保已为使用的帐户和配置文件正确配置了数据库邮件,包括在DatabaseMailUserRole中的msdb角色中的成员身份。您可能还需要为表使用三部分名称(database.schema.table)。

SQL变量表达式示例:

除了连接表达式的引号外,还要注意电子邮件变量周围的@ query参数中的双引号。您可以在查询中使用两个单引号或在双引号前加上\,以将双引号用作表达式的一部分。

"DECLARE @Title varchar(100)

SET @Title = 'Email Title'

EXEC MSDB.DBO.SP_SEND_DBMAIL @profile_name = 'Your Profile',
 @recipients = 'YourEmail@test.org',  

@query = 'SELECT * FROM YourDatabase.YourSchema.YourTable WHERE EmailColumn = "" 
+ @[User::VariableWithEmailAddress]  + ""',
@query_result_no_padding = 1, @subject = @Title ; "

答案 1 :(得分:0)

我有一个包裹,唯一的作用是从包裹中发送电子邮件并将结果记录到表中。我从任何发送邮件的软件包中反复使用这个软件包。

这只是一个脚本任务,需要参数并完成工作:

The Parameters received

要处理的脚本:

    public void Main()
    {
        //Read variables 
        #region ReadVariables
        string cstr = Dts.Variables["connString"].Value.ToString();
        //string sender = (string)Dts.Variables["User::Sender"].Value;
        string title = (string)Dts.Variables["$Package::Title"].Value;
        string priority = (string)Dts.Variables["$Package::Priority"].Value;
        string body = (string)Dts.Variables["$Package::Body"].Value;
        string source = Dts.Variables["$Package::Source"].Value.ToString();
        string directTo = Dts.Variables["$Package::DirectMail"].Value.ToString();
        string groups = Dts.Variables["$Package::MailGroups"].Value.ToString();



        #endregion


        //Send Email
        #region SendMail
        MailMessage mail = new MailMessage();
        //mail.From = new MailAddress(sender);
        mail.Subject = title;
        mail.Body = body;
        mail.IsBodyHtml = true;

        switch(priority.ToUpper())
        {
            case "HIGH":
                mail.Priority= MailPriority.High;
                priority = "High";
                break;
            default:
                mail.Priority=MailPriority.Normal;
                priority = "Normal";
                break;
        }

        DataTable dt = new DataTable(); //This is going to be a full distribution list

        //Fill table with group email
        if (groups.Split(',').Length > 0)
        {
            foreach (string group in groups.Split(','))
            {
                string strCmd = "mail.spGetEmailAddressesByGroup";
                using (OleDbConnection conn = new OleDbConnection(cstr))
                {
                    using (OleDbCommand cmd = new OleDbCommand(strCmd, conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.AddWithValue("A", group);
                        OleDbDataAdapter da = new OleDbDataAdapter(cmd);
                        da.Fill(dt);
                    }
                }
            }
        }

        //add the directs to email
        if (directTo.Split(',').Length > 0)
        {
            foreach (string m in directTo.Split(','))
            {
                if (m != "")
                {
                    DataRow dr = dt.NewRow();
                    dr[0] = "TO";
                    dr[1] = m;
                    dt.Rows.Add(dr);
                }
            }
        }

        //Add from and reply to defaults
        DataRow dr2 = dt.NewRow();
        dr2[0] = "REPLYTO";
        dr2[1] = ""; //WHERE DO YOU WANT REPLIES
        dt.Rows.Add(dr2);
        DataRow dr3 = dt.NewRow();
        dr3[0] = "FROM";
        dr3[1] = ""; //ENTER WHO YOU WANT THE EMAIL TO COME FROM
        dt.Rows.Add(dr3);

        //Bind dt to mail
        foreach (DataRow dr in dt.Rows)
        {
            switch (dr[0].ToString().ToUpper())
            {
                case "TO":
                    mail.To.Add(new MailAddress(dr[1].ToString()));
                    dr[0] = "To";
                    break;
                case "CC":
                    mail.CC.Add(new MailAddress(dr[1].ToString()));
                    dr[0] = "Cc";
                    break;
                case "BCC":
                    mail.Bcc.Add(new MailAddress(dr[1].ToString()));
                    dr[0] = "Bcc";
                    break;
                case "REPLYTO":
                    mail.ReplyToList.Add(new MailAddress(dr[1].ToString()));
                    dr[0] = "ReplyTo";
                    break;
                case "FROM":
                    mail.From = new MailAddress(dr[1].ToString());
                    dr[0] = "From";
                    break;
                case "SENDER":
                    mail.Sender = new MailAddress(dr[1].ToString());
                    dr[0] = "Sender";
                    break;
                default:
                    dr[0] = "NotSent";
                    break;
            }
        }



        try
        {
            SmtpClient smtp = new SmtpClient();
            smtp.Port = 25;
            smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
            smtp.UseDefaultCredentials = false;
            smtp.Host = ""; //ENTER YOUR IP / SERVER 
            smtp.Send(mail);
        }
        catch (Exception e)
        {

        }
        #endregion

        //Record email as sent //I WILL NOT BE PROVIDING THIS PART
        //#region RecordEmailInDB

那只是为了发送邮件,我有很多软件包可以构建要发送的电子邮件。大多数是调用中参数的变量。最复杂的是电子邮件正文的构建,这是您的特定问题发挥作用的地方。

这是示例控制流:

Control Flow of Body Builder

有一个数据流查询需要发送的详细信息并将其记录到一个对象中。以及记录计数器。

enter image description here

返回控制流。行计数> 0设置了优先约束。

我有一个脚本任务来基本构建主体。而且我有一个将ADO对象转换为HTML表的类。

    public string BuildHTMLTablefromDataTable(DataTable t)
    {
        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        sb.Append("<table border='1'><tr style='background-color: #1A5276; color:#FFFFFF;'>");

        foreach (DataColumn c in t.Columns)
        {
            sb.Append("<th align='left'>");
            sb.Append(c.ColumnName);
            sb.Append("</th>");
        }

        sb.Append("</tr>");

        int rc = 0;

        foreach (DataRow r in t.Rows)
        {
            rc++;
            //every other row switches from white to gray
            string OpeningTR = "<tr style='background-color: " + ((rc % 2 == 1) ? "#E5E7E9;'>" : "#FCF3CF;'>");
            sb.Append(OpeningTR);

            foreach (DataColumn c in t.Columns)
            {
                sb.Append("<td align='left'>");
                sb.Append(System.Web.HttpUtility.HtmlEncode(
                                                            r[c.ColumnName] == null ? String.Empty : r[c.ColumnName].ToString()
                                                            )); //This will handle any invalid characcters and convert null to empty string
                sb.Append("</td>");
            }

            sb.Append("</tr>");
        }

        sb.Append("</table>");

        return sb.ToString();
    }


    public string BuildBody(DataTable dt)
    {

        string body = "<P>The following are vouchers that are not in the voucher table but in the GL:</p>";

        DataView v = new DataView(dt);
        body += BuildHTMLTablefromDataTable(dt); //v.ToTable(true, "Name", "LastVisit", "DaysUntilTimeout", "ExpDate", "RoleName"));

        return body;
    }


    public void Main()
    {
        #region Read Variables
        System.Data.OleDb.OleDbDataAdapter da = new System.Data.OleDb.OleDbDataAdapter();
        DataTable dt = new DataTable();
        da.Fill(dt, Dts.Variables["User::Changes"].Value);
        #endregion

        string body = BuildBody(dt);

        Dts.Variables["User::Body"].Value = body;


        Dts.TaskResult = (int)ScriptResults.Success;
    }

最后,我将调用SendMail程序包并传递参数。

出于您的目的,您需要围绕此软件包进行一次foreach,并在每次通过时为该人调整您的where子句。

这是发送电子邮件的示例(仅限正文):

Body of email