Auto generate a email based on a date (ColdFusion) - loops

I have this big database table that contains 12 medical ceritifcations, expiration dates, links to files and what companies they're from. I need to generate a report via email within 90,60,30 and 15 days of the the certification expiring date.
Here's what the datebase looks like:
certID,
profileID,
cprAdultExp,
cprAdultcompany,
cprAdultImage,
cprAdultOnFile,
cprInfantChildExp,
cprInfantChildcompany,
cprInfantChildImage,
cprInfantChildOnFile,
cprFPRExp,
cprFPRcompany,
cprFPRImage,
cprFPROnFile,
aedExp,
aedcompany,
aedImage,
aedOnFile,
firstAidExp,
firstAidcompany,
firstAidImage,
firstAidOnFile,
emtExp,
emtcompany,
emtImage,
emtOnFile,
waterSafetyInstructionExp,
waterSafetyInstructioncompany,
waterSafetyInstructionImage,
waterSafetyInstructionOnFile,
bloodPathogensExp,
bloodPathogenscompany,
bloodPathogensImage,
bloodPathogensOnFile,
oxygenAdminExp,
oxygenAdmincompany,
oxygenAdminImage,
oxygenAdminOnFile,
lifegaurdingExp,
lifegaurdingcompany,
lifegaurdingImage,
lifegaurdingOnFile,
wildernessResponderExp,
wildernessResponderCompany,
wildernessResponderImage,
wildernessResponderOnFile,
notes
How do I write some sort of loop to check all the dates (anything with EXP is a date) then store which ones are expiring, and email all those details to a person?

Since you have to send the email through CF (I presume) then the way I'd approach this is to run a scheduled task once a day that checks which rows have a 15, 30, 60 and 90 day expiry anniversary. So the scheduled task would run a few queries and then send the emails.
The first thing is to actually find the rows in question (all my SQL presumes MS SQL Server - other RDBMSs will have similar syntax):
<cfquery name="qExpiring">
select
certID,
dateDiff(day, cprAdultExp, getDate()) as cprAdultExpDaysSince
dateDiff(day, cprInfantChildExp, getDate()) as cprInfantChildExpDaysSince
from yourTable
where
dateDiff(day, cprAdultExp, getDate()) in (15, 30, 60, 90)
or
dateDiff(day, cprInfantChildExp, getDate()) in (15, 30, 60, 90)
</cfquery>
This should give you a result set like so:
certID|cprAdultExpDaysSince|cprInfantChildExpDaysSince|etc.
___________________________________________________________
xxxxxx|30 |5 |etc.
xxxxxx|16 |60 |etc.
xxxxxx|2 |90 |etc.
Any that have matches on 15, 30, 60, 90 you are interested in processing futher. You could use a query of queries to do this:
<cfquery name="qAdultExpRenewal" dbtype="query">
select * from qExpiring
where cprAdultExpDaysSince in (15, 30, 60, 90)
</cfquery>
You cn then loop over these records and send the appropriate email based on the value of cprAdultExpDaysSince.
You're missing a fair bit of info to give you a comprehensive answer but I hope that this will point you in the right direction.

If you have access to the database, you should probably create a view or views which give you only those who are expiring or adds a field for days until expiration for each cert and query that. Alternatively, you could write a single query which grabs all info where any cert is expiring (WHERE cprAdultExp [comparison] date OR cprInfantExp [comparison] date....), then loop through the records to filter or group by cert expiring.

You proably want some sort of stupid-huge query which looks like
select "CPR Adult", cprAdultExp, cprAdultcompany, cprAdultImage, cprAdultOnFile from thebigtable where cprAdultExp [comparison] interestingdate
union
select "CPR Child", cprChild....
union ...
Then iterate over the rows that you get back, using the first column to indicate what ceritification is expiring.

Related

sending reminder mail when specific no. of days are left Which is manger by the Query SQL Server?

