微软BI 之SSIS 系列 - 使用 Script Task 访问非 Windows 验证下的 SMTP 服务器发送邮件
原文:微软BI 之SSIS 系列 - 使用 Script Task 访问非 Windows 验证下的 SMTP 服务器发送邮件
开篇介绍
大多数情况下我们的 SSIS 包都会配置在 SQL Agent Job 中周期性的按计划执行,比如每天晚上调用 SSIS 包刷新数据,处理 Cube 等。一旦 SSIS 包中出现任何异常,报错,那么配置在 SQL Agent Job 中的通知,邮件提醒就会把这些错误信息发邮件到指定的用户或者系统维护者,这样就起到了一个错误监控的作用。
但是在有的情况下,有一些自定义的 SSIS 调度框架的计划调度都不是通过 SQL Agent Job 配置来完成的。比如我以前在一个小项目中设计过一个 SSIS 调度框架,只有一个主包配置在 SQL Agent Job 中,所有子包的上线不由 SQL Agent Job 支配。每次新增的子包要上线,只需要将相应的信息以及调度计划注册到相应的表中即可,不需要打开 SQL Agent Job 调整各个子包的执行顺序等等。那么在这种情况下,就只能在 SSIS 内部使用发送邮件的功能来发送错误信息,因为所有的子包和 SQL Agent Job 都是没有直接关系的。
在 SSIS 中我们可以通过 Send Mail Task 或者 Script Task 来发送邮件,当然还有第三种方式就是写存储过程调用发送邮件存储过程.
Send Mail Task 发送邮件
Send Mail Task 的使用其实非常的简单,配置的步骤也并不多,但是在使用它的时候有几个限制:
- 只能发送普通的文本格式的邮件,也就是说不支持 HTML 格式的邮件。
- 连接 SMTP Server 时不支持用户填写用户名和密码,也就是说用户要么在域环境下 SMTP Server 对用户进行 Windows 方式验证,要么就是访问的 SMTP Server 支持匿名访问,不需要提供用户名和密码。
- SMTP Server 的端口号使用默认的,也就是说如果在域中的 SMTP Server 端口号不是默认的话 Send Mail Task 就无法使用了。
这里是我常用的一个测试服务器地址 http://www.yopmail.com/en/ ,免费的并支持匿名访问,可以通过它来进行邮件发送的测试。关于 Send Mail Task 的使用方式就不在这里演示了,在非域和非 Windows 验证方式下用我提到的可匿名访问的 Yop Mail 一试便知,主要是讲 Script Task 发送邮件的方式。
Script Task 发送邮件
新建一个包并首先创建一个 SMTP 连接 - New Connection。
选择 SMTP 连接管理器。
以我的邮箱为例子 BIWORK@126.com 发送邮箱服务器是 smtp.126.com,这个可以在网易邮箱配置页面查到。但是非常遗憾!在这里仍然是没有地方可以配置用户名和密码的,默认的情况下仍然是只支持 Windows 验证或者匿名访问。
所以说,如果想要在 SMTP Connection 里自己动手配置用户名和密码是不可能的,那么像这种 163,126等等很多很多邮箱直接通过 SMTP Connection 是肯定无法完成发送邮件操作的。
看下图时一定要理解一点:几乎每一个 SSIS 控件的属性都是可配置的,也是可获取的,这是我们在 SSIS ETL 的学习过程中解决很多很多问题的最关键的地方!
新建一些常用的变量,发件人,收件人,抄送,邮件标题,内容,附件地址,还有用户名和密码等。
PS:关于这个密码有一个故事,以前在公司里有一个管机房管电脑的同事,他的网络下载速度最快也没人管,他的电脑里有各种游戏,高清蓝光和 1024。每次大家伙要点东西像挤牙膏似的,大家都在想办法搞他的密码,直到后来大家有意无意记了并试出了密码 - 大概就是 lowformat1MBD!! 类似于这样的!看了密码之后我们都一致认为这个密码确实很符合他的职业,不过貌似苦大仇深啊!
其中 PV_CONTENT 变量描述的是邮件发送的 HTML 格式的内容,注意是字符串类型的因此需要双引号。
"<h1>Hi BIWORK!</h1>
<p>
This is a test email from the test SSIS package of BIWORK!
</p>
<p>Server Name - "+ @[System::MachineName] +"</p>
<p>Package Name - "+ @[System::PackageName] +"</p>
<p>Package Start Time - "+ (DT_WSTR, 12) ( DT_DBDATE) @[System::StartTime] +"</p>
<p></br>Thanks and Regards!</p>
<p>Simon</p>"
系统变量的信息也通过表达式嵌入到邮件正文中。
编辑 Script Task 并引入这些变量,Script Task 中的代码 -
using System.Net.Mail; // BIWORK Added
using System.Text.RegularExpressions; // BIWORK Added
Main 中的代码包括处理优先级,多个收件人的处理,用户名和密码,添加附件的方式等等。
public void Main()
{
// Default Priority and SMTP Server Port
int iPriority = ;
int smtpPort = ; //User::PV_ATTACHED_FILE,User::PV_CONTENT,User::PV_MAIL_FROM,
//User::PV_MAIL_TO,User::PV_MAIL_TO_CC,User::PV_TITLE
String mailFrom = Dts.Variables["User::PV_MAIL_FROM"].Value.ToString();
String mailTo = Dts.Variables["User::PV_MAIL_TO"].Value.ToString();
String mailToCC = Dts.Variables["User::PV_MAIL_TO_CC"].Value.ToString();
String mailTitle = Dts.Variables["User::PV_TITLE"].Value.ToString();
String mailContent = Dts.Variables["User::PV_CONTENT"].Value.ToString();
String mailAttachedFilePath = Dts.Variables["User::PV_ATTACHED_FILE"].Value.ToString(); // User Information
String loginUser = Dts.Variables["User::PV_LOGIN_USER"].Value.ToString();
String loginPwd = Dts.Variables["User::PV_LOGIN_PWD"].Value.ToString(); // Get SMTP Server Information from Connection Manager
String smtpServer = Dts.Connections["CM_SMTP_126"].Properties["SmtpServer"].GetValue(Dts.Connections["CM_SMTP_126"]).ToString(); try
{
SmtpClient smtpClient = new SmtpClient();
MailMessage message = new MailMessage();
MailAddress fromAddress = new MailAddress(mailFrom, "BIWORKTEST"); string[] sEmailTo = Regex.Split(mailTo, ";");
string[] sEmailToCC = Regex.Split(mailToCC, ";"); smtpClient.Host = smtpServer;
smtpClient.Port = smtpPort; // Login information
System.Net.NetworkCredential myCredentials =
new System.Net.NetworkCredential(loginUser, loginPwd);
smtpClient.Credentials = myCredentials; // Attachment
System.Net.Mail.Attachment attachment;
attachment = new System.Net.Mail.Attachment(mailAttachedFilePath);
message.Attachments.Add(attachment); message.From = fromAddress; // Multiple email to address
if (sEmailTo != null)
{
for (int i = ; i < sEmailTo.Length; ++i)
{
if (sEmailTo[i] != null && sEmailTo[i] != "")
{
message.To.Add(sEmailTo[i]);
}
}
} // Multiple cc address
if (sEmailToCC != null)
{
for (int i = ; i < sEmailToCC.Length; ++i)
{
if (sEmailToCC[i] != null && sEmailToCC[i] != "")
{
message.To.Add(sEmailToCC[i]);
}
}
} // Email priority
switch (iPriority)
{
case :
message.Priority = MailPriority.High;
break;
case :
message.Priority = MailPriority.Low;
break;
default:
message.Priority = MailPriority.Normal;
break;
} message.Subject = mailTitle;
message.IsBodyHtml = true;
message.Body = mailContent; smtpClient.Send(message);
}catch (Exception ex)
{
Dts.TaskResult = (int)ScriptResults.Failure;
}
// Close Script Task with success
Dts.TaskResult = (int)ScriptResults.Success;
}
保存并执行 SSIS 包,执行成功!
优先级别,标题,发送人等信息 -
附件信息和内容都可以看的到,包括在抄送栏中抄送给了自己,Package Start Time 的时间是来自虚机的时间,我虚机的时间还是 28日,这个是正确的 -
总结
从中可以看出,虽然在 SSIS 中提供了 SMTP 的连接方式,但是实际上它还是默认只允许通过 Windows 验证或者匿名访问的方式来访问。但是我们通过 Script Task 在 Script 中关联到了 SMTP 服务器,并同时写入用户名和密码,这样就实现了在 SSIS 中访问非域环境下第三方的 SMTP 服务器并通过身份验证且发送邮件的效果。
当然,这种方式在实际项目中可能用的并不是很多,因为项目中的邮件肯定是通过域验证的方式去访问更安全一些,毕竟系统信息的传递只能限制在域中。
在项目中使用邮件通知如是 Windows 验证的方式,有这几个点需要注意:
- 在开发与测试过程中,手动执行 SSIS Package 的这个用户要有域中发送邮件的权限,能够通过 Windows 验证。
- 当包部署到 SQL Agent Job 中后,执行 SQL Agent Job 的账号要有域发送邮件的权限,也必须能通过 Windows 验证。
- 如果不需要部署到 SQL Agent Job,那么就直接使用 Send Mail Task 通过 Windows 验证也可以直接发送错误消息提醒。
疑问
在这个例子中的代码是不是一定要像这样去访问 SMTP Server 的连接信息,感觉是不是多此一举? - 可以不用这样访问,其实很多 SMTP 的配置信息最为方便的是配置成变量,通过变量传递给 Script Task 就可以了。这里通过这样的一种方式来表示在 Script Task 中如何获取连接管理器的属性信息的,因为很多时候我们只知道如何去获取变量信息,这一点体现了 C# Script 的灵活性,我们在 Script 中可以做非常多的事情。包括这些访问 SMTP Server 如何使用 smtpClient 发送邮件的代码可以在网上找到现成的很多很多示例,而我们要做的事情就是大胆的灵活运用它们来解决我们的问题。
在我的这些文章中也提到了邮件处理相关的内容
微软BI 之SSRS 系列 - 报表邮件订阅中 SMTP 服务器匿名访问与 Windows验证, 以及如何成功订阅报表的实例
更多 BI 文章请参看 BI 系列随笔列表 (SSIS, SSRS, SSAS, MDX, SQL Server) 如果觉得这篇文章看了对您有帮助,请帮助推荐,以方便他人在 BIWORK 博客推荐栏中快速看到这些文章。
微软BI 之SSIS 系列 - 使用 Script Task 访问非 Windows 验证下的 SMTP 服务器发送邮件的更多相关文章
- 微软BI 之SSIS 系列 - 使用 Script Component Destination 和 ADO.NET 解析不规则文件并插入数据
开篇介绍 这一篇文章是 微软BI 之SSIS 系列 - 带有 Header 和 Trailer 的不规则的平面文件输出处理技巧 的续篇,在上篇文章中介绍到了对于这种不规则文件输出的处理方式.比如下图中 ...
- 微软BI 之SSIS 系列 - MVP 们也不解的 Scrip Task 脚本任务中的一个 Bug
开篇介绍 前些天自己在整理 SSIS 2012 资料的时候发现了一个功能设计上的疑似Bug,在 Script Task 中是可以给只读列表中的变量赋值.我记得以前在 2008 的版本中为了弄明白这个配 ...
- 微软BI 之SSIS 系列 - Execute SQL Task 中的 Single Row 与 Full Result Set 的处理技巧
开篇介绍 Execute SQL Task 这个控件在微软BI ETL 项目中使用的频率还是非常高的,也是大部分入门 SSIS 初学者最早接触到的几个控制流控件. 我们通常使用 Execute SQL ...
- 微软BI 之SSIS 系列 - 使用 Multicast Task 将数据同时写入多个目标表,以及写入Audit 与增量处理信息
开篇介绍 在 SSIS Data Flow 中有一个 Multicast 组件,它的作用和 Merge, Merge Join 或者 Union All 等合并数据流组件对比起来作用正好相反.非常直观 ...
- 微软BI 之SSIS 系列 - 在 SSIS 中导入 ACCESS 数据库中的数据
开篇介绍 来自 天善学院 一个学员的问题,如何在 SSIS 中导入 ACCESS 数据表中的数据. 在 SSIS 中导入 ACCESS 数据库数据 ACCESS 实际上是一个轻量级的桌面数据库,直接使 ...
- 微软BI 之SSIS 系列 - 数据仓库中实现 Slowly Changing Dimension 缓慢渐变维度的三种方式
开篇介绍 关于 Slowly Changing Dimension 缓慢渐变维度的理论概念请参看 数据仓库系列 - 缓慢渐变维度 (Slowly Changing Dimension) 常见的三种类型 ...
- 微软BI 之SSIS 系列 - Lookup 中的字符串比较大小写处理 Case Sensitive or Insensitive
开篇介绍 前几天碰到这样的一个问题,在 Lookup 中如何设置大小写不敏感比较,即如何在 Lookup 中的字符串比较时不区分大小写? 实际上就这个问题已经有很多人提给微软了,但是得到的结果就是 C ...
- 微软BI 之SSIS 系列 - 再谈Lookup 缓存
开篇介绍 关于 Lookup 的缓存其实在之前的一篇文章中已经提到了 微软BI 之SSIS 系列 - Lookup 组件的使用与它的几种缓存模式 - Full Cache, Partial Cache ...
- 微软BI 之SSIS 系列 - 带有 Header 和 Trailer 的不规则的平面文件输出处理技巧
案例背景与需求介绍 之前做过一个美国的医疗保险的项目,保险提供商有大量的文件需要发送给比如像银行,医疗协会,第三方服务商等.比如像与银行交互的 ACH 文件,传送给协会的 ACH Credit 等文件 ...
随机推荐
- socket示例代码演示程序(螺纹)
client码,如以下: import java.io.*; import java.net.*; public class DailyAdviceClient { public void go(){ ...
- C#使用ServiceController控制windows服务
C#在,使用ServiceController控制类windows服务,添加首次使用前引文:System.ServiceProcess,空间中引用:using System.ServiceProces ...
- 使用HttpURLConnection向服务器发送post和get请求(转)
一.使用HttpURLConnection向服务器发送get请求 1.向服务器发送get请求 @Test publicvoid sendSms() throws Exception{ String m ...
- ORM-Dapper+DapperExtensions
ORM-Dapper+DapperExtensions 现在成熟的ORM比比皆是,这里只介绍Dapper的使用(最起码我在使用它,已经运用到项目中,小伙伴们反馈还可以). 优点: 1.开源.轻量.小巧 ...
- 每天收获一点点------Hadoop基本介绍与安装配置
一.Hadoop的发展历史 说到Hadoop的起源,不得不说到一个传奇的IT公司—全球IT技术的引领者Google.Google(自称)为云计算概念的提出者,在自身多年的搜索引擎业务中构建了突破性的G ...
- mac在查看jre通路
于Finder于command+shift+G 选/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home 版权声明:本文博主原创 ...
- HDU 2647 Reward(图论-拓扑排序)
Reward Problem Description Dandelion's uncle is a boss of a factory. As the spring festival is comin ...
- cocos2dx 3.1.1移植安卓apk (lua交叉编译器项目 mac环境)
cocos2dx 3.1.1 lua项目安卓交叉编译 mac环境 本文基于ant,sdk,ndk,adt等软件和环境已经事前设置好 1\新建项目 在mac的终端下输入命令: cocos new t ...
- 当<script>中的type等于text/html的妙用
我们可以在<script>片断中定义一个被JS调用的代码,但代码又不在页面上显示,这时,我们可以使用下面的方法: <script id="commentTemplate&q ...
- IE打印的参数配置说明
IE自动给我们在页眉和页脚处加上了这些不必要的打印信息.如果我们不想要任何页眉和页脚的话,直接删除它们就行了.:-)大部分时候我都是这样做的.但如果你想自定义页眉和页脚的时候,该怎么做呢?上面的那些“ ...