原文:微软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 的使用其实非常的简单,配置的步骤也并不多,但是在使用它的时候有几个限制:

  1. 只能发送普通的文本格式的邮件,也就是说不支持 HTML 格式的邮件。
  2. 连接 SMTP Server 时不支持用户填写用户名和密码,也就是说用户要么在域环境下 SMTP Server 对用户进行 Windows 方式验证,要么就是访问的 SMTP Server 支持匿名访问,不需要提供用户名和密码。
  3. 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 验证的方式,有这几个点需要注意:

  1. 在开发与测试过程中,手动执行 SSIS Package 的这个用户要有域中发送邮件的权限,能够通过 Windows 验证。
  2. 当包部署到 SQL Agent Job 中后,执行 SQL Agent Job 的账号要有域发送邮件的权限,也必须能通过 Windows 验证。
  3. 如果不需要部署到 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 服务器发送邮件的更多相关文章

  1. 微软BI 之SSIS 系列 - 使用 Script Component Destination 和 ADO.NET 解析不规则文件并插入数据

    开篇介绍 这一篇文章是 微软BI 之SSIS 系列 - 带有 Header 和 Trailer 的不规则的平面文件输出处理技巧 的续篇,在上篇文章中介绍到了对于这种不规则文件输出的处理方式.比如下图中 ...

  2. 微软BI 之SSIS 系列 - MVP 们也不解的 Scrip Task 脚本任务中的一个 Bug

    开篇介绍 前些天自己在整理 SSIS 2012 资料的时候发现了一个功能设计上的疑似Bug,在 Script Task 中是可以给只读列表中的变量赋值.我记得以前在 2008 的版本中为了弄明白这个配 ...

  3. 微软BI 之SSIS 系列 - Execute SQL Task 中的 Single Row 与 Full Result Set 的处理技巧

    开篇介绍 Execute SQL Task 这个控件在微软BI ETL 项目中使用的频率还是非常高的,也是大部分入门 SSIS 初学者最早接触到的几个控制流控件. 我们通常使用 Execute SQL ...

  4. 微软BI 之SSIS 系列 - 使用 Multicast Task 将数据同时写入多个目标表,以及写入Audit 与增量处理信息

    开篇介绍 在 SSIS Data Flow 中有一个 Multicast 组件,它的作用和 Merge, Merge Join 或者 Union All 等合并数据流组件对比起来作用正好相反.非常直观 ...

  5. 微软BI 之SSIS 系列 - 在 SSIS 中导入 ACCESS 数据库中的数据

    开篇介绍 来自 天善学院 一个学员的问题,如何在 SSIS 中导入 ACCESS 数据表中的数据. 在 SSIS 中导入 ACCESS 数据库数据 ACCESS 实际上是一个轻量级的桌面数据库,直接使 ...

  6. 微软BI 之SSIS 系列 - 数据仓库中实现 Slowly Changing Dimension 缓慢渐变维度的三种方式

    开篇介绍 关于 Slowly Changing Dimension 缓慢渐变维度的理论概念请参看 数据仓库系列 - 缓慢渐变维度 (Slowly Changing Dimension) 常见的三种类型 ...

  7. 微软BI 之SSIS 系列 - Lookup 中的字符串比较大小写处理 Case Sensitive or Insensitive

    开篇介绍 前几天碰到这样的一个问题,在 Lookup 中如何设置大小写不敏感比较,即如何在 Lookup 中的字符串比较时不区分大小写? 实际上就这个问题已经有很多人提给微软了,但是得到的结果就是 C ...

  8. 微软BI 之SSIS 系列 - 再谈Lookup 缓存

    开篇介绍 关于 Lookup 的缓存其实在之前的一篇文章中已经提到了 微软BI 之SSIS 系列 - Lookup 组件的使用与它的几种缓存模式 - Full Cache, Partial Cache ...

  9. 微软BI 之SSIS 系列 - 带有 Header 和 Trailer 的不规则的平面文件输出处理技巧

    案例背景与需求介绍 之前做过一个美国的医疗保险的项目,保险提供商有大量的文件需要发送给比如像银行,医疗协会,第三方服务商等.比如像与银行交互的 ACH 文件,传送给协会的 ACH Credit 等文件 ...

随机推荐

  1. 提高duilib的richedit控制的一些特征

    转载请注明原始出处.谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/41208207 假设要使用透明异形窗口功能,首先要改进duilib库让他 ...

  2. linux 字符界面浏览器 w3m(转)

    最近找到了几个linux终端下使用的浏览器,主要用来测试本机web服务器是否搭建成功.因为我们一般是用ssh客户端连接linux的,所以很需要一个字符界面的浏览器.找了几个显示都不理想,只有w3m用起 ...

  3. UVa 208 - Firetruck 回溯+剪枝 数据

    题意:构造出一张图,给出一个点,字典序输出所有从1到该点的路径. 裸搜会超时的题目,其实题目的数据特地设计得让图稠密但起点和终点却不相连,所以直接搜索过去会超时. 只要判断下起点和终点能不能相连就行了 ...

  4. vs2010公布时去除msvcp100.dll和msvcr100.dll图讲解明

    近期开发个程序,Copy到虚拟机环境中測试时提示缺少msvcr100.dll,于是想到编译时设置选项去除依赖. 什么是 msvcr100.dll MS = Microsoft V = Visual C ...

  5. Cocos2d-x3.3它DrawPrimitivesTest分析

    1.代码列表 2.VisibleRect类 该类是test-cpp自带工具类 3.HelloWorldScene类 同前面代码 4.DrawPrimitivesDemo类 1).h文件 #includ ...

  6. strtok、strtok_s、strtok_r 字符串切割函数

    1.strtok函数 函数原型:char * strtok (char *str, const char * delimiters); 參数:str,待切割的字符串(c-string):delimit ...

  7. PHP操作XML文件学习笔记

    原文:PHP操作XML文件学习笔记 XML文件属于标签语言,可以通过自定义标签存储数据,其主要作用也是作为存储数据. 对于XML的操作包括遍历,生成,修改,删除等其他类似的操作.PHP对于XML的操作 ...

  8. 5、VS2010+ASP.NET MVC4+EF4+JqueryEasyUI+Oracle该项目的开发——使用datagrid做报表

    来点需要:我使用的数据库访问EF框架,但是,因为使用一个动态表来的统计报告中.单独是每天产生基于数据表,它是很难使用EF加盟前.所以我包装在两组数据库存取层的框内,一个是EF,一种是传统的ADO.NE ...

  9. UVALive 5099 Nubulsa Expo 全球最小割 非网络流量 n^3

    主题链接:点击打开链接 意甲冠军: 给定n个点m条无向边 源点S 以下m行给出无向边以及边的容量. 问: 找一个汇点,使得图的最大流最小. 输出最小的流量. 思路: 最大流=最小割. 所以题意就是找全 ...

  10. ftp设置(2015-04-04)[转]

    anonymous_enable=YES /允许匿名访问 12行local_enable=YES /允许本地用户访问(/etc/passwd中的用户) 15行write_enable=YES /允许写 ...