difference xp_sendmail and sp_send_dbmail proc - sql-server

Can I ask what is the difference between xp_sendmail and sp_send_dbmail proc? They are both send e-mail message, which may include a query result set attachment, to the specified recipients.....
What is the difference?

xp_sendmail requires a MAPI client installed, such as Outlook, on the server. This is the only option for SQL Server 2000 and before.
sp_send_dbmail is a simple SMTP solution, added for SQL Server 2005+
sp_send_dbmail is by far better.

Another difference between the two is that email message sent using sp_send_dbmail() will be rolled back (not sent) if the transaction is rolled back. This does not happen with email sent using xp_sendmail().
So, if you want the email message to be sent regardless of the end result of the transaction you'll need to use xp_sendmail().
I was sending emails to notify users if an SP was unable to complete it's processing. Of course, I was rolling back the transaction in that event. When I switched to sp_send_dbmail() the transactions that were being rolled back (the very ones I wanted to get an email notification from) stopped sending emails.

we don't control the calling code - it's closed and calls the sp in a transaction. We need a feature in SQL Server to send direct or flush the mail queue.

Related

SQL Server with Service Broker

When I do something such as insert, update in SQL Server, and I have a Service Broker queue. I just know do SEND to send the message to the queue.
Q: can the message send to queue automatically? Thanks.
No, there is no built-in way of sending messages in response to changes to a table. You would have to wire this up yourself using triggers or forcing all your table changes to go via stored procedures.

Sending mail through DB or through service call from a CLR

I've a scenario where I've to send a mail after checking a condition after every insert in a table.
Is trigger the right way to do it?
My second question would be as to what approach to take
Should I directly send a mail from the DB. (Note: My DBserver and Mail server are in different networks, might've to create firewall rule exception)
Should I have a CLR-sproc. From the DB, I call the CLR-sproc and CLR-sproc calls a service and from there sends the mail.
Is there a better approach?
Both SQL Server DBMail and a CLR proc will use SMTP to send the email. So, why add complexity?
In addition, sending an email via DBMail or CLR will require processing on INSERT. Note that DBMail uses a queue so will impact less than running a CLR procedure.
A trigger is a good way to do it. However, consider using a stored procedure to do the ISNERT with the email sent outside of the transaction (you'll have an implicit one because of the INSERT). Sending in a trigger means it is part of the implicit transaction for the INSERT.
From a security perspective, SQLMachine still needs access to SMTPMachine, whether using DBMail or a service call by a CLR Proc.
1) Yes, a trigger would be the right way of performing an action after every insert
2) SQL server has a feature called Database Mail which looks like it will do what you want (although I've never used it myself)

SQL Server Agent Job Completion E-mail Notification

I've created a Database Mail account (tested and sends with no problem), created an operator, set up an alert on the job I want to monitor, and restarted my SQL Server Agent. But I still am not alerted when the job in question completes. Is there a step that is missing?
Look at your Database Mail log and make sure you don't have any errors sending there. Make sure your internal relay mail servers allow sending from the SQL server's IP address. Also run EXEC msdb.dbo.sysmail_help_status_sp and make sure the dbmail queue status is "Started" or "Receives_Occuring". If the queue is in a Stopped status, restart it with EXEC msdb.dbo.sysmail_stop_sp and EXEC msdb.dbo.sysmail_start_sp
Open the job, go to notifications and select Email, choose the operator you created, and the condition "When the job fails". That should do it.
Was able to get notifications to start sending after a server restart

Sending and Receiving SQL Server Service Broker Messages within Nested Transactions

I'd like to use SQL Server 2008 Service Broker to log the progress of a long-running (up to about 30 minutes) transaction that is dynamically created by a stored procedure. I have two goals:
1) To get real-time logging of the dynamically-created statements that make up the transaction so that the progress of the transaction can be monitored remotely,
2) To be able to review the steps that made up the transaction up to a point where a failure may have occurred requiring a rollback.
I cannot simply PRINT (or RAISERROR(msg,0,0)) to the console because I want to log the progress messages to a table (and have that log remain even if the stored procedure rollsback).
But my understanding is that messages cannot be received from the queue until the sending thread commits (the outer transaction). Is this true? If so, what options do I have?
It is true that you cannot read messages from the service queue until the transaction is committed.
You could try some other methods:
use a sql clr procedure to send a .net remoting message to a .net app that receives the messages and them log them.
use a sql clr procedure to write a text or other log file to disk.
Some other method...
Regards
AJ

Send message from SQL Server trigger

I need to signal a running application (Windows service) when certain things happen in SQL Server (2005). Is there a possibility to send a message from a trigger to an external application on the same system?
You can use a SQL Service Broker queue to do what you want.
The trigger can create a conversation and send a message on the queue.
When it starts, the external process should connect to the database and issue a WAITFOR (RECEIVE) statement on this queue. It will receive the message when the trigger sends it.
Not sure DBA's would approve of this, but there is a way to run commands using xp_cmdshell
"Executes a given command string as an operating-system command shell and returns any output as rows of text. Grants nonadministrative users permissions to execute xp_cmdshell."
Example from MS's site:
CREATE PROC shutdown10
AS
EXEC xp_cmdshell 'net send /domain:SQL_USERS ''SQL Server shutting down
in 10 minutes. No more connections allowed.', no_output
EXEC xp_cmdshell 'net pause sqlserver'
WAITFOR DELAY '00:05:00'
EXEC xp_cmdshell 'net send /domain: SQL_USERS ''SQL Server shutting down
in 5 minutes.', no_output
WAITFOR DELAY '00:04:00'
EXEC xp_cmdshell 'net send /domain:SQL_USERS ''SQL Server shutting down
in 1 minute. Log off now.', no_output
WAITFOR DELAY '00:01:00'
EXEC xp_cmdshell 'net stop sqlserver', no_output
Either:
Use RAISERROR (severity 10) to fire a SQL agent alert and job.
Load a separate table that is polled periodically by a separate mail handling process. (as HLGEM suggested)
Use a stored procedure to send the message and write to the table.
Each solution decouples the transactional trigger from a potentially long messaging call.
You can send an email from a trigger, but it isn't a recommended practice becasue if the email ssystem is down, no data changes can be made to the table.
Personally if you can live with less than realtime, I would information about the event you are interested in to another table (so the real change of data can go smoothly even if email is down for some reason.) Then I would have a job that checks that table every 5-10 minutes for any new entries and emails those out.
You can use a dbmail email message. It should not slow the trigger down if the mail server is down because the message is queued and then sent by and external (to sql) process.
The table idea sounds good if the application can access sql server.
You could also give access to that same table via sql 2005 native XML Services - which exposes procs through xml.
http://msdn.microsoft.com/en-us/library/ms345123(SQL.90).aspx
Depending on what sort of message you want to send, you could use a CLR stored procedure to connect to a socket on the running process and write the message to that. If you have no control over the process (i.e. can't modify it) you could build a bridge or use a library that can issue a message in a suitable format.
For reliable delivery, you could do something that uses MSMQ to deliver the message.
A reminder that triggers can be problematic for stuff like this because they are embedded in set-operations. And being associated with tables, they aren't very sensitive to the context in which they are fired. The problem can be if they fire on an operation that involves multiple rows, because it's hard to avoid invoking as many instances of your action as there are records in the operation. Several hundred emails are not unlikely, for instance.
Hopefully "things that happen" can be detected in closer association with the context in which they happen (which also can be interesting to try to backtrack from a trigger.)

Resources