I have the following structure:
cho_id int
cho_nombre varchar(200)
cho_documento varchar(15)
cho_dirrecion varchar(100)
cho_telefono varchar(15)
cho_fec_vencimiento_lic datetime
cho_categoria int
est_id int
I have a row of datetime type and I want that every time the date approaches send me an alert 15 days before and send me by email.
How can I design this in SQL Server? Does it have to be with stored procedures? Triggers?
Here's a quick shell you can use for a procedure, which you'll then schedule as a job to run daily. You can change the logic of the IF as you seem fit.
create procedure myProc
as
if (select datediff(day,max(cho_fec_vencimiento_lic),getdate()) from SomeTable) = 15
begin
exec msdb.dbo.sp_send_dbmail
#profile_name = null,
#recipients = 'email#domain.org',
#body = 'This is your email alert',
#body_format = 'TEXT',
#subject = 'Alert'
end
go
sp_dend_dbmail reference
Schedule a job reference
Related
Using SQL-Server 2019; I am trying to use sp_send_dbmail and have successfully sent test emails from SQL-Server so believe the configuration is fine.
A sproc runs in the execution context of a SQL-Login, which updates some tables in a database and then calls the sproc below which is supposed to send emails via msdb.dbo.sp_send_dbmail.
CREATE PROCEDURE [dbo].[sp_SendEmail]
#emailAddress AS NVARCHAR(MAX),
#emailBody AS NVARCHAR(MAX),
#emailSubject AS NVARCHAR(150),
#attachmentPath AS NVARCHAR(255) = NULL,
#emailId AS INT OUTPUT
WITH EXECUTE AS N'Bob'
AS
BEGIN
SET NOCOUNT ON;
DECLARE #bSuccess AS INT = 0;
EXECUTE #bSuccess = [msdb].[dbo].[sp_send_dbmail]
#profile_name = N'Profile',
#recipients = #emailAddress,
#subject = #emailSubject,
#body = #emailBody,
#body_format = N'HTML',
#importance = N'High',
#file_attachments = #attachmentPath,
#mailitem_id = #emailId OUTPUT;
RETURN #bSuccess;
END
GO
When I run the sproc I get the error:
Msg 229, Level 14, State 5, Procedure msdb.dbo.sp_send_dbmail, Line 1
[Batch Start Line 2] The EXECUTE permission was denied on the object
'sp_send_dbmail', database 'msdb', schema 'dbo'.
The SQL-Login, Bob, has a user mapping to the msdb database using the default schema and is a member of the DatabaseMailUserRole role.
I've given Bob execute permission on the sp_send_dbmail securable, which seems like a duplication of what the DatabaseMailUserRole provides, but still get the error above.
I'd appreciate any insight you can throw at me.
This question already has an answer here:
Send e-mail from a trigger
(1 answer)
Closed 1 year ago.
I'm trying to use an INSERT TRIGGER in an SQL Server db. It's my first trigger an I want to use it to send an email if certain value has been met in that inserted row:
CREATE TRIGGER dbo.SEND_MAIL
ON dbo.table
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON
IF (SELECT field1 FROM INSERTED) = '1'
BEGIN
EXEC msdb.dbo.sp_send_dbmail
#recipients = 'mail address',
#profile_name = 'profile1',
#subject = 'subject',
#body = 'body text';
END
END
If I try to execute the send_dbmail stored procedure with those email parameters, the email is sent perfectly. But not in the trigger.
I see that values that comply the condition in the IF statement (field1 = '1') are being inserted in the table. But can't figure out why is not working in the trigger.
I tried to use 'LIKE '1'' instead of equal in the IF but no luck.
Any hint to make it work?
Thank you so much in advance,
You can have many records in the inserted-table, so I would suggest you to write it like:
IF exists (SELECT field1 FROM INSERTED where field1='1')
BEGIN
EXEC msdb.dbo.sp_send_dbmail
#recipients = 'mail address',
#profile_name = 'profile1',
#subject = 'subject',
#body = 'body text';
END
I have a T-SQL stored procedure (which returns a single scalar value called #HourDifference as an output parameter); you can see the execution below:
DECLARE #HourDifference_output TINYINT;
-- I declare a variable to capture the output parameter--
EXEC dbo.sproc_XYZ_Notification
#HourDifference = #HourDifference_output OUTPUT;
SELECT #HourDifference_output AS HourDifferenceCaptured
I have the below requirements:
If HourDifferenceCaptured > 12, I will need to send a email
If HourDifferenceCaptured <= 12, no email needs to be sent; nothing needs to be done.
I need to have two schedules, one at 7 AM, the other at 7 PM in the SQL Server Agent.
Can someone provide the code and guide me through this process?
You could create an SQL Server agent job, with a t-sql step which uses msdb.dbo.sp_send_dbmail for sending an e-mail, when required (please see here, for the stored procedure complete reference).
Try something similar to the following:
DECLARE #HourDifference_output TINYINT;
EXEC dbo.sproc_XYZ_Notification #HourDifference_output OUTPUT;
-- SELECT #HourDifference_output AS HourDifferenceCaptured
IF #HourDifference_output > 12
BEGIN
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'db_mail_profile_i_have_already_created',
#recipients = 'intended-recipients#yourorganization.com',
#body = 'Too many hours difference.',
#subject = 'Automated Message' ;
END
You must have already configured a database mail account, a database mail profile and granted appropriate access to the user running the job step. The second link also contains sample scripts for creating a database mail account and profile, adding the account to the profile and granting access appropriately (I personally prefer to configure database mail via the SSMS db mail wizard).
A decision to be made is whether to create a public or a private profile. You can find more information about the differences here.
Finally, it is, in my opinion, good practice to notify an administrator (via SQL Server Agent build-in mechanisms) when a job / step fails.
USE <database_name>
GO
DECLARE #subject NVARCHAR(max) = 'Email subject'
, #body NVARCHAR(MAX)
DECLARE #HourDifference_output TINYINT;
EXEC dbo.sproc_XYZ_Notification #HourDifference = #HourDifference_output OUTPUT;
SELECT #HourDifference_output AS HourDifferenceCaptured
IF (#HourDifference_output> 12)
BEGIN
SET #body = '<!DOCTYPE html>
<html>
<body>
<body style="color:black; font-family:Times New Roman; font-size:14x"> .......... body text ......... </body>
<body style="color:SlateGray; font-family:Times New Roman; font-size:14px;line-height: 1;"> ------------------------------------------------------------------' + '
<body style="color:SlateGray; font-family:Times New Roman; font-size:14px;line-height: 1;"> ------------------------------------------------------------------' + '
</body>
</HTML>'
EXEC msdb.dbo.sp_send_dbmail #profile_name = 'Profile name'
, #recipients = 'distibution email'
, #body = #body
, #body_format = 'HTML'
, #subject = #subject
END
GO
i have a table in SQl server which occasionally gets data from a linked server, and than i have to do activities on it .
but the problem is there is no way to check if the data is inserted in table (table is always truncated after performing the activity so next time when data is pushed table is already empty) i manually check daily for data if it is inserted or not .
what i want is to get auto alert on my email (i already have db_mail configured and working) whenever the data is pushed in a table .
i have sa admin and complete privileges on Database and also on Windows server 2012 R2
You can do this with a trigger but you will have to do some preparations with privileges so the executor (the login that's inserting the records on your tracking table) can send email correctly:
CREATE TRIGGER dbo.TrackingTableNameAfterInsert ON TrackingTable
AFTER INSERT
AS
BEGIN
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'YourConfiguredProfile',
#recipients = 'youremail#mail.com',
#subject = 'Records were inserted on TrackingTable',
#body = ''
END
You might want to encapsulate the email sending on an SP and configure it's permissions there.
In regards to the following:
...table is always truncated after performing the activity so next time
when data is pushed table is already empty...
You can create a historical table and use a trigger to also insert inserted records on this table, so the TRUNCATE or DROP of the original one won't affect the copied records.
CREATE TABLE TrackingTableMirror (
/*Same columns and types*/
InsertedDate DATETIME DEFAULT GETDATE())
GO
CREATE TRIGGER dbo.TrackingTableInsertMirror ON TrackingTable
AFTER INSERT
AS
BEGIN
INSERT INTO TrackingTableMirror (
/*Column list*/)
SELECT
/*Column list*/
FROM
inserted AS I
END
This way you can check all records on this mirrored table and not the volatile one (and avoid all the email sending).
1) Create Profile and Account
You need to create a profile and account using the Configure Database Mail Wizard which can be accessed from the Configure Database Mail context menu of the Database Mail node in Management Node. This wizard is used to manage accounts, profiles, and Database Mail global settings.
2) Run Query
sp_CONFIGURE 'show advanced', 1
GO
RECONFIGURE
GO
sp_CONFIGURE 'Database Mail XPs', 1
GO
RECONFIGURE
GO
3)
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.'
through the table
DECLARE #email_id NVARCHAR(450), #id BIGINT, #max_id BIGINT, #query NVARCHAR(1000)
SELECT #id=MIN(id), #max_id=MAX(id) FROM [email_adresses]
WHILE #id<=#max_id
BEGIN
SELECT #email_id=email_id
FROM [email_adresses]
set #query='sp_send_dbmail #profile_name=''yourprofilename'',
#recipients='''+#email_id+''',
#subject=''Test message'',
#body=''This is the body of the test message.
Congrates Database Mail Received By you Successfully.'''
EXEC #query
SELECT #id=MIN(id) FROM [email_adresses] where id>#id
END
4) Trigger Code
CREATE TRIGGER [dbo].[Customer_INSERT_Notification]
ON [dbo].[Customers]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #CustomerId INT
SELECT #CustomerId = INSERTED.CustomerId
FROM INSERTED
declare #body varchar(500) = 'Customer with ID: ' + CAST(#CustomerId AS VARCHAR(5)) + ' inserted.'
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'Email_Profile'
,#recipients = 'recipient#gmail.com'
,#subject = 'New Customer Record'
,#body = #body
,#importance ='HIGH'
END
I refer this link.
I'm using the sp_send_dbmail stored procedure, and I'm trying to include the result from a query in the body string. I can't seem to get this to work. Any ideas would be much appreciated.
use msdb
go
exec sp_send_dbmail
#profile_name = 'WarehouseEmailer',
#recipients = 'someone#example.com',
#subject = 'Database Mail Test 1',
#Body = 'This is a test email from SQL Server. <br> This should be line 2. <br> The
subject\'s first name is: '+ (select top(1) FirstName from Warehouse.dbo.Subject),
#body_format = 'HTML'
Obviously this example just a simple test, but it is exactly the type of data I'd like to pass to the stored procedure to include in the email body. I look forward to your responses and many thanks for any advice!
Dynamic SQL, or concatenated strings, cannot be passed into the procedures parameters like that.
Try this:
use msdb
go
declare #msgbody nvarchar(1000)
set #msgbody = 'This is a test email from SQL Server.' + char(10) + 'This should be line 2. <br> The
subject''s first name is: '+ (select top(1) FirstName from Warehouse.dbo.Subject)
exec sp_send_dbmail
#profile_name = 'WarehouseEmailer',
#recipients = 'someone#example.com',
#subject = 'Database Mail Test 1',
#Body = #msgbody,
#body_format = 'HTML'