i want to send the Email on Certification expiry when 21,14,7,3,2,1 days are left by a scheduler which picks the data by the Query .
i am using the ExpiryNotification bit col.as a flag(as previous it used to sent on 30 days only)
the data in the Query is picked from scheduler.now if i have to do changes in the Query to implement this logic i will need to change the col from bit to int and check the Notification col.but what if the Scheduler does not run when 21 days are left for some odd reason then what will happen.is there any other way to implement this Logic by sql server ?
it will make the ExpiryNotification col value to 1 when the mail is send
exisitng Query (checking only 30 days)
Select * from wsm_certification
where
(DATEDIFF(d, GETDATE(), wsm_Certification.RenewalDate) = 30
and wsm_Certification.ExpiryNotification = 0)
You may try something like this
(DATEDIFF(d, GETDATE(), wsm_Certification.RenewalDate) = 21 OR (DATEDIFF(d, GETDATE(), wsm_Certification.RenewalDate) = 14
Use in operator to check multi values
Eg:
Select * from wsm_certification
where
(DATEDIFF(d, GETDATE(), wsm_Certification.RenewalDate) in (21,14,7,3,2,1)
and wsm_Certification.ExpiryNotification = 0)

How to identify missing weeks using SQL code?

I am trying to identify specific weeks that are missing in my data. I have multiple states with different date ranges and would like to output all of the missing weeks for the various states that I do have. Not even sure where to begin with a SQL code that would begin to identify missing weeks. Any help on this would be greatly appreciated. BTW I'm using SQL Server 2016.
Thanks!
Sample Data:
State WeekEndingDate Sales
ID 7/5/2015 125000
ID 12/13/2015 127263
IN 8/20/2016 126589
IN 8/27/2016 124568
IN 10/15/2016 119654
MI 01/02/2017 105687
MI 02/05/2017 145962
An example of my desired output would be:
MI 01/09/2017 136589
MI 01/16/2017 125641
MI 01/23/2017 145769
MI 01/30/2017 135697
IN 09/03/2016 145693 and so on....
This is what's commonly known as a "gaps and islands" problem.
To solve, I strongly suggest you create a date table. Then, assuming that you have established that your week ending day is always Saturday, you can include that date table in the query.
select MD.state,DT.weekendingdate,MD.sales
from DateTable DT
left outer join MyData MD on DT.Weekendingdate = MD.Weekendingdate
where dt.weekendingdate >= '2016-08-01' and dt.weekendingdate <= '2016-08-31'

add x number of working days to date

I am trying to find the date after specific number of days.
My query looks like this:
UPDATE [PST].[dbo].[tbl_Project_tracker1]
SET Predicted_Eng_Comp_date = tb2.Predicted_Eng_Comp_date
FROM (SELECT NETWORK_NO,
dateadd(DAY, 20, Actual_Eng_Start_date) as Predicted_Eng_Comp_date
FROM [PST].[dbo].[tbl_Project_tracker1]
) as tb2
WHERE [NETWORK_NO] = tb2.[NETWORK_NO]
The query works fine but i am looking for working days. How do i calculate that?
Please make use of below Query (Which replaces your current query):
UPDATE [PST].[dbo].[tbl_Project_tracker1] SET Predicted_Eng_Comp_date = DATEADD(DAY, 20, Actual_Eng_Start_date)

Alternatives for parsing sql query

I have an audit running on multiple tables in my database that is triggered when a user runs a select against said tables. I am attempting to parse the 'statement' returned from the audit and get a username out of the information. Here is my query:
SELECT *
FROM (SELECT LastName,
queryLastName,
statement,
Event_time AS CurrentDateTime,
'AuditFile' AS SourceTable
FROM (SELECT statement,
event_time,
SUBSTRING(server_principal_name, 9, len(server_principal_name) - 8) AS LastName,
SUBSTRING(SUBSTRING(statement, CHARINDEX('LastName like ''%', statement) + 16, 20), 0, CHARINDEX('%''', SUBSTRING(statement, CHARINDEX('LastName like ''', statement) + 16, 20))) AS queryLastName
FROM #MyTempTable
WHERE server_principal_name != 'abc'
AND CHARINDEX('LastName like ''%', statement) > 0) AS A) AS B
WHERE querylastname != ''
Now, the above query will correctly return any SELECT query that has Lastname like '%name%', but i'd also like to be able to return names looked up in other ways such as '%name' or '_name__'. Are there any more elegant solutions to solve this problem?
Edit: The Audit file contains a column called 'Statement'. This holds what the query was that triggered the audit. For example,
SELECT * from tblUserNames where LastName Like '%Smith%'
will trigger the audit and place the above query in statement.
My query takes Smith out of the string however if a user entered '%Smith' instead, the query would not work as it does not pick up variations. Same goes for 'Smith', 'Smith' etc. If possible, I need a more elegant way to handle multiple situations where a user could look up a name using wildcards on either end of the name.

Google App Engine / BigQuery log search for arbitrary string with full context

I have enabled the Google App Engine (GAE) log export functionality, so all of my App Engine logs can be queried with Google BigQuery.
I would like to find a specific user ID in any logs in the past 7 days. I'm able to get each matching protoPayload.line with the snippet below, but I'm unable to show full context, i.e. all the other instances of protoPayload.line which came with the matching log entry.
SELECT
metadata.timestamp AS Time,
protoPayload.host AS Host,
protoPayload.status AS Status,
protoPayload.resource AS Path,
protoPayload.line.logMessage
FROM
(TABLE_DATE_RANGE(my_logs.appengine_googleapis_com_request_log_,
DATE_ADD(CURRENT_TIMESTAMP(), -7, 'DAY'), CURRENT_TIMESTAMP())
)
WHERE
protoPayload.line.logMessage like "%My Search String%"
ORDER BY time
limit 100
Here is how I would write your query without TABLE_DATE_RANGE duplication. I also changed LIKE to CONTAINS for the search condition.
SELECT
insertId,
metadata.timestamp AS Time,
protoPayload.host AS Host,
protoPayload.status AS Status,
protoPayload.resource AS Path,
protoPayload.line.logMessage AS Message
-- [add more fields here]
FROM
TABLE_DATE_RANGE(my_logs.appengine_googleapis_com_request_log_, DATE_ADD(CURRENT_TIMESTAMP(), -7, 'DAY'), CURRENT_TIMESTAMP())
OMIT RECORD IF
EVERY(NOT protoPayload.line.logMessage CONTAINS "My Search String")
ORDER BY
insertId
LIMIT 100
After lots of digging, below is how you do full context search for the string "My Search String" in the past seven days.
Some things to note:
You must replace my_logs with whatever your BigQuery dataset is called.
You can change the number -7 in both locations to change the date range you care about. -8 will target the past 8 days, for example.
You can add additional information you want returned in the outer select block by putting them above where it says [add more fields here].
SELECT
insertId,
metadata.timestamp AS Time,
protoPayload.host AS Host,
protoPayload.status AS Status,
protoPayload.resource AS Path,
protoPayload.line.logMessage AS Message
-- [add more fields here]
FROM (
SELECT
*
FROM
TABLE_DATE_RANGE(my_logs.appengine_googleapis_com_request_log_, DATE_ADD(CURRENT_TIMESTAMP(), -7, 'DAY'), CURRENT_TIMESTAMP()) )
WHERE
insertId IN (
SELECT
insertId
FROM (TABLE_DATE_RANGE(my_logs.appengine_googleapis_com_request_log_, DATE_ADD(CURRENT_TIMESTAMP(), -7, 'DAY'), CURRENT_TIMESTAMP()) )
WHERE
protoPayload.line.logMessage LIKE "%My Search String%" )
ORDER BY
insertId
LIMIT 100
There may be a way to write the above without the strange TABLE_DATE_RANGE duplication, so if anyone knows, please let me know!

Resources