Obtain a repeated data and send SQL mail - sql

Good day I have a table called Ticket which has several tickets registered, each one has a status:
1 = Accepted,2 = Assigned,3 = At ​​attention,4 = Attended,5 = Agree.
I want to perform a stored procedure in which I only send mail to the tickets that are in state 4, that is, my ticket has status 4, it is activated exec sp_sendmail .
Then I will use it as a Job every 30 minutes, check to see if it is still in that state and if it is in state 4 it sends again mail, once it changes state 4 to 5 it will not send anything and it will be closed.

Something like this, that loops through the list of tickets and sends an email. Couple notes, though: first, if you try to send too many at once, your email provider may start dropping them, so maybe put in a {pre}WAITFOR DELAY '00:00:02'{pre} delay between messages. Also, instead of sending one email per ticket, you can look into the query options in sp_send_dbmail: you can email a single list of all currently-4 tickets. It just depends on your needs.
CREATE PROCEDURE dbo.SendTicketAttendedEmails
AS
BEGIN
DECLARE #MailList TABLE(TicketID INT, SendTo VARCHAR(255))
DECLARE #ThisTicketID INT
, #MailMessage NVARCHAR(2000)
, #MailSubject NVARCHAR(255)
, #SendTo VARCHAR(255)
INSERT INTO #MailList
([TicketID], [SendTo])
SELECT t.[ID], u.[UserEmail]
FROM dbo.YourTicketTable t
JOIN dbo.YourUserTable u
ON t.UserCreated = u.ID
WHERE [StatusID] = 4
WHILE EXISTS(SELECT 1 FROM #MailList)
BEGIN
SELECT TOP(1) #ThisTicketID = [TicketID]
, #MailSubject = 'Ticket ' + CAST([TicketID] AS VARCHAR(10)) + ' is in status 4.'
, #MailMessage = 'Please review, or whatever, ticket ' + CAST([TicketID] AS VARCHAR(10)) + '.'
, #SendTo = COALESCE([SendTo], 'yourEmailAddress#InCase.Missing')
FROM #MailList
ORDER BY [TicketID];
DECLARE #mailitem_id INT ;
EXEC [msdb].dbo.[sp_send_dbmail]
#profile_name = 'SomeDBMailProfileName' -- sysname
, #recipients = #SendTo -- varchar(max)
, #subject = #MailSubject -- nvarchar(255)
, #body = #MailMessage -- nvarchar(max)
, #mailitem_id = #mailitem_id OUTPUT -- int
, #from_address = 'you#you.com' -- varchar(max)
, #reply_to = 'you#you.com' -- varchar(max)
DELETE #MailList
WHERE [TicketID] = #ThisTicketID
END
END

Basically you will use something like this for your job.
exec sp_send_dbmail
#profile_name = 'your_mail_profile'
,#recipients = 'you#email.com'
,#subject = 'Attended'
,#query = 'select * from yourTable where [status] = 4'
--,#attach_query_result_as_file = 1
--,#query_attachment_filename = 'somefile.csv'
See other options in the docs... and adjust accordingly.

Related

select statement blocking another select statement

I'm not quite sure what is happening here. I have an alert that goes out if #StoreOrderID >1.
It goes like this:
declare #message varchar(1000)
#StoreID --(retrieves info from StoreOrders tables)
BEGIN
select #message = 'store' + storename
from StoreOrders as so
join Distributors as ds
on ds.DistributorID = so.StoreOrderID
where ds.SDistributorID = #StoreID
select #message = brandID
from StoreOrders a
join Brandtitles as b
on b.branddistributorID = a.StoreOrderID
where b.brandNum = #DistributorNum and b.branddistributorID = #StoreID
select #message = 'date' + ISNULL(convert(varchar, #Date),'')
select #message = 'cost' + ISNULL(Convert(varchar,#Cost),'')
Also for some reason if i try to concatenate a string unto the 'brand' select it throws an error. I can do it for the 'storename'. I think this may have something to do with it.
If I comment out the storename select it will send the alert for brandID, if I comment out the other one it does the other one. However, if I leave both of them, it will only show one of them. What am I doing wrong here?
As a user mentioned in the comments, you are overwriting the #message variable everytime you assign it a new value, you are not concatenating any of the values. A much simpler and cleaner way would be something like....
declare #message varchar(1000)
#StoreID [DataType]--(retrieves info from StoreOrders tables)
BEGIN
Declare #storename VARCHAR(100)
, #brandID VARCHAR(100)
, #Date VARCHAR(100)
, #Cost VARCHAR(100);
select #storename = 'store' + ISNULL(storename , 'Unknown')
from StoreOrders as so
join Distributors as ds
on ds.DistributorID = so.StoreOrderID
where ds.SDistributorID = #StoreID;
select #brandID = ISNULL(CAST( brandID AS VARCHAR(100) , 'Unknown')
from StoreOrders a
join Brandtitles as b
on b.branddistributorID = a.StoreOrderID
where b.brandNum = #DistributorNum
and b.branddistributorID = #StoreID;
select #Date = 'date' + ISNULL(convert(varchar, #Date),'');
select #Cost = 'cost' + ISNULL(Convert(varchar,#Cost),'');
SET #message = #storename + #brandID + #Date + #Cost;
I Assume the code "alerting" the message is after the snipped you showed.
Then, as you use the same variable #message as target for both assignments, you overwrite the contents you assigned the first time when doing the second assignment. Only the values from the second assignment make it to the "alerting" command.
Use two different variables or "alert" your message after each assignment.

Script to check if mail profile is enabled in SQL Server

Does anyone have a script (TSQL or PowerShell) to check if mail profile is enabled on a SQL Server?
I noticed we are not receiving mails from a bunch of production servers, because mail profile NOT being enabled.
I need a script to run across all our prod boxes to check if this feature is enabled. I did some research, but failed to find a script. Thank you so much.
I asked a similar question here on dba.stackexchange.com.
From that help, I created this script which I have on GitHub which i set up a job to alert me when this is changed.
Here's the part you seem to care about:
/*
Confirm the Database Mail account and profile is configured correctly
*/
DECLARE #DatabaseMail VARCHAR(255);
SELECT
ProfileName = smp.name
,AccountName = sma.name
,AccountFromAddress = sma.email_address
,AccountReplyTo = sma.replyto_address
,SMTPServer = sms.servername
,SMTPPort = sms.port
FROM msdb.dbo.sysmail_account sma
INNER JOIN msdb.dbo.sysmail_profileaccount smpa ON sma.account_id = smpa.account_id
INNER JOIN msdb.dbo.sysmail_profile smp ON smpa.profile_id = smp.profile_id
INNER JOIN msdb.dbo.sysmail_server sms ON sma.account_id = sms.account_id;
/*
Confirm SQL Server Agent is configured to use Database Mail correctly
*/
DECLARE #res TABLE
(
Value VARCHAR(255)
, Data VARCHAR(255)
);
INSERT INTO #res
EXEC master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'UseDatabaseMail';
INSERT INTO #res
EXEC master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'DatabaseMailProfile';
IF (
SELECT COUNT(*)
FROM #res r
WHERE r.Value = 'UseDatabaseMail' AND r.Data = 1
) = 1 AND
(
SELECT COUNT(*)
FROM #res r
WHERE r.Value = 'DatabaseMailProfile' AND r.Data IS NOT NULL
) = 1
SET #DatabaseMail = 'Configured'
ELSE
SET #DatabaseMail = 'Not Configured';
select #DatabaseMail
Or, the limited results on what the profile is, and if you have it enabled at the agent level:
DECLARE #res TABLE
(
Value VARCHAR(255)
, Data VARCHAR(255)
);
INSERT INTO #res
EXEC master.dbo.xp_instance_regread
#rootkey = N'HKEY_LOCAL_MACHINE'
, #key = N'Software\Microsoft\MSSQLServer\SQLServerAgent'
, #value_name = N'DatabaseMailProfile';
INSERT INTO #res
EXEC sys.xp_instance_regread
#rootkey = N'HKEY_LOCAL_MACHINE'
, #key = N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent'
, #value_name = N'UseDatabaseMail'
SELECT *
FROM #res;
Here's the final code. I removed the additional info from scsimon's code.
DECLARE #DatabaseMail VARCHAR(255);
/*
Confirm SQL Server Agent is configured to use Database Mail correctly
*/
DECLARE #res TABLE
(
Value VARCHAR(255)
, Data VARCHAR(255)
);
INSERT INTO #res
EXEC master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'UseDatabaseMail';
INSERT INTO #res
EXEC master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'DatabaseMailProfile';
IF (
SELECT COUNT(*)
FROM #res r
WHERE r.Value = 'UseDatabaseMail' AND r.Data = 1
) = 1 AND
(
SELECT COUNT(*)
FROM #res r
WHERE r.Value = 'DatabaseMailProfile' AND r.Data IS NOT NULL
) = 1
SET #DatabaseMail = 'Configured'
ELSE
SET #DatabaseMail = 'Not Configured';
select #DatabaseMail EnableMailProfile

SQL Server 2008 R2 match counts

I have a SQL query that checks when a stored procedure was last run, from that date it gathers all the units that were purchased between that date and today's date and compares it to another number. If they match it sends an email saying the two number match and executes the rest of the stored procedure. However, when it runs I constantly get 0 for the number of accounts, when it should be a value greater than 0 daily:Here is my code:
DECLARE #UnitsPurchased int
DECLARE #WelcomeLetterGenerated int
DECLARE #LastSuccesfulRunTime datetime
SET #LastSuccesfulRunTime = (select cast(run_datetime as DATE) from apsllc_v2.dbo.LastSuccesfulRunDate)
SET #UnitsPurchased = (SELECT COUNT(*) FROM rsbi.dbo.loans as l
where rsbi.dbo.fn_Convert_Paradata_Birth_Date(l.Unit_PURDATE) between #LastSuccesfulRunTime
AND getDate() and l.LN_CLASS in (58,59)) -- Shows the number of units that were purchased yesterday
SET #WelcomeLetterGenerated = ( SELECT COUNT(*) FROM apsllc_v2.dbo.ApsUpload ap where ap.FormNumber IN(1100,1150) ) -- Shows how many welcome letters were generated today
if #UnitsPurchased <> #WelcomeLetterGenerated
begin
EXEC msdb.dbo.sp_send_dbmail
#recipients = N''
, #body = ' '
, #subject = 'Welcome Letter Counts do not Match'
, #profile_name = 'Email_Profile_01'
return
end
ELSE if #UnitsPurchased = #WelcomeLetterGenerated --or if
begin
EXEC msdb.dbo.sp_send_dbmail
#recipients = N''
, #body = ' '
, #subject = 'Welcome Letter Counts Match'
, #profile_name = 'Email_Profile_01'
end

