Sql server 通过正文中的“发送邮件”任务从SQL Server表发送所有记录
我正在尝试通过发送邮件任务发送电子邮件正文中的所有表记录 我的流程:Sql server 通过正文中的“发送邮件”任务从SQL Server表发送所有记录,sql-server,ssis,ssis-2012,ssis-2008,Sql Server,Ssis,Ssis 2012,Ssis 2008,我正在尝试通过发送邮件任务发送电子邮件正文中的所有表记录 我的流程: 我使用SQLExecuteTask从表中获取行并存储在对象中 用于每个循环容器,其中我使用脚本任务将行存储在EmailMessage正文中 我使用“发送邮件”任务发送电子邮件 我只获取消息正文中表的最后记录 请指导我如何在邮件正文中一次发送所有表数据 我想我会采取一种稍微不同的方法,直接在脚本任务中递归记录集,但这看起来也会起作用。我猜您的问题是,您在每次迭代时都覆盖了User::EmailMessage。你说你得到了最后几
我想我会采取一种稍微不同的方法,直接在脚本任务中递归记录集,但这看起来也会起作用。我猜您的问题是,您在每次迭代时都覆盖了User::EmailMessage。你说你得到了最后几条记录,但看看你的代码,我想你会得到1,除非你取消注释IF
(varcollection==string.empty)
,在这种情况下你可能会得到更多
无论如何,主要的冒犯问题是
varCollection["User::EmailMessage"].Value = header;
这会在调用EmailMessage时将其正文重置为标题行
编辑:根据您的评论添加,以在每个新装运编号处重置消息。添加另一个包变量PrevShippingNum,该变量将保存上一个循环编号,以测试其是否相同或已更改。确保此变量列为脚本任务的ReadWriteVariable。然后修改脚本以包含如下内容:
Dts.VariableDispenser.GetVariables(ref varCollection);
bool newMessage = (varCollection["User::PrevShippingNum"].value != varCollection["User::ShppingNum"].value) ? true : false;
if (string.IsNullOrWhiteSpace(varCollection["User::EmailMessage"].Value.ToString()) || newMessage)
{
varCollection["User::EmailMessage"].Value = string.Format("{0}........");
}
varCollection["User::EmailMessage"].Value += string.Format("{0}......");
积极的一面是,您还可以使用新变量作为约束来确定何时发送电子邮件任务
另一种方法:
请注意,添加新子项以按ShippingNum发送电子邮件的编辑量相当大:
我将继续将您正在使用的记录集变量传递给脚本任务,并让它生成电子邮件。要清楚的是,这是为了替换您的foreach循环!以下是根据我的一个解决方案改编的一些代码:
添加对System.Data.DataSetExtensions的引用
添加以下名称空间:
using System.Data.OleDb;
using System.Net.Mail;
using System.Linq;
using System.Collections.Generic;
private void Main()
{
//using System.Data.OleDb;
OleDbDataAdapter oleAdapter = new OleDbDataAdapter();
DataTable dt = new DataTable();
oleAdapter.Fill(dt, Dts.Variables["User::OleDbRecordSetVar"].Value);
//build header row
string headerRow = string.Format("{0}........", "ShippingNum ....");
//get distinct shippingNums
var shippingNums = (from DataRow dr in dt.Rows
select (int)dr["ShppingNum"]).Distinct();
//Now Build the Differnt Emails
foreach (var num in shippingNums)
{
string emailBody = headerRow;
List<DataRow> emailLines = (from DataRow dr in dt.Rows
where (int)dr["ShippingNum"] == num
select dr).ToList<DataRow>();
foreach (DataRow line in emailLines)
{
emailBody += string.Format("{0}....", line["ColumnName1"].ToString(), line["ColumnName2"].ToString());
}
SendEmail(emailBody);
}
Dts.TaskResult = (int)ScriptResults.Success;
}
private void SendEmail(string messageBody)
{
//get the smtp server address from the SSIS connection manger
ConnectionManager smtpConnectionManager = Dts.Connections["Name Of SMTP Connection Manager"];
//note this is for trusted authentication if you want to use a username and password you will have to do some discovery
SmtpClient emailClient = new SmtpClient(smtpConnectionManager.Properties["SmtpServer"].GetValue(smtpConnectionManager).ToString());
MailMessage email = new MailMessage();
email.Priority = MailPriority.Normal;
email.IsBodyHtml = false; //change to true if you send html
//can hard code addresses if you desire I use variables to make it more flexible
email.From = new MailAddress(Dts.Variables["User::FromAddress"].Value.ToString());
email.To.Add(Dts.Variables["User::ToAddress"].Value.ToString());
email.Body = messageBody;
emailClient.Send(email);
}
使用System.Data.OleDb;
使用System.Net.Mail;
使用System.Linq;
使用System.Collections.Generic;
私有void Main()
{
//使用System.Data.OleDb;
OleDbDataAdapter oleAdapter=新的OleDbDataAdapter();
DataTable dt=新的DataTable();
oleAdapter.Fill(dt,Dts.Variables[“User::OleDbRecordSetVar”].Value);
//生成标题行
string headerRow=string.Format(“{0}…….”,“ShippingNum…”);
//获得不同的发货数量
var shippingNums=(来自dt.Rows中的DataRow dr
选择(int)dr[“ShppingNum”]).Distinct();
//现在构建不同的电子邮件
foreach(shippingNums中的var num)
{
字符串emailBody=headerRow;
列出emailLines=(来自dt.Rows中的DataRow dr)
其中(int)dr[“ShippingNum”]==num
选择dr.ToList();
foreach(emailLines中的数据行)
{
emailBody+=string.Format(“{0}..”,第[“ColumnName1”].ToString()行,第[“ColumnName2”].ToString()行);
}
sendmail(emailBody);
}
Dts.TaskResult=(int)ScriptResults.Success;
}
私有void sendmail(字符串messageBody)
{
//从SSIS连接管理器获取smtp服务器地址
ConnectionManager smtpConnectionManager=Dts.Connections[“SMTP连接管理器的名称”];
//注意:这是用于可信身份验证的。如果您想使用用户名和密码,则必须进行一些查找
SmtpClient emailClient=新的SmtpClient(smtpConnectionManager.Properties[“SmtpServer”].GetValue(smtpConnectionManager.ToString());
MailMessage email=新的MailMessage();
email.Priority=MailPriority.Normal;
email.IsBodyHtml=false;//如果发送html,则更改为true
//如果您希望我使用变量使其更灵活,可以对地址进行硬编码吗
email.From=新邮件地址(Dts.Variables[“User::FromAddress”].Value.ToString());
email.To.Add(Dts.Variables[“User::ToAddress”].Value.ToString());
email.Body=messageBody;
emailClient.Send(email);
}
我想我会采取一种稍微不同的方法,直接在脚本任务中递归记录集,但这看起来也会起作用。我猜您的问题是,您在每次迭代时都覆盖了User::EmailMessage
。你说你得到了最后几条记录,但看看你的代码,我想你会得到1,除非你取消注释IF(varcollection==string.empty)
,在这种情况下你可能会得到更多
无论如何,主要的冒犯问题是
varCollection["User::EmailMessage"].Value = header;
这会在调用EmailMessage时将其正文重置为标题行
编辑:根据您的评论添加,以在每个新装运编号处重置消息。添加另一个包变量PrevShippingNum,该变量将保存上一个循环编号,以测试其是否相同或已更改。确保此变量列为脚本任务的ReadWriteVariable。然后修改脚本以包含如下内容:
Dts.VariableDispenser.GetVariables(ref varCollection);
bool newMessage = (varCollection["User::PrevShippingNum"].value != varCollection["User::ShppingNum"].value) ? true : false;
if (string.IsNullOrWhiteSpace(varCollection["User::EmailMessage"].Value.ToString()) || newMessage)
{
varCollection["User::EmailMessage"].Value = string.Format("{0}........");
}
varCollection["User::EmailMessage"].Value += string.Format("{0}......");
积极的一面是,您还可以使用新变量作为约束来确定何时发送电子邮件任务
另一种方法:
请注意,添加新子项以按ShippingNum发送电子邮件的编辑量相当大:
我将继续将您正在使用的记录集变量传递给脚本任务,并让它生成电子邮件。要清楚的是,这是为了替换您的foreach循环!以下是根据我的一个解决方案改编的一些代码:
添加对System.Data.DataSetExtensions的引用
添加以下名称空间:
using System.Data.OleDb;
using System.Net.Mail;
using System.Linq;
using System.Collections.Generic;
private void Main()
{
//using System.Data.OleDb;
OleDbDataAdapter oleAdapter = new OleDbDataAdapter();
DataTable dt = new DataTable();
oleAdapter.Fill(dt, Dts.Variables["User::OleDbRecordSetVar"].Value);
//build header row
string headerRow = string.Format("{0}........", "ShippingNum ....");
//get distinct shippingNums
var shippingNums = (from DataRow dr in dt.Rows
select (int)dr["ShppingNum"]).Distinct();
//Now Build the Differnt Emails
foreach (var num in shippingNums)
{
string emailBody = headerRow;
List<DataRow> emailLines = (from DataRow dr in dt.Rows
where (int)dr["ShippingNum"] == num
select dr).ToList<DataRow>();
foreach (DataRow line in emailLines)
{
emailBody += string.Format("{0}....", line["ColumnName1"].ToString(), line["ColumnName2"].ToString());
}
SendEmail(emailBody);
}
Dts.TaskResult = (int)ScriptResults.Success;
}
private void SendEmail(string messageBody)
{
//get the smtp server address from the SSIS connection manger
ConnectionManager smtpConnectionManager = Dts.Connections["Name Of SMTP Connection Manager"];
//note this is for trusted authentication if you want to use a username and password you will have to do some discovery
SmtpClient emailClient = new SmtpClient(smtpConnectionManager.Properties["SmtpServer"].GetValue(smtpConnectionManager).ToString());
MailMessage email = new MailMessage();
email.Priority = MailPriority.Normal;
email.IsBodyHtml = false; //change to true if you send html
//can hard code addresses if you desire I use variables to make it more flexible
email.From = new MailAddress(Dts.Variables["User::FromAddress"].Value.ToString());
email.To.Add(Dts.Variables["User::ToAddress"].Value.ToString());
email.Body = messageBody;
emailClient.Send(email);
}
使用System.Data.OleDb;
使用System.Net.Mail;