SQL Server 2008 DBMail - sql

Could anyone help on the below stored procedure? I am getting error
Incorrect syntax near '#profile_name'" SELECT distinct(EmailAddress)
as RECIPIENTS, #body = Replace(#bodypre, "$Approver", Forename) FROM
[STAS].[dbo].[NotifictationEmailID_View]
in the query
SELECT distinct(EmailAddress) as RECIPIENTS,
#body = Replace(#bodypre, "$Approver", Forename)
FROM [STAS].[dbo].[NotifictationEmailID_View]
which is part of this stored procedure:
ALTER proc [dbo].[test]
as
begin
DECLARE #subject VARCHAR(500)
Declare #bodypre varchar(5000)
DECLARE #ProgramName VARCHAR(50)
DECLARE #FirstName VARCHAR(50)
DECLARE #body VARCHAR(5000)
DECLARE #email VARCHAR(500)
declare #recipients VARCHAR(5000)
DECLARE #CurrentRec AS INT
DECLARE #RecCount AS INT
Declare #emailStop as int
SET #CurrentRec = 1
SET #RecCount = 0
select #subject=EmailMessageSubject,
#bodypre = EmailMessageBody,
#emailStop = EmailStop_Flag
from STAS.dbo.MC_STAS_EmailMessage where TimeSheetStatusID = 3
SELECT #RecCount = COUNT(EmailAddress) FROM [STAS].[dbo].[NotifictationEmailID_View]
if (#emailStop <> 1 AND #RecCount > 0)
WHILE #RecCount >= #CurrentRec
begin
EXEC msdb.dbo.sp_send_dbmail
SELECT distinct(EmailAddress) as RECIPIENTS ,#body =Replace(#bodypre,"$Approver",Forename) from [STAS].[dbo].[NotifictationEmailID_View]
#profile_name = "STAS Email User",
#recipients = #RECIPIENTS,
#subject = #SUBJECT,
#body = #body
SET #CurrentRec = #CurrentRec + 1
end
end
Thanks,

Try this:
SELECT DISTINCT
EmailAddress as RECIPIENTS,
#body = Replace(#bodypre, "$Approver", Forename)
FROM [STAS].[dbo].[NotifictationEmailID_View]
DISTINCT is not a function that you can call like you did - it's a SQL keyword.

Related

SSIS Error: Unable to retrieve destination column descriptions from the parameters of the SQL command

I am getting an error :
[Load updated records to Table_vwAs_FixedIdentifier [85]] Error: Unable to retrieve destination column descriptions from the parameters of the SQL command.
when I execute the SSIS task in the image. It fails on the lower left "Load updated records to Table_vwAs.." oleDb update task. It has the following sql statement and also has a trigger also shown below. I have not been able to identify the cause of this issue till now. When I disabled the trigger, the task ran successfully. Any help will be eye-opening.
UPDATE
[dbo].[Sec]
SET
[SecID]=?
,[SECURITY_NAME]=?
,[SECURITY_SECTYPE_ID]=?
,[SECURITY_EXCHANGE_ID]=?
WHERE
[MasterID]=?
Trigger code is as follows:
alter trigger [dbo].[TrTable_Fixed_AFTERUPDATE] on [dbo].[Sec]
after insert ,update
as
set NOCOUNT on
declare #DBMailDistributionListId varchar(50)
declare #ProfileName varchar(max)
declare #Recipients varchar(max)
declare #CopyRecipients varchar(max)
declare #BlindCopyRecipients varchar(max)
set #DBMailDistributionListId = 'Crossadyne1'
set #ProfileName = SharedCode.dbo.FnGetDBMailDistributionListProfileName(#DBMailDistributionListId)
set #Recipients = SharedCode.dbo.FnGetDBMailDistributionListRecipients(#DBMailDistributionListId)
set #CopyRecipients = SharedCode.dbo.FnGetDBMailDistributionListCopyRecipients(#DBMailDistributionListId)
set #BlindCopyRecipients = SharedCode.dbo.FnGetDBMailDistributionListBlindCopyRecipients(#DBMailDistributionListId)
declare #Subject varchar(max)
declare #Body varchar(max)
set #Body = ''
select distinct #Body = #Body + 'Master Sec ID: ' + convert(nvarchar(50) ,i.MasterId) + char(13) + char(10)
+ 'New Legal Entity ID: ' + convert(nvarchar(50) ,i.[INTERNAL_SECURITY_LEGALENTITY_ID])
from INSERTED i
inner join DELETED d
on i.MasterId = d.MasterId
where i.[INTERNAL_SECURITY_LEGALENTITY_ID] <> d.[INTERNAL_SECURITY_LEGALENTITY_ID]
and i.Security_Change_Date = i.LegalEntityChangeDate
and i.LegalEntityChangedBy not in (2 ,5)
if (#Body <> '')
begin
set #Subject = 'WARNING: Crossadyne Security Legal Entity changed'
exec msdb.dbo.sp_send_dbmail
#profile_name = #ProfileName
, #recipients = #Recipients
, #copy_recipients = #CopyRecipients
, #blind_copy_recipients = #BlindCopyRecipients
, #subject = #Subject
, #body = #Body
end
set #DBMailDistributionListId = 'test'
set #ProfileName = SharedCode.dbo.FnGetDBMailDistributionListProfileName(#DBMailDistributionListId)
set #Recipients = SharedCode.dbo.FnGetDBMailDistributionListRecipients(#DBMailDistributionListId)
set #CopyRecipients = SharedCode.dbo.FnGetDBMailDistributionListCopyRecipients(#DBMailDistributionListId)
set #BlindCopyRecipients = SharedCode.dbo.FnGetDBMailDistributionListBlindCopyRecipients(#DBMailDistributionListId)
set #Body = ''
select distinct #Body = #Body + 'Master ID: ' + convert(nvarchar(50) ,i.MasterId) + char(13) + char(10)
+ 'Previous Legal Entity ID: ' + convert(nvarchar(50) ,d.[INTERNAL_SECURITY_LEGALENTITY_ID])
from INSERTED i
inner join DELETED d
on i.MasterId = d.MasterId
where i.[INTERNAL_SECURITY_ID] <> d.[INTERNAL_SECURITY_LEGALENTITY_ID]
if (#Body <> '')
begin
set #Subject = 'WARNING: Crossadyne Security Legal Entity changed'
exec msdb.dbo.sp_send_dbmail
#profile_name = #ProfileName
, #recipients = #Recipients
, #copy_recipients = #CopyRecipients
, #blind_copy_recipients = #BlindCopyRecipients
, #subject = #Subject
, #body = #Body
end
set NOCOUNT off
The issue was being caused due to
exec msdb.dbo.sp_send_dbmail
in the trigger code, because it is not configured on the QA server. Resolved after I commented those lines.

Send sp_send_dbmail only if results are available

I want to send an e-mail from my database only if the executed query has output and is not empty.
I was wondering how I can do this and where to embed this into my code. On top of my head, I thought of counting the results and having count > 0 or maybe something with the query in conjunction with ##rowcount > 0. What would you suggest?
Here is my code:
ALTER proc dbo.spBornBefore2000 as
set nocount on
DECLARE #sub VARCHAR(100),
#qry VARCHAR(max),
#msg VARCHAR(250),
#query NVARCHAR(max),
#tab char(1) = CHAR(9)
SELECT #sub = 'before 1990 -' + cast(getdate() as varchar(100))
SELECT #msg = N'blablabla.....'
SELECT #query = ' select id, name, dob, year(dob) as birth_year
from people
where year(dob) < 2000 '
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'USERS',
#recipients = 'abc#gmail.com',
#body = #msg,
#subject = #sub,
#query = #query,
#query_attachment_filename = 'before2000.csv',
#attach_query_result_as_file = 1,
#query_result_header = 1,
#query_result_width = 256 ,
#query_result_separator = #tab,
#query_result_no_padding =1;
You can do something like this:
EXEC(#query)
IF ##ROWCOUNT > 0
BEGIN
-- send email here
END
ALTER proc dbo.spBornBefore2000 as
set nocount on
DECLARE #sub VARCHAR(100),
#qry VARCHAR(max),
#msg VARCHAR(250),
#query NVARCHAR(max),
#tab char(1) = CHAR(9)
SELECT #sub = 'before 1990 -' + cast(getdate() as varchar(100))
SELECT #msg = N'blablabla.....'
SET #query = ' select id, name, dob, year(dob) as birth_year
from people
where year(dob) < 2000 '
IF EXISTS (select id, name, dob, year(dob) as birth_year
from people
where year(dob) < 2000)
begin
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'USERS',
#recipients = 'abc#gmail.com',
#body = #msg,
#subject = #sub,
#query = #query,
#query_attachment_filename = 'before2000.csv',
#attach_query_result_as_file = 1,
#query_result_header = 1,
#query_result_width = 256 ,
#query_result_separator = #tab,
#query_result_no_padding =1;
end
ELSE
begin
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'USERS',
#recipients = 'myself#gmail.com',
#body = 'No results returned'
end

using select in #recipients in sp_send_dbmail

I am using a sp_send_dbmail in a procedure. I execute it 4 times with different countries.
exec pr_drop_out_addresses #country='NO'
exec pr_drop_out_addresses #country='SE'
exec pr_drop_out_addresses #country='FI'
exec pr_drop_out_addresses #country='DK'
For each exec I would like to send the mail to set og receipients. They are different for each country. I try to solve it with a declare #recipients, but I get problems with the quotes. The code is like this. Any suggestions how to bypass the problem?
declare #country varchar (10)
set #country='SE'
declare #recipients nvarchar(500)='''' +select CASE when #country='NO' then 'xxxx#xxx' when #country='SE' then 'yyy#xxxx' END+'''';
declare #subject nvarchar(255) = 'Adresser fra ' + #country;
declare #query_attachment_filename nvarchar(255) = 'Adresser_for_'+#country +'_'+convert(varchar(10),getdate(),121) +'.csv';
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'VNPSQL email',
#recipients = #recipients,
#query = 'SELECT * FROM NSGstatistikk_dev.dbo.test',
#subject = #subject,
#attach_query_result_as_file=1,
#query_attachment_filename = #query_attachment_filename,
#query_result_separator = ';',
#query_result_no_padding = 1;
You are using incorrect syntax:
Use:
SELECT #recipients ='''' + CASE when #country='NO' then 'xxxx#xxx' when #country='SE' then 'yyy#xxxx' END+'''';
also, quotes are not required at all:
SELECT #recipients = CASE when #country='NO' then 'xxxx#xxx' when #country='SE' then 'yyy#xxxx' END;

How to loop the variables in t-sql

I have a t-sql i have to loop the variables.
DECLARE #empno nVARCHAR(MAX),#tableHTML NVARCHAR(MAX) ;
set #empno = (select Employee_No from emptemp where active = 'Yes');
SET #tableHTML =
N'<H2>Additions</H2>' +
N'<table border="1">' +
N'<th>Ename</th>' +
N'<th>Sal</th>' +
'<tr>' +
CAST ( ( select td=ename,'',td=sal,'' from emp Where empno = #empno)
FOR XML PATH('tr'), TYPE ) AS NVARCHAR(MAX) ) + N'</table>' ;
EXEC msdb.dbo.sp_send_dbmail
#recipients=someone#gmail.com,
#subject = emp ,
#body = #tableHTML , #body_format = 'HTML',
#profile_name = 'Sql Profile'
The Emptemp table looks like
id empno active
1 245 yes
2 124 yes
3 255 yes
4 224 No
I have to send the individual mail based on the data in emp table
That is how cursor will look like:
DECLARE #empno nVARCHAR(MAX)
DECLARE #tableHTML NVARCHAR(MAX) ;
DECLARE #ID INT;
DECLARE Curs CURSOR FAST_FORWARD
FOR
SELECT DISTINCT ID
FROM dEmptemp
WHERE active = 'Yes'
ORDER BY ID
OPEN Curs
FETCH NEXT FROM Curs INTO #ID
WHILE ##FETCH_STATUS = 0
BEGIN
set #empno = (SELECT empno FROM emptemp WHERE ID = #ID);
SET #tableHTML =
N'<H2>Additions</H2>' +
N'<table border="1">' +
N'<th>Ename</th>' +
N'<th>Sal</th>' +
'<tr>' +
CAST ( ( select td=ename,'',td=sal,'' from emp Where empno = #empno)
FOR XML PATH('tr'), TYPE ) AS NVARCHAR(MAX) ) + N'</table>' ;
EXEC msdb.dbo.sp_send_dbmail
#recipients=someone#gmail.com,
#subject = emp ,
#body = #tableHTML , #body_format = 'HTML',
#profile_name = 'Sql Profile'
FETCH NEXT FROM Curs INTO #ID
END
CLOSE Curs
DEALLOCATE Curs;

Stored Procedure sends two emails

EDIT
My previous posting on this subject involved specific transactions within the procedure which are no longer used and the error now only seems to occur in a very specific set of circumstances when I use an invalid user name to our companies email address badname#ourcompany.co.uk
The agent runs a stored procedure every ten minutes to send out emails. If it finds a new record then it sends a mail.
Noticed some strange behavior - if the TO field is correct but the BCC is an invalid email address but uses our valid company domain name (e.g. rubbishPart#ourcompany.co.uk) then the stored procedure sends out two emails to the TO. The domain name needs to be our company's domain name to get this behavior ...if I change the domain to gmail.com then only one mail goes out.
Why is this happening?
How do I change this behavior?
Is the Catch in this procedure redundant?
Here is the procedure:
BEGIN TRY
DECLARE #Exit TINYINT = 0
WHILE #Exit = 0
BEGIN
DECLARE #MailIdFound INT =
(
SELECT CASE
WHEN MIN(EmailId) IS NULL THEN 0
ELSE MIN(EmailId)
END
FROM WH.dbo.EmailQueue
WHERE DateEmailKey IS NULL
)
IF #MailIdFound = 0
BEGIN SET #Exit = 1 END --exit here as
ELSE
BEGIN --send the mail here
DECLARE #DateEmailKey INT
DECLARE #EmailBCC NVARCHAR(1000)
DECLARE #EmailTO NVARCHAR(1000)
DECLARE #EmailCC NVARCHAR(1000)
DECLARE #EmailBody NVARCHAR(MAX)
DECLARE #EmailImportance VARCHAR(6)
DECLARE #EmailSubject NVARCHAR(1000);
WITH myMostUrgentMail_cte
AS
(
SELECT TOP 1
DateEmailKey,
EmailBCC,
EmailTO,
EmailCC,
EmailBody,
EmailImportance,
EmailSubject
FROM WH.dbo.EmailQueue
WHERE EmailId = #MailIdFound
)
SELECT #DateEmailKey = DateEmailKey,
#EmailTO = EmailTO,
#EmailCC = EmailCC,
#EmailBCC = EmailBCC,
#EmailBody = EmailBody,
#EmailSubject = EmailSubject
FROM myMostUrgentMail_cte;
SET #EmailBody = #EmailBody + '<html>

<span style=''font-size:11.0pt;font-family:"Calibri","sans-serif"; color:black''><p><b>blah blah</b></p></span></html>'
EXEC msdb..sp_send_dbmail
#recipients = #EmailTO,
#copy_recipients = #EmailCC,
#blind_copy_recipients = #EmailBCC,
#subject = #EmailSubject,
#Importance = #EmailImportance,
#body_format = 'html',
#body = #EmailBody
UPDATE x
SET x.DateEmailKey = (CONVERT(CHAR(8),GETDATE(),(112))),
x.DateEmailTime = (CONVERT([time](7),left(CONVERT([char](12),GETDATE(),(114)),(8)),(0)))
FROM WH.dbo.EmailQueue x
WHERE x.EmailId = #MailIdFound
END
END
END TRY
BEGIN CATCH
-- handle error here
EXEC msdb..sp_send_dbmail
#recipients = 'ME#ME.com;'
, #subject = 'ERROR OCCURED DURING EMAIL CREATION'
, #body_format = 'html'
, #body = 'ERROR OCCURED'
UPDATE x
SET x.ErrorOccured = 1
FROM WH.dbo.EmailQueue x
WHERE x.EmailId = #MailIdFound
END CATCH;