I believe that dbMail is properly set up, I can send an email to myself using it.
But I have a scheduleded job which looks like;
DECLARE #Forename VARCHAR(50)
DECLARE #EmailAddress VARCHAR(50)
DECLARE #subject VARCHAR(500)
DECLARE #emailsubject VARCHAR(500)
Declare #bodypre as varchar(5000)
DECLARE #body VARCHAR(5000)
declare #recipients VARCHAR(5000)
Declare #emailStop as int
declare #replaceApproverName as varchar(20)
declare #link as varchar(100)
declare #replaceNextLine as varchar(20)
declare #profile_name as varchar(50)
declare #bodypost as varchar(5000)
declare #footerMessage as varchar(1000)
set #replaceApproverName ='$Approver'
set #replaceNextLine ='$NextLine'
set #link ='$Link'
DECLARE #NewLineChar AS CHAR(1) = CHAR(13)
select #emailsubject=EmailMessageSubject,
#bodypre = EmailMessageBody,
#emailStop = EmailStop_Flag
from STAS.dbo.MC_STAS_EmailMessage where TimeSheetStatusID = 2
SET #bodypre =Replace(#bodypre ,#link, 'http://liveweb.website.com/stas');
select #footerMessage =EmailMessageBody from STAS.dbo.MC_STAS_EmailMessage where MessageType='Footer'
SET #bodypre += #footerMessage;
SET #bodypre =Replace(#bodypre ,#replaceNextLine, #NewLineChar) ;
DECLARE emailCursor CURSOR FOR
SELECT distinct EmailAddress,Forename from [STAS].[dbo].[NotifictationEmailID_View] vw
OPEN emailCursor FETCH NEXT FROM
emailCursor INTO #EmailAddress,#Forename WHILE ##FETCH_STATUS = 0
BEGIN
if(#emailStop = 1)
set #EmailAddress = 'xxx.xxxx#xxxxx.co.uk'
set #bodypost = Replace(#bodypre,#replaceApproverName,#Forename)
EXEC msdb.dbo.sp_send_dbmail
#profile_name='STAS Alert',
#recipients =#EmailAddress,
#subject=#emailsubject,
#body =#bodypost;
FETCH NEXT FROM emailCursor INTO #EmailAddress,#Forename END
CLOSE emailCursor
DEALLOCATE emailCursor
When I look at the Database mail error log I see this;
The mail could not be sent to the recipients because of the mail server failure. (Sending Mail using Account 1 (2013-09-04T14:03:48). Exception Message: Cannot send mails to mail server. (The operation has timed out.).
Sending Mail using Account 1 . Exception Message: Cannot send mails to mail server. (Failure sending mail.).
Yet the profile 'STAS Alert' is set up and I can send an email using it to myself.
So why is this happening and what should I do to fix it?
Did you check out SQL Server Agent Properties/alert system ?
Mail profile should be enabled and your mail profile should be chosen correctly.
Related
I create Logins for a lot of people. They work mostly but a few now and then behave like this:
Logins are authenticated through SQL Server Authentication. The person gets this message:
When I look at the Login I see this:
So it tells me they are not locked out. I have to edit their pw and the login starts working again. I don't even have to change the PW, I just re-enter the current one. Am I missing something?
Here is the script that creates the Login:
ALTER PROCEDURE [dbo].[spCreateLogins]
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
declare #newdb sysname
DECLARE #studentID AS varchar(20)
begin try
close student_cursor
DEALLOCATE student_cursor
end try
begin catch
end catch
DECLARE student_cursor CURSOR FOR SELECT UserName FROM tStudent where studentid>35
DECLARE #SQL NVARCHAR(4000)
OPEN student_cursor
FETCH NEXT FROM student_cursor
INTO #studentID
WHILE ##FETCH_STATUS = 0
BEGIN
-- Create the user name
SET #SQL = 'CREATE LOGIN ' + ltrim(rtrim(#StudentID)) + ' WITH PASSWORD = ''P#ssword1'', DEFAULT_DATABASE=' + ltrim(rtrim(#StudentID)) + ', CHECK_EXPIRATION=OFF, CHECK_POLICY=ON';
print #SQL
EXECUTE(#SQL);
FETCH NEXT FROM student_cursor
INTO #studentID
END
END
I looked in Security Settings-->Account Policies-->AccountLockout policy in secpol.msc as suggested by #SEarle1986. I had no idea a lockout could be temporary. :)
The trigger I am using is not firing, any ideas/help is appreciated. I checked the sysmail_allitems and its empty. To give some more explanation, I have a program where we submit travel requests through a form, when you submit a form a new row is created in TS_CUSTOM_TRVLBCK, everytime this happens I want an email to be sent with the conditions below. I have submitted a new form form (added image), the row is there but the trigger didnt fire.
My goal is to receive an email when one of the users in the where statement submits a request (a new row is created)
CREATE TRIGGER [dbo].[TS_TRAVEL_NEW_IIS]
ON [dbo].[TS_CUSTOM_TRVLBCK]
FOR INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #user Varchar(100)
DECLARE #subject Varchar(100)
DECLARE #body Varchar (200)
SELECT #user + RTRIM(TRVL_INITIATOR) FROM inserted;
SET #subject = 'New Travel Request - ' + #user
SET #body = 'Kindky note that user ' + #user + ' has submitted a new travel request.'
IF EXISTS (SELECT 1 FROM inserted WHERE [TRVL_INITIATOR] IN ('Luke Gatt','Marcelle Attard','Matthew Borg Dingli','Mark Schembri','Fiona Tesi','Charmaine Buttigieg','Stephen Mifsud','Tessabelle Cammilleri'))
BEGIN
EXEC msdb.dbo.sp_send_dbmail
#recipients = 'luke.gatt#mca.org.mt',
#profile_name = 'AbsenceMailer',
#subject = #subject,
#body = #body;
END
END
GO
There are servers A and B with the SQL Server instances. There are created services with a route through TRANSPORT. Messages are successfully received. I'm trying to create an internal activation on B, but the queue stops. What am I doing wrong? Fixed. For each message sent from A to B is returned 5 copies.
SERVER A
USE master
GO
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'PAROLPAROL123'
CREATE CERTIFICATE [GA_SERVER]
WITH SUBJECT = 'GA_SERVER';
GO
CREATE ENDPOINT BROKER
STATE=STARTED
AS TCP (LISTENER_PORT = 4022)
FOR SERVICE_BROKER
(
AUTHENTICATION = CERTIFICATE [GA_SERVER]
);
GRANT CONNECT ON ENDPOINT::BROKER TO [PUBLIC];
GO
CREATE DATABASE DB_A
GO
ALTER DATABASE DB_A
SET ENABLE_BROKER
WITH ROLLBACK IMMEDIATE;
GO
USE DB_A;
CREATE MESSAGE TYPE RequestMT
validation=NONE;
CREATE MESSAGE TYPE ResponseMT
validation=NONE;
CREATE CONTRACT GAContract
(
RequestMT
SENT BY INITIATOR,
ResponseMT
SENT BY TARGET
);
CREATE QUEUE GAQueue
WITH status = ON;
CREATE SERVICE [tcp://10.10.100.56:4022/GAservice]
ON QUEUE GAQueue (GAContract)
GO
GRANT SEND ON SERVICE::[tcp://10.10.100.56:4022/GAservice] TO [PUBLIC]
CREATE ROUTE transport WITH ADDRESS = 'TRANSPORT';
GO
CREATE TABLE [dbo.t1](
[mes] [nvarchar](max) NULL
) ON [PRIMARY];
GO
CREATE PROCEDURE ActivProcA
AS
BEGIN
SET NOCOUNT ON
DECLARE #RecvReqDlgHandle UNIQUEIDENTIFIER;
DECLARE #RecvReqMsg NVARCHAR(1000);
DECLARE #RecvReqMsgName sysname;
BEGIN TRANSACTION;
WHILE (1=1)
BEGIN
WAITFOR
( RECEIVE TOP(1)
#RecvReqDlgHandle = conversation_handle,
#RecvReqMsg = message_body,
#RecvReqMsgName = message_type_name
FROM GAQueue
), TIMEOUT 5000;
IF (##ROWCOUNT = 0)
BEGIN
ROLLBACK TRANSACTION;
-- END CONVERSATION #RecvReqDlgHandle;
BREAK;
END
IF #RecvReqMsgName =
N'ResponseMT'
BEGIN
INSERT INTO [dbo.t1] (mes) VALUES (N'back to A from B ('+ CAST(CURRENT_TIMESTAMP AS NVARCHAR)+N'):'+#RecvReqMsg);
END
ELSE
END CONVERSATION #RecvReqDlgHandle;
COMMIT TRANSACTION;
SET NOCOUNT OFF;
END;
END;
GO
ALTER QUEUE GAQueue
WITH
STATUS = ON,
ACTIVATION
( STATUS = ON,
PROCEDURE_NAME = ActivProcA,
MAX_QUEUE_READERS = 10,
EXECUTE AS SELF
);
GO
SERVER B
USE MASTER
GO
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'PAROLPAROL123'
CREATE CERTIFICATE [GOS_SERVER]
WITH SUBJECT = 'GOS_SERVER';
GO
CREATE ENDPOINT BROKER
STATE=STARTED
AS TCP (LISTENER_PORT = 4022)
FOR SERVICE_BROKER
(
AUTHENTICATION = CERTIFICATE [GOS_SERVER],
);
GRANT CONNECT ON ENDPOINT::BROKER TO [PUBLIC];
GO
CREATE DATABASE DB_B_1
GO
ALTER DATABASE DB_B_1
SET ENABLE_BROKER
WITH ROLLBACK IMMEDIATE;
GO
USE DB_B_1;
CREATE MESSAGE TYPE RequestMT
validation=NONE;
CREATE MESSAGE TYPE ResponseMT
validation=NONE;
CREATE CONTRACT GAContract
(
RequestMT
SENT BY INITIATOR,
ResponseMT
SENT BY TARGET
);
CREATE QUEUE GAQueue
WITH status = OFF;
GO
CREATE SERVICE [tcp://10.10.100.78:4022/GOS_DB_B_1_service]
ON QUEUE GAQueue (GAContract)
GO
GRANT SEND ON SERVICE::[tcp://10.10.100.78:4022/GOS_DB_B_1_service] TO [PUBLIC]
CREATE ROUTE transport WITH ADDRESS = 'TRANSPORT';
GO
CREATE TABLE [dbo.t1](
[mes] [nvarchar](max) NULL
) ON [PRIMARY];
GO
CREATE PROCEDURE ActivProcB
AS
BEGIN
SET NOCOUNT ON;
DECLARE #RecvReqDlgHandle UNIQUEIDENTIFIER;
DECLARE #RecvReqMsg NVARCHAR(100);
DECLARE #RecvReqMsgName sysname;
WHILE (1=1)
BEGIN
BEGIN TRANSACTION;
WAITFOR
( RECEIVE TOP(1)
#RecvReqDlgHandle = conversation_handle,
#RecvReqMsg = message_body,
#RecvReqMsgName = message_type_name
FROM GAQueue
), TIMEOUT 5000;
IF (##ROWCOUNT = 0)
BEGIN
ROLLBACK TRANSACTION;
BREAK;
END
IF #RecvReqMsgName =
N'RequestMT'
BEGIN
INSERT INTO [dbo.t1] (mes) VALUES (N'('+ CAST(CURRENT_TIMESTAMP AS NVARCHAR)+N'):'+#RecvReqMsg);
DECLARE #Msg NVARCHAR(100);
DECLARE #I INT;
SET #I = 1;
WHILE #I<6
BEGIN
SET #Msg = N'<MsgFromB1>'+CAST (#I AS NVARCHAR(1))+N' ('+CAST(CURRENT_TIMESTAMP AS NVARCHAR)+N')</MsgFromB1>';
SEND ON CONVERSATION #RecvReqDlgHandle
MESSAGE TYPE
ResponseMT
(#Msg);
SET #I = #I+1;
END
END;
COMMIT TRANSACTION;
END
SET NOCOUNT OFF;
END;
GO
ALTER QUEUE GAQueue
WITH
STATUS = ON,
ACTIVATION
( STATUS = ON,
PROCEDURE_NAME = ActivProcB,
MAX_QUEUE_READERS = 10,
EXECUTE AS SELF
);
GO
SERVER A
USE DB_A
DECLARE #ConversationHandle UNIQUEIDENTIFIER;
DECLARE #RequestMsg NVARCHAR(4000);
BEGIN TRANSACTION
BEGIN DIALOG #ConversationHandle
FROM SERVICE [tcp://10.10.100.56:4022/GAservice]
TO SERVICE 'tcp://10.10.100.78:4022/GOS_DB_B_1_service'
ON CONTRACT GAContract
WITH ENCRYPTION = OFF;
SELECT #RequestMsg =
N'<RequestMsg>test1</RequestMsg>';
SEND
ON CONVERSATION #ConversationHandle
MESSAGE TYPE RequestMT
(#RequestMsg);
COMMIT TRANSACTION;
GO
I'm trying to create an internal activation on B, but the queue stops
That's most likely poison message detection kicking in. It means your activated procedure is raising an exception and cause a rollback. When this happens the output of the procedure (including error messages) is logged into the ERRORLOG. That's where you need to look.
You can also attempt to troubleshoot the procedure by disabling activation and invoking the procedure manually from a query window. This way you'll see directly any error messages/exceptions. To execute under the same context as the activated procedure, issue an EXECUTE AS USER = 'dbo' before invoking the procedure.
See Troubleshooting Activation Stored Procedures.
I am using SQL broker to do some asynchronous tasks(In my case sending mails). But the problem I am having is the stored procedure which is run when the the value is inserted to the queue runs twice every time the XML message is passed from a Trigger to the queue.
I have a message type:
CREATE MESSAGE TYPE MailMessage
AUTHORIZATION dbo
VALIDATION = WELL_FORMED_XML
I have a contract:
CREATE CONTRACT MailContract
AUTHORIZATION dbo
(MailMessage SENT BY INITIATOR)
I have a Queue:
CREATE QUEUE dbo.MessageQueue
WITH STATUS=ON,
ACTIVATION (
PROCEDURE_NAME = MailExecuter ,
MAX_QUEUE_READERS = 1,
EXECUTE AS OWNER );
I have two services:
CREATE SERVICE MailSendActivator
AUTHORIZATION dbo
ON QUEUE dbo.MessageQueue (MailContract) ; // I have removed this the contract to make it a initiator but it did not worked out
-- Create target Service
CREATE SERVICE MailSendExec
AUTHORIZATION dbo
ON QUEUE dbo.MessageQueue (MailContract);
Here is my trigger:
CREATE TRIGGER MailSendTrigOnMailQueue ON dbo.MailQueue
FOR INSERT
As
SET NOCOUNT ON;
DECLARE #MessageBody XML
DECLARE #TableId int
SET #MessageBody = (SELECT CreatedDateTime,[Subject], MailType FROM inserted
FOR XML AUTO)
If (#MessageBody IS NOT NULL)
BEGIN
DECLARE #Handle UNIQUEIDENTIFIER;
BEGIN DIALOG CONVERSATION #Handle
FROM SERVICE MailSendActivator
TO SERVICE 'MailSendExec'
ON CONTRACT MailContract
WITH ENCRYPTION = OFF;
SEND ON CONVERSATION #Handle MESSAGE TYPE MailMessage(#MessageBody);
END
I have a stored procedure:
In the stored procedure I am Inserting values to a test table whether the stored procedure is running.
Stored Procedure:
CREATE PROCEDURE dbo.MailExecuter
AS
BEGIN
DECLARE #msgBody XML
DECLARE #dlgId uniqueidentifier
Insert into TestTable(Name, Test) values('MEX','test');
WHILE (1 = 1)
BEGIN
WAITFOR ( RECEIVE TOP(1) #msgBody = CAST(message_body AS XML), #dlgId = conversation_handle FROM dbo.MessageQueue ), TIMEOUT 500
IF (##ROWCOUNT = 0 OR #msgBody IS NULL)
BEGIN
BREAK
END
ELSE
BEGIN
DECLARE #Subject nvarchar(200), #CreatedDateTime datetime, #MailType nvarchar(50)
---EXEC dbo.SendMails 1,1;
END
END CONVERSATION #dlgId
END
END
But the stored procedure is running twice and populate my test table twice. I think the problem is with the send conversation part in the trigger.
I have been struck on this for a long time. Please, Can some one help me on this
You need to add to the RECEIVEprojection list the message_type_name. You must look at what message type you received and only call the mailing routine when the message type is MailMessage. As things are, you will always get a second message, the one from your END DIALOG. You simply need to call END DIALOG again on that case, to close the sending side handle:
WAITFOR (
RECEIVE TOP(1)
#msgBody = CAST(message_body AS XML),
#dlgId = conversation_handle ,
#msgType = message_type_name
FROM dbo.MessageQueue ), TIMEOUT 500
IF (##ROWCOUNT = 0 OR #msgBody IS NULL)
BREAK
ELSE IF #msgType = N'MailMessage'
BEGIN
DECLARE #Subject nvarchar(200), #CreatedDateTime datetime, #MailType nvarchar(50)
---EXEC dbo.SendMails 1,1;
END
END CONVERSATION #dlgId;
Any particular reason you are re-inventing the wheel? This is pretty much how sp_send_dbmail already works (except is using external activation).
Hi would like to send an email alert after checking the result of a query which will return the numbers of rows in a table. Does anyone have any ideas how I could do this in SQL Server 2000 in 2005 I would use a maintenence plan but not sure how in 2000?
I did this a few years ago - hastily adapted from a MS Knowledgebase article. I changed the params to be hardcoded variables. I've removed the identifying servernames/email addresses etc etc from here but you should be able to figure it out!
CREATE PROCEDURE [dbo].[usp_SendSuccessMail]
--Adapted from a Microsoft KnowledgeBase article, Jan 16th 2006.
-- #From varchar(100) ,
-- #To varchar(100) ,
-- #Subject varchar(100)=" ",
--#Body varchar(4000) =" "
/*********************************************************************
This stored procedure takes the parameters and sends an e-mail.
All the mail configurations are hard-coded in the stored procedure.
Comments are added to the stored procedure where necessary.
References to the CDOSYS objects are at the following MSDN Web site:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cdosys/html/_cdosys_messaging.asp
***********************************************************************/
AS
Declare #From varchar(100) --origninally passed as parameter above. We want to hard-code it.
Declare #To varchar(100) --origninally passed as parameter above. We want to hard-code it.
Declare #Subject varchar(100) --origninally passed as parameter above. We want to hard-code it.
Declare #Body varchar(4000) --origninally passed as parameter above. We want to hard-code it.
Declare #iMsg int
Declare #hr int
Declare #source varchar(255)
Declare #description varchar(500)
Declare #output varchar(1000)
Set #From = 'abc#xyz.com'
Set #To = 'xyz#abc.com'
Set #Subject = 'Whatever Subject You Want'
Set #Body = 'Some useful text'
--************* Create the CDO.Message Object ************************
EXEC #hr = sp_OACreate 'CDO.Message', #iMsg OUT
IF #hr <>0 BEGIN
print 'sp_OACreate failed'
END
--***************Configuring the Message Object ******************
-- This is to configure a remote SMTP server.
-- http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cdosys/html/_cdosys_schema_configuration_sendusing.asp
EXEC #hr = sp_OASetProperty #iMsg, 'Configuration.fields("http://schemas.microsoft.com/cdo/configuration/sendusing").Value','2'
-- This is to configure the Server Name or IP address.
-- Replace MailServerName by the name or IP of your SMTP Server.
EXEC #hr = sp_OASetProperty #iMsg, 'Configuration.fields("http://schemas.microsoft.com/cdo/configuration/smtpserver").Value', 'mail.xxxxxxxxxx.com'
-- Save the configurations to the message object.
EXEC #hr = sp_OAMethod #iMsg, 'Configuration.Fields.Update', null
-- Set the e-mail parameters.
EXEC #hr = sp_OASetProperty #iMsg, 'To', #To
EXEC #hr = sp_OASetProperty #iMsg, 'From', #From
EXEC #hr = sp_OASetProperty #iMsg, 'Subject', #Subject
-- If you are using HTML e-mail, use 'HTMLBody' instead of 'TextBody'.
EXEC #hr = sp_OASetProperty #iMsg, 'TextBody', #Body
EXEC #hr = sp_OAMethod #iMsg, 'Send', NULL
IF #hr <>0
BEGIN
EXEC #hr = sp_OAGetErrorInfo NULL, #source OUT, #description OUT
IF #hr = 0
BEGIN
SELECT #output = ' Source: ' + #source
PRINT #output
SELECT #output = ' Description: ' + #description
PRINT #output
END
END
-- Do some error handling after each step if you have to.
-- Clean up the objects created.
send_cdosysmail_cleanup:
If (#iMsg IS NOT NULL) -- if #iMsg is NOT NULL then destroy it
BEGIN
EXEC #hr=sp_OADestroy #iMsg
END
ELSE
BEGIN
PRINT ' sp_OADestroy skipped because #iMsg is NULL.'
RETURN
END
GO
Because SQLMail is so useless for real world usage (MAPI, etc), we ended up using SQLAnswersMail which is very powerful and easy to use.
Perhaps CDOSYS will serve your needs, check the links below
Configuring SQL Server 2000
Notification with CDOSys
How to send e-mail without using SQL Mail in SQL Server?
Try this:
xp_smtp_sendmail
Link
http://www.sqldev.net/xp/xpsmtp.htm
I've used it before in production and it works great.