How do I compile SQL email but not send? - sql-server

In SQL Server, it's possible to send an email via Outlook.
I want to compile an email but have it automatically sent. The code below automatically queues the email and sends to the recipients. I need to make adjustments on the email before sending it out. These adjustments account for dates. Is that possible?
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'Email Team',
#recipients='username#eemail.com',
#subject='Monthly Report',
#body='Good morning, reports have ran for these dates: ',
#body_format='HTML',
#from_address='<username#email.com>'
As a result, I get this:
Mail (Id: 3549) queued.

Related

SQL Server Mail senging error using sp_send_dbmail on gmail server

I am setting up a trigger based mail notification and while using it, I am also getting error.
The Profile setup is as bellow:
EXECUTE msdb.dbo.sysmail_add_account_sp #account_name = 'TestMailAccount',
#description = 'Test Mail Account for sending notifications',
#email_address = 'my_gmail_id#gmail.com',
#display_name = 'Test Mail Notification',
#username = 'my_gmail_id#gmail.com',
#password = 'my_gmail_password',
#mailserver_name = 'smtp.gmail.com',
#port = 587,
#enable_ssl = 1;
EXECUTE msdb.dbo.sysmail_add_profile_sp #profile_name = 'TestMailProfile',
#description = 'Main test profile used to send notification email';
EXECUTE msdb.dbo.sysmail_add_profileaccount_sp #profile_name = 'TestMailProfile',
#account_name = 'TestMailAccount',
#sequence_number = 2;
EXECUTE msdb.dbo.sysmail_add_principalprofile_sp
#profile_name = 'TestMailProfile',
#principal_name = 'public',
#is_default = 0;
Now to send the mail, I executed:
DECLARE #mail_body NVARCHAR(MAX);
SET #mail_body = CONCAT( N'<html>',
N'<body>',
N'<h1>Test Mail</h1>',
N'</body>',
N'</html>');
EXECUTE msdb.dbo.sp_send_dbmail
#profile_name = 'TestMailProfile',
#recipients = 'dest#gmail.com',
#subject = N'DB Test Mail',
#body = #mail_body,
#body_format = 'HTML';
After this, I checked the log:
select * from sysmail_event_log
The description shows:
The mail could not be sent to the recipients because of the mail server failure. (Sending Mail using Account 42 (2020-03-01T18:41:09). Exception Message: Cannot send mails to mail server. (The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.0 Authentication Required. Learn more at).
I already have enabled google account's setting for using Less secure app access.
I am not sure what I am missing and any help will be highly appritiated.
Gmail settings look correct. With the caveat of "try different port" (also mentioned in the comments of the original question above)
From https://granadacoder.wordpress.com/2006/02/08/smarter-emailsmtp-setup-with-dotnet-configuration-sections-1-1-and-2-0/
<!–Note, with the 2.0 Framework, my tests show that gmail likes port 587–>
<smtpServer
smtpServerName="smtp.gmail.com"
defaultEmailFrom="donotreply#gmail.com"
portNumber="465"
authenicationMode="SSL"
smtpUserName="mygmailaddress#gmail.com"
smtpUserPassword="mygmailpassword"/>
More likely, you probably have a port blockage.
https://www.microsoft.com/en-us/download/details.aspx?id=24009
This is what I use to ping ports. If you can install this small utility on the sql-server machine, it'll go a long way.
On the outside chance you're running sql-server on linux...you can "apt install curl" (or similar) and ping the port that way.
But sending email from sql-server has always been tricky. You need the exact settings, and you need port (un)blocks. Most times its the port(s) issue.
If the portqueryui tool above reports "blocked" or "filtered"...you may have to open an port on your computer.
https://support.microsoft.com/en-us/help/4028544/windows-10-turn-windows-defender-firewall-on-or-off
Your router/network can also block ports. Again,the portqueryui tool is a quick way to test the path from the machine you're trying to get out to internet-land.

Problem with Hebrew charset in send_DbMail used in SSIS package

Using SQL2016 SSIS for single action: send email using send_DbMail procedure.
The SQL server installed in English with Hebrew localization.
The #subject & #body contain Hebrew, and the body is HTML formated. when executing an sql job with a code to send the email - it sent OK.
If I create SSIS package, test it on my PC - email sent OK.
If I upload the package from my PC to my SSIS server and run it in sql job - the email will be non readable (both subject & body).
Testing the all_mailitems query show the data is not recognized before exit to exchange.
Why there is a difference between 2 sql jobs types (direct code & SSIS package)? any idea how to configure the SSIS server to recognize Hebrew?
Sample code:
Declare #myHtml as nvarchar(max)
set #myHtml = N'<html><body><H1>בדיקה בדיקה</H1></body></html>'
exec msdb.dbo.sp_send_dbmail
#profile = 'MyProfile',
#recipients ='MyEmail',
#Subject = N'מייל בדיקה',
#body = #myHtml,
#body_format = 'html'
I can't reproduce any problems. After replacing #profile with #profile_name I was able to send the message to a GMail account and receive it without problem. The subject header was sent as UTF8 which some old email clients may not like.
What I received contained this :
Subject: מייל בדיקה
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: base64
PGh0bWw+PGJvZHk+PEgxPteR15PXmden15Qg15HXk9eZ16fXlDwvSDE+PC9ib2R5PjwvaHRtbD4=
Which was rendered correctly by GMail. The decoded Base64 string is identical to the original body.
Email headers like Subject had to use MIME encoding for non-ASCII text in the past. RFC6532 finally allowed UTF8

In msdb.dbo.sp_send_dbmail, #profile_name is not valid

I use a SQL Server job to execute SendEmail stored procedure. The job is working fine when the #recipients is our specified email address.
Since I couldn't log into our specified email address to check whether the email has been received, I want to change #recipients as my email address
The question is when I make this changed, the job history shows this job is not executed. The error is
Profile_name is not valid
Does anyone have any idea about this?
Here is the example.
EXEC msdb.dbo.sp_send_email
#profile_name = 'ISSS Group',
#recipients = 'isss#xxx.edu',
#body = #mess,--#mess is a table
#body_format = 'HTML',
#subject = 'Student Information Update',
#from_address = 'administration#xxx.edu';
I want to change #recipients = 'isss#xxx.edu' to #recipients = 'myemail#xxx.edu'to check whether the email has been received. But once I change it, the SQL Server job is failed. The error shows
Profile name is not valid.
You must pass the name of a registered profile; you can't make them up on-the-fly.
However, I assume you want a different display name, hence why you seem to be trying to change it by renaming the profile.
You would either need to create a new profile for the new name, or simply pass it in at runtime. The format for this is:
#from_address = 'Displayed Name <emailaddress#example.com>'
So, for example,
#from_address = 'ISSS Group <administration#xxx.edu>'
I use this method, and it might do everything you need here. Whether there is any benefit to setting up an entirely separate profile, I don't know; you would have to research that further.

when use sp_send_dbmail , got error : mail server failure , The requested name is valid, but no data of the requested type was found)

when i use this code try to send a email from sql server
exec msdb.dbo.sp_send_dbmail
#recipients='yang.liu#hotmail.com',
#body= 'abc',
#subject = 'new request',
#profile_name ='thisProfile'
sql server management show me : Mail queued.
but actually, this email is not been send , when i check log to see the reason :
SELECT TOP 100 [log_id]
,[event_type]
,[log_date]
,[description]
,[process_id]
,[mailitem_id]
,[account_id]
,[last_mod_date]
,[last_mod_user]
FROM [msdb].[dbo].[sysmail_event_log]
order by [log_id] desc
the log show me :
The mail could not be sent to the recipients because of the mail server failure. (Sending Mail using Account 1 (2014-07-10T10:34:17). Exception Message: Could not connect to mail server. (The requested name is valid, but no data of the requested type was found).
could anyone tell me what the reason , thanks

sp_send_dbmail executed from job fails with query result attached as file

I have faced with the following issue: when trying to send email with results of query attached as file, using sp_send_dbmail via executing ordinary query everything seems to be working OK.
But if add the same code into JobStep and run the job, it fails.
Error in job history says
Error formatting query, probably invalid parameters [SQLSTATE 42000] (Error 22050). The step failed.
But when I comment out parameter that refers to file attaching it starts working correctly again.
exec msdb.dbo.sp_send_dbmail
#profile_name = 'profile_name',
#recipients = 'some#mail.com',
#body = 'body',
#subject = 'subj',
--Parameters that refers to attached file
#attach_query_result_as_file = 1,
#query_result_header = 0,
#query_result_no_padding = 1,
#query = 'select 1',
#query_attachment_filename = 'test.csv'
Any suggestions?
I've come to workaround of that issue. Don't know why would it work but never the less. :)
It is definitely about security.
I've investigated that SQL Agent is running on behalf of domain user, say DOMAIN\User.
It has full set of admin rights on server ('sysadmin' server role, etc). SQL Server itself is running under that same user.
The step of job that contains call to sp_send_dbmail runs under the same DOMAIN\User.
Also I've traced that when running the query part of sp_send_dbmail it tries to execute
exec xp_logininfo 'DOMAIN\User' to check against Active Directory if that user is OK. And surprise: something is definitely not OK. This check ends up with:
Msg 15404, Level 16, State 19, Server SQLC002INS02\SQLC002INS02, Line 1
Could not obtain information about Windows NT group/user 'DOMAIN\User.', error code 0x2.
That, with some probability can mean anything about that user's password is expired or user is locked or any other non pleasant things for that guy.
I decided that its to risky to change user for Agent. So I come up to sending mail on behalf of 'sa' which has same 'sysadmin' server role but SQL authorization and omits this AD checking step.
It looks like one user that pretends to be admin to ask the real admin to run dangerous code for him :)
So final code of this job's the first and the only step resembles this:
execute as login = 'sa'
exec msdb.dbo.sp_send_dbmail
#profile_name = 'profile_name',
#recipients = 'some#mail.com',
#body = 'body',
#subject = 'subj',
--Parameters that refers to attached file
#attach_query_result_as_file = 1,
#query_result_header = 0,
#query_result_no_padding = 1,
#query = 'select 1',
#query_attachment_filename = 'test.csv'
revert
I had this problem. I am using SQL Server 2008 R2. I got the email sent with more info about the error by adding option:
#append_query_error = 1,
I got the email with this error about permissions instead of my query:
Msg 916, Level 14, State 1, Server SERVER\INST01,
Procedure GetSalesReport, Line 62
The server principal "CONTROLLEDNETWO\sql.service" is not able
to access the database "MYDB01" under the current security co
ntext.
My query was trying to access some tables where SQL Agent had no permissions (actually in my case it has not even access to it).
I fixed it through SQLSMS by adding a new user "CONTROLLEDNETWO\sql.service" to the db "MYDB01" and granting permissions to "select".
This was all helpful thank you. Wanted to share what I was trying to do with the excel(xls) attachment which was put the results in columns. This worked for me by adding the query_result_no_padding = 1, and query_result_separator= ' , '. ( that is a Tab,Tab in the ticks )
#query_result_header= 1,
#attach_query_result_as_file = 1,
#query_result_no_padding = 1,
#query_attachment_filename = 'TestPriceFlingerReport.xls',
#query_result_separator= ' , ',
#profile_name = 'Test Exchange Server'
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'Main Profile',
#recipients = 'me#vwp.com',
#subject = 'Test',
#body = 'this is a test',
#execute_query_database = 'myTargetDatabase_mscrm',
#query = N'SELECT * from myTargetDatabase_mscrm.dbo.SystemUserBase',
#attach_query_result_as_file = 1,
#query_attachment_filename = 'Test.txt'
For reference, this failed repeatedly showing as invoked as the domain administrator, but run as local\sqladmin. After flipping variables off an on and trying to give permissions, I saw in the script of the job that it was still using the master database. I found the setting staring me in the face. It's in the configuration for the Step. I changed it to msdb and it worked. Keep in mind that I changed the select from myTable to select from myDatabase.dbo.myTable based on some posts. That may or may not have contributed to fixing the problem. I also used #execute_query_database to make sure it's running the query from the right place. Again, that might not have been necessary.
No matter what finally made it happy, it had nothing to do with whether it was attaching or not.
in my situation, It could not identify the table belongs to with database. Once the database.dbo.table was added to the query it worked.
When you manually execute your query, YOUR credentials are used. When SQL Agent executes the same query, the SQL Agent service account's credentials are used. By default, SQL Server Agent will use the LocalSystem account credentials. One way to fix the problem would be to change the user under which the SQL Server Agent service is running with a user that has access to your csv directory\file.
I believe this problem was due to a change implemented in SQL 2008 and later regarding locking down security for just the sp_send_dbmail.
It only happens if you pass a qry to send_dbmail to execute, and return the results thru the email. The problem is the error message is misleading and not appropriate.
A good solution is to create a SQL user with just the minimum necessary permissions to perform that query. For example, db_reader, or db_writer, and db_owner if absolutely necessary. And make that user the owner. You can also create a SQL credential and configure that sql job to run under that SQL credential.
I had this problem too, and solved it in two parts using much of the advice here.
1) Right-click, 'View History' on the job showed failure details, and the failure notice gave the name of the user the job ran under, so I gave this user read-only access to my DB.
2) I had forgotten to specify DBName.dbo.MyTableName and was using MyTableName only.
Incidentally, the emails were all going to my junk email folder.

Resources