הקדמה:
משלוח מיילים מתוך SQL Server זו משימה פשוטה למדי: צריך רק להגדיר, לקנפג, לקסטם, לדבג, לאתחל, ולפבלש וזה עובד..
זו לפחות הייתה ההרגשה שלי בעבר, אבל החל מגרסת 2005 – משלוח מיילים נעשה הרבה יותר פשוט ונוח באמצעות הפרוצדורה msdb.dbo.sp_send_dbmail, ונוספה גם האפשרות לכתוב פרוצדורת CLR (במקרה שלנו באמצעות VB.net) ולהפעיל אותה מתוך ה-SQL Server- אופציה חשובה לגרסאות שאינן מאפשרות משלוח מיילים בדרכים אחרות.
מכיוון ש-Gmail הוא ספק שירותי המייל המוביל כיום, אני אדגים באמצעותו. מי שמשתמש בחשבון אחר, יצטרך ברוב המקרים רק לשנות את חשבון ה-smtp (החשבון המאפשר משלוח מיילים והוא מופיע בהגדרות ה-Outlook – למי שיש..).
כתיבת פרוצדורת CLR ויצירת קובץ DLL:
זו בדרך כלל המשימה שגורמת לאנשים כמוני לסגור את החלון ולעבור למשימה אחרת, ולכן זה מוגש כאן מוכן לשימוש..
יש להעתיק את הקוד הבא לתוך מסמך Notepad (או כל עורך טקסט אחר) ולשמור בתור C:\Tmp\Email.vb
Imports System.Net
Imports System.Net.Mail
Public Class StoredProcedure
<Microsoft.SqlServer.Server.SqlProcedure()> _
Public Shared Sub P_EMail(ByVal Mail_To As String, _
ByVal Mail_Cc As String, _
ByVal Mail_Bcc As String, _
ByVal Subject As String, _
ByVal From As String, _
ByVal Body As String, _
ByVal Attach As String)
Dim Smtp_Client As SmtpClient
Dim Str As String
Dim Nmbr As Integer
Using EMail As New MailMessage()
EMail.Subject = Subject
EMail.SubjectEncoding = System.Text.Encoding.Unicode
EMail.Body = Body
EMail.BodyEncoding = System.Text.Encoding.Unicode
Attach = Attach.Trim
While Attach <> ""
Nmbr = InStr(Attach, ";")
If Nmbr = 0 Then
Str = Attach
Attach = ""
Else
Str = Attach.Substring(0, Nmbr - 1)
Attach = Attach.Substring(Nmbr, Attach.Length - Nmbr)
Attach = Attach.Trim
End If
EMail.Attachments.Add(New Attachment(Str))
End While
Mail_To = Mail_To.Trim
While Mail_To <> ""
Nmbr = InStr(Mail_To, ";")
If Nmbr = 0 Then
Str = Mail_To
Mail_To = ""
Else
Str = Mail_To.Substring(0, Nmbr - 1)
Mail_To = Mail_To.Substring(Nmbr, Mail_To.Length - Nmbr)
Mail_To = Mail_To.Trim
End If
EMail.To.Add(New MailAddress(Str))
End While
Mail_Cc = Mail_Cc.Trim
While Mail_Cc <> ""
Nmbr = InStr(Mail_Cc, ";")
If Nmbr = 0 Then
Str = Mail_Cc
Mail_Cc = ""
Else
Str = Mail_Cc.Substring(0, Nmbr - 1)
Mail_Cc = Mail_Cc.Substring(Nmbr, Mail_Cc.Length - Nmbr)
Mail_Cc = Mail_Cc.Trim
End If
EMail.CC.Add(New MailAddress(Str))
End While
Mail_Bcc = Mail_Bcc.Trim
While Mail_Bcc <> ""
Nmbr = InStr(Mail_Bcc, ";")
If Nmbr = 0 Then
Str = Mail_Bcc
Mail_Bcc = ""
Else
Str = Mail_Bcc.Substring(0, Nmbr - 1)
Mail_Bcc = Mail_Bcc.Substring(Nmbr, Mail_Bcc.Length - Nmbr)
Mail_Bcc = Mail_Bcc.Trim
End If
EMail.Bcc.Add(New MailAddress(Str))
End While
EMail.From = New MailAddress(From)
EMail.IsBodyHtml = True
Smtp_Client = New SmtpClient("smtp.gmail.com", 587)
Smtp_Client.EnableSsl = True
Smtp_Client.Credentials = New NetworkCredential("MyMail@gmail.com", "MyPwd")
Smtp_Client.Send(EMail)
End Using
End Sub
End Class
כמובן שיש לשנות את שם החשבון ב-Gmail בהתאם למה שיש לכם ולציין את הסיסמה במקומות המודגשים בצהוב.
כעת יש להריץ את הפקודה הבאה דרך ה-Command Line (או דרך Start ו-Run):
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\vbc /target:library C:\Tmp\Email.vb
הפעולה תימשך כ-30 שניות לכל היותר, ובסיומה יווצר הקובץ c:\Tmp\Email.dll.
יצירת הפרוצדורה ב-SQL Server:
יש להריץ את הקוד הבא ב-Management Studio:
Use msdb
Go
Alter Database msdb Set TrustWorthy On
Go
If (Select Object_Id('P_EMail')) Is Not Null Drop Procedure dbo.P_EMail
Go
If (Select name From sys.assemblies Where name='EMail') Is Not Null Drop Assembly Email
Go
Create Assembly Email From 'C:\Tmp\Email.dll'
With Permission_Set = UnSafe
Go
Create Procedure dbo.P_EMail
@Mail_To NVarChar(Max),
@Mail_Cc NVarChar(Max),
@Mail_Bcc NVarChar(Max),
@Subject NVarChar(Max),
@From NVarChar(Max),
@Body NVarChar(Max),
@Attachment NVarChar(Max)
With Execute As Caller
As
External Name Email.StoredProcedure.P_EMail
Go
Sp_Configure 'Clr Enabled', 1
Go
ReConfigure
Go
כעת תיווצר פרוצדורה בשם P_Email שבאמצעותה ניתן יהיה לשלוח מיילים.
השימוש בפרוצדורה:
בדוגמה הבאה נשלח מייל עם קובץ גראפי לחבר אחד, עם עותק גלוי CC לשני, ועותק מוסתר BCC לשלישי; כאשר מצויין המייל (@From) אליו הם יגיבו אם יבצעו Reply:
Execute msdb..P_EMail @Mail_To = 'MyFriend1@HisMail1.com',
@Mail_Cc = 'MyFriend2@HisMail2.com',
@Mail_Bcc = 'MyFriend3@HisMail3.com',
@Subject = 'Hello friends',
@From = 'MySelf@MyMail.com',
@Body = N'מה שלומכם? זו התמונה שלי..',
@Attachment = 'C:\Tmp\MyPicture.jpg';
כמובן שאפשרויות שונות יכולות להישאר ריקות אם אין בהן צורך, או ניתן לציין מספר פריטים. למשל:
Execute msdb..P_EMail @Mail_To = 'MyFriend1@HisMail1.com;MyFriend2@HisMail2.com',
@Mail_Cc = '',
@Mail_Bcc ='',
@Subject = 'Hello friends',
@From = 'MySelf@MyMail.com',
@Body = N'מה שלומכם? הנה כמה תמונות שלי..',
@Attachment = 'C:\Tmp\Pic1.jpg;C:\Tmp\Pic2.jpg;C:\Tmp\Pic3.jpg';
אפשרות נוספת- ניתן לעצב את גוף המייל באמצעות תגיות Html:
Execute msdb..P_EMail @Mail_To = 'MyFriend1@HisMail1.com',
@Mail_Cc = '',
@Mail_Bcc ='',
@Subject = 'Hello friends',
@From = 'MySelf@MyMail.com',
@Body = N'מה שלומכם? <B>אני מרגיש טוב!</B.',
@Attachment = '';
במקרה זה גוף ההודעה יראה כך: מה שלומכם? אני מרגיש טוב!
קריאה נוספת:
מי שמעוניין לנסות אופציות נוספות – כדאי לעיין בפוסט הבא (הדוגמאות הן ב-C# ויש להעביר אותן ל-VB.net):
http://blogs.microsoft.co.il/blogs/justinangel/archive/2008/09/20/full-guide-to-system-net-mail.aspx
יש כאן בעיה אחת שצריך לציין (אם אינני טועה ), אתה צריך לפתוח את השרת שעליו ה SQL SERVER לפורט 25 על מנת שהוא יוכל לגשת לGMAIL, כשבד"כ ברוב השרתים דווקא יש חסימה על מנת להגן על ה DB.
כן, אבל צריך לפתוח רק מבפנים החוצה את הפורט ל-SMTP (שאגב במקרה של גוגל הוא לא 25).
וזה לא כ"כ בעייתי, הבעיה היא מבחוץ פנימה.
היי גרי,
לא הבנתי למה כתבת את ה-CLR sproc. אפשר לשלוח מייל דרך gmail גם באמצעות database mail סטנדרטי, רק צריך להגדיר את הפורט…
לדוגמא כאן – http://blog.sqlauthority.com/2008/08/23/sql-server-2008-configure-database-mail-send-email-from-sql-database/
ל-Saggi Neumann: בוודאי שאפשר ואולי אף יותר נוח עם msdb.dbo.sp_send_dbmail.
זו אופציה נוספת, שגם לה עשויים להיות יתרונות מסוימים, או יכולות שאין לפונקציה המובנת.
למשל – במקום ליצור Profil קשוח לשמור את ההגדרות במקום אחר ולהעביר לפרוצדורת ה-CLR.