I have configured a database email, operators, and such on my SQL managed instance, to receive an email when a job fails.
In the email, we get something like this "The yyy_job failed on step 3".
But my question is... Is there a way to add the error message on the body of the email? I've been searching for this, but can't fine a suitable answer.
Thank you in advance
As far as I know there's no way to add further details to the email notifications when a job fails.
The only way is to implement your own notification process.
https://www.sqlshack.com/reporting-and-alerting-on-job-failure-in-sql-server/
We have a similar set up. We have a SQL Server Agent job that consists of several steps.
I configured it in such a way that we receive notification email when the job starts and another email when it finishes. There are two versions of the final email - one for success, another for failure.
At the end of the job there are two final steps called "Email OK" and "Email FAIL". Note how each of the steps have their "On Success" and "On Failure" configured.
This is how "Email OK" and "Email FAIL" steps look like in our case:
In my case I simply have different subjects of the emails, so it is easy to filter in the email client.
You can write any extra T-SQL code to execute a query against msdb.dbo.sysjobhistory and include the relevant result into the email.
I will not write a complete query here, but I imagine it would look similar to my sketch below. If you need help with that, ask another question.
This is how you can use msdb.dbo.sp_send_dbmail to include the result of some query into the email text:
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'ABC'
,#recipients = 'abc#example.com'
,#subject = 'Some subject line'
,#body = #VarBody
,#body_format = 'TEXT'
,#importance = 'NORMAL'
,#sensitivity = 'NORMAL'
,#query = N'
-- show latest entry in the log for your job
SELECT TOP(1)
message, ...
FROM
msdb.dbo.sysjobhistory
WHERE
job_id = ''your job ID''
ORDER BY
instance_id DESC;
'
,#execute_query_database = 'msdb'
;
Have a look at the documentation for a list of parameters for sp_send_dbmail. Example above inlines the query result. You can also attach it as a separate file.
Related
In my SQL, I already created profile & account.
I also know how to send the message though code :
USE msdb
GO
EXEC sp_send_dbmail #profile_name='yourprofilename',
#recipients='test#Example.com',
#subject='Test message',
#body='This is the body of the test message.
Congrates Database Mail Received By you Successfully.'
** Above is an example
However, I was wondering how can I insert an image into the message.
I'm trying to send email using the DatabaseMail on SQL Server 2008; I can see my emails sitting in the msdb.dbo.sysmail_unsentitems
But they just sit there and I get no error messages.
I've checked and I have rights to use the DatabaseMail by using the following:
EXEC msdb.sys.sp_helprolemember 'DatabaseMailUserRole';
And I tried running
EXEC msdb.dbo.sysmail_help_queue_sp #queue_type = 'mail';
which shows the length as the number of emails I've tried to send, but the Status is showing as Inactive.
Am I missing something else?
i wrote a procedure in which i tried to send mail using below command.
EXEC Sp_send_cdontsmail 'from','to','Test','TEST DATA'
After executing its showing "Command(s) completed successfully."
but i am not getting any mail.please help me on this.
You need to configure Database Mail and then use sp_send_dbmail to send mail. This is a supported procedure, part of the SQL Server.
PS. I am aware that out there some code sample circulates that advocates something along the lines of:
CREATE PROCEDURE [dbo].[sp_send_cdontsmail]
...
EXEC #hr = master..sp_OACreate 'CDONTS.NewMail', #MailID OUT
EXEC #hr = master..sp_OASetProperty #MailID, 'From',#From
EXEC #hr = master..sp_OASetProperty #MailID, 'Body', #Body
...
This is horrible code. As one can easily see there is absolutely 0 (zero, nada, zip) error checking in this code. Any failure will be reported as 'success'. COM interop will not raise T-SQL notification messages, is all in the HRESULT, which goes unchecked. Steer away from such code.
I'm having an issue where I'm preaty not sure how to resolve this and I want to know what is the best approach I should consider in order to achieve this task.
We are developping an application VB.net 2.0 and SQL 2005. Users are allowed to cancel a reception based on a purchase which may contains many received goods. But, during the process of cancellation, some questions are asked to users such as "Do you want to cancel Good #1". If yes, delete. Then, "Do you want to cancel Good #2", no, do not delete and one another question (if received item is issued, a process must be made manualy by the user). And, at the end, if all goods were successfully cancelled, we have to cancel the reception itself. But sometime, if an error occurs or some conditions occurs once asked to user in this process, we want to cancel any actions made from the beginning and make it back to his original state. So I thought about Transaction.
I know there is Transaction for SQL which can be used and I know good enough how to use it, but I can't realy use this as user must perform actions which possibly cancel this transaction.
I also remembered TransactionScope from .NET 2.X and over which can achieve something similar and I also know as well how to use it. The problem comes with TransactionScope and MSDTC. When using this, we still getting an error which said :
Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool.
I've tried what is describe here in another stack post and it works great... until user restard their computer. EVERY time users restart their computer, they must put value back. Plus, per default, no computer have this value set to On. At least on 10 computers bases, none were activated. There is something like 300 computers on which this program is installed so it's surely not the good things to consider neither.
So anyone have an idea of how I can acheive this? Is there anything else doing transaction via code which I can use?
NOTE1 : I know some would say, first ask conditions to user and maintain values in memory. Once done, if everything went well, go with delete. But what if an error occurs when deleting let's say, goods #4? And how can I give to a store procedure a dynamic list of goods to be deleted?
NOTE2 : Sorry for my english, I usualy talk french.
NOTE3 : Any exemple in C# can be provide also as I know both VB and C#.
Assuming you already have similar stored procedure to manage cancelation:
create proc CancelGood (#goodID int)
as
SET NOCOUNT ON
SET XACT_ABORT ON
begin transaction
update table1 set canceled = 1
where GoodID = #GoodID
update table2 set on_stock = on_stock + 1
where GoodID = #GoodID
commit transaction
VB code adds a string to some canceledGoods list if user selects 'Oui'. I'm not familiar with VB.Net; in c# it would look like:
canceledGoods.Add (string.Format("exec dbo.CancelGood {0}", goodID));
Than, if there is at least one string in canceledGoods, build and execute batch:
batch = "BEGIN TRANSACTION" +
" BEGIN TRY " +
string.Join (Environment.NewLine, canceledGoods.ToArray()) +
" END TRY" +
" BEGIN CATCH " +
" -- CODE TO CALL IF THERE WAS AN ERROR" +
" ROLLBACK TRANSACTION" +
" RETURN" +
" END CATCH" +
" -- CODE TO CALL AFTER SUCCESSFULL CANCELATION OF ALL GOODS" +
" COMMIT TRANSACTION"
conn.ExecuteNonQuery (batch);
Essentially I have a job which runs in BIDS and as as a stand lone package and while it runs under the SQL Server Agent it doesn't complete properly (no error messages though).
The job steps are:
1) Delete all rows from table;
2) Use For each loop to fill up table from Excel spreasheets;
3) Clean up table.
I've tried this MS page (steps 1 & 2), didn't see any need to start changing from Server side security.
Also SQLServerCentral.com for this page, no resolution.
How can I get error logging or a fix?
Note I've reposted this from Server Fault as it's one of those questions that's not pure admin or programming.
I have logged in as the proxy account I'm running this under, and the job runs stand alone but complains that the Excel tables are empty?
Here's how I managed tracking "returned state" from an SSIS package called via a SQL Agent job. If we're lucky, some of this may apply to your system.
Job calls a stored procedure
Procedure builds a DTEXEC call (with a dozen or more parameters)
Procedure calls xp_cmdshell, with the call as a parameter (#Command)
SSIS package runs
"local" SSIS variable is initialized to 1
If an error is raised, SSIS "flow" passes to a step that sets that local variable to 0
In a final step, use Expressions to set SSIS property "ForceExecutionResult" to that local variable (1 = Success, 0 = Failure)
Full form of the SSIS call stores the returned value like so:
EXECUTE #ReturnValue = master.dbo.xp_cmdshell #Command
...and then it gets messy, as you can get a host of values returned from SSIS . I logged actions and activity in a DB table while going through the SSIS steps and consult that to try to work things out (which is where #Description below comes from). Here's the relevant code and comments:
-- Evaluate the DTEXEC return code
SET #Message = case
when #ReturnValue = 1 and #Description <> 'SSIS Package' then 'SSIS Package execution was stopped or interrupted before it completed'
when #ReturnValue in (0,1) then '' -- Package success or failure is logged within the package
when #ReturnValue = 3 then 'DTEXEC exit code 3, package interrupted'
when #ReturnValue in (4,5,6) then 'DTEXEC exit code ' + cast(#Returnvalue as varchar(10)) + ', package could not be run'
else 'DTEXEC exit code ' + isnull(cast(#Returnvalue as varchar(10)), '<NULL>') + ' is an unknown and unanticipated value'
end
-- Oddball case: if cmd.exe process is killed, return value is 1, but process will continue anyway
-- and could finish 100% succesfully... and #ReturnValue will equal 1. If you can figure out how,
-- write a check for this in here.
That last references the "what if, while SSIS is running, some admin joker kills the CMD session (from, say, taskmanager) because the process is running too long" situation. We've never had it happen--that I know of--but they were uber-paranoid when I was writing this so I had to look into it...
Why not use logging built into SSIS? We send our logs toa database table and then parse them out to another table in amore user friendly format and can see every step of everypackage that was run. And every error.
I did fix this eventually, thanks for the suggestions.
Basically I logged into Windows with the proxy user account I was running and started to see errors like:
"The For each file enumerator is empty"
I copied the project files across and started testing, it turned out that I'd still left a file path (N:/) in the properties of the For Each loop box, although I'd changed the connection properties. Easier once you've got error conditions to work with. I also had to recreate the variable mapping.
No wonder people just recreate the whole package.
Now fixed and working!