SQL SERVER: Altering service broker stored procedures

I cannot alter the service broker stored procedure, when I update the stored procedure it does not show any error and successfully gets updated but the changes does not come into affect.
Is it because I need to stop the queue of the service broker on both databases before the changes could come into affect?
Note: the service broker stored procedures produce and read xmls.
INCLUDING THE STORE PROCEDURE
ALTER PROCEDURE [dbo].[ServiceBroker_AtTarget_FromSLICJobEstimateDetailsNewLineAddedBySupplier]
#XML XML(SLICMessageSchema)
AS
BEGIN
-- extract data :
DECLARE
#LogNo INT,
#QuoteReference INT,
#JobEstimatesDetailID INT,
#UserName NVARCHAR(50),
#Description NVARCHAR(MAX),
#UnitValue DECIMAL(18,2),
#Quantity DECIMAL(18,2),
#LineTotal DECIMAL(18,2),
#QuoteTotal DECIMAL(18,2),
#tsCreated DATETIME
SELECT #QuoteReference = #XML.value('data(//FromSLIC/FromSLICJobEstimateDetailsNewLineAddedBySupplier/#QuoteReference)[1]', 'int'),
#JobEstimatesDetailID = #XML.value('data(//FromSLIC/FromSLICJobEstimateDetailsNewLineAddedBySupplier/#JobEstimatesDetailID)[1]', 'int'),
#UserName = #XML.value('data(//FromSLIC/FromSLICJobEstimateDetailsNewLineAddedBySupplier/#UserName)[1]', 'nvarchar(50)'),
#Description = #XML.value('data(//FromSLIC/FromSLICJobEstimateDetailsNewLineAddedBySupplier/#Description)[1]', 'nvarchar(max)'),
#UnitValue = #XML.value('data(//FromSLIC/FromSLICJobEstimateDetailsNewLineAddedBySupplier/#UnitValue)[1]', 'decimal(18,2)'),
#Quantity = #XML.value('data(//FromSLIC/FromSLICJobEstimateDetailsNewLineAddedBySupplier/#Quantity)[1]', 'decimal(18,2)'),
#tsCreated = #XML.value('data(//FromSLIC/FromSLICJobEstimateDetailsNewLineAddedBySupplier/#tsCreated)[1]', 'datetime')
SET #LogNo = (SELECT mlq.logno FROM fsgmgtservices.dbo.maintlogquotes mlq WHERE mlq.quoteno = #QuoteReference)
INSERT INTO fsgcentraldata.dbo.[tblSLICGeneratedEvents]
(EventNameID, tsCreated, CreatedBy, IsAcknowledged, JobNumber, ContractorID)
SELECT 9, #tsCreated, #UserName, 0, #LogNo, je.contractorid
FROM [slic3.0].dbo.JobEstimates je WHERE je.legacyreference = CAST(#quotereference AS varchar(50))
SET #LineTotal = (#UnitValue * #Quantity) // IF I CHANGE IT TO ((#UnitValue * 2)) FOR EXMPL
INSERT INTO fsgmgtservices.dbo.maintlogquotedetails
(quoteno, details, quantity, rate, amount, [date], slicreference)
SELECT #QuoteReference, #description, #quantity, #UnitValue, #LineTotal, #tscreated, #JobEstimatesDetailID
SET #QuoteTotal = (SELECT SUM(mlqd.amount) FROM fsgmgtservices.dbo.maintlogquotedetails mlqd
WHERE mlqd.quoteno = #QuoteReference)
UPDATE fsgmgtservices.dbo.maintlogquotes SET amount = #QuoteTotal WHERE quoteno = #QuoteReference
INSERT INTO [fsgmgtservices].[dbo].maintlognotes
(logno, [date], [user], [note], transferredfromslic)
SELECT #LogNo, #tsCreated, #UserName, 'Quote ' + CAST(#QuoteReference AS varchar(20)) + ', new lines added by supplier in SLIC By ' + #UserName , 0
END
Changing an activated stored procedure does not kill any running instance. Most likely your old code is still running in a loop and will continue to run until it exits the loop or you kill it.

Dyanamic SQL Query not working

I have a table called procedure look up which stores medical procedures
and have multiple company table for which i had to calculate the procedure fees so i had created a dynamic query for it
below is the query
declare #TableProviderName varchar(500)
,#SQLQuery1 nvarchar(max)
,#MaxRecordSize Int
,#Name varchar(250) = null
,#code varchar(50) = null
set #Name = 'sug'
set #TableProviderName = 'PRD_Tata_Details'
set #MaxRecordSize = 50
set #SQLQuery1 = '
;WITH CTE_Procedure AS
(
select top (#MaxRecordSize1)
GPL_ID_PK as ProcedureID
,GPL_ProcedureType as ProcedureType
,GPL_Code as ProcedureCode
,coalesce(Name,GPL_Name,null)as Procedurename
,GPL_CurrencyType_FK as CurrencyType
,ISNULL(GPL_Description,''NIL'') as ProcedureDescription
,ISNULL(GPL_PatientInstruction,''NIL'')as PatientInstructions
,GPL_ProcedureCategory_FK as ProcedureCategory
,GPL_CategorySpecialization_FK as ProcedureSpecialization
,coalesce(PatientPayable,GPL_ProcedureFee,0) as PatientPayable
,0 as InsurancePayable
,0 as InsuranceDiscount
,1 as ProcedureCount
,0 as IndBillingStatus
,Case
when GeneralProcedureID is not null then ''Insurance Supported''
else ''Insurance not Supported''
end as InsuranceStatus
,ROW_NUMBER( ) OVER ( ORDER BY GPL_Name ASC) as RowNumber
from
dbo.PRD_GeneralProcedure_Lookup
left join '
+ #TableProviderName +
'
on
GeneralProcedureID = GPL_ID_PK
where
GPL_ProcedureType = #ProcedureType1
and
(#Name1 is null or GPL_Name like %#Name1%)
and
(#code1 is null or GPL_Code like %#code1%)
)
Select
*
from
CTE_Procedure
'
Execute sp_executesql #SQLQuery1, N'#MaxRecordSize1 int, #ProcedureType1 tinyint,#Name1 varchar(250)
, #code varchar(50)' ,#MaxRecordSize1 = #MaxRecordSize, #ProcedureType1 = 1 , #Name1 = #Name, #code1 = #code
but when executing error occurs saying
"Incorrect syntax near '#Name1'"
can anyone help me with that where condition side issue
I think It may have something to do with your like statement and the way you pass the parameter.
Have a look at this question Parameters & Like statement.
#Name1 = "'%yourvalue%'"