Auto-Generate Emails using SQL - sql-server

I come from a programming background, and i'm having some difficulty wrapping my head around SQL's conditionals.
I'm looking to auto-generate emails when two criteria are met in my sql table.
If the value in column NextTestDate is not null AND today's date is equivalent to the next test date + 30 days THEN generate an email.
SELECT * FROM dbo.datmaintest
if NextTestDate is NOT NULL
AND DATEADD(day,30,DATEDIFF(day, 0, GETDATE())) = DATEADD(DAY, DATEDIFF(day, 0, NextTest), 0) then
BEGIN
use msdb
GO
EXEC sp_send_dbmail #profile_name='ControllerDB',
#recipients='test#test.com',
#subject='ITS ALIVE!',
#body='Time to grab lunch'
END

Think that you are looking for something like this.
IF EXISTS(
select *
FROM dbo.datmaintest
where DATEADD(day, 30, DATEDIFF(day, 0, GETDATE())) = NextTestDate
)
EXEC sp_send_dbmail #profile_name='ControllerDB'
, #recipients = 'test#test.com'
, #subject = 'ITS ALIVE!'
, #body = 'Time to grab lunch'

Something like this should get you started (I'm assuming that in the date logic portion, you meant to type 'NextTestDate' instead of 'NextTest'):
DECLARE #NextTestDate DATETIME
SET #NextTestDate = (SELECT TOP 1 NextTestDate FROM dbo.datmaintest)
--If the value is not null and today is equal to the value of 'next test date' + 30 days:
IF #NextTestDate IS NOT NULL
AND DATEDIFF(DAY, #NextTestDate, GETDATE()) = 30
BEGIN
use msdb
GO
EXEC sp_send_dbmail #profile_name='ControllerDB',
#recipients='test#test.com',
#subject='ITS ALIVE!',
#body='Time to grab lunch'
END
Basically, declare a variable and set it to the value from the database you want to check. Then, perform your check and if it is true, begin the email sending (and close it out with an END)

Related

set a text if GetDate() is equal to a specific date

I want to show a specific text in a stored procedure if the date is dec 24'th. How can I check if the current date is dec 24'th and then set a specific text and otherwise the text should be blank.
Are you looking for something like this?
SELECT
CASE WHEN MONTH(GETDATE()) = 12 AND DAY(GETDATE()) = 24
THEN 'Merry Christmas!'
ELSE ''
END
declare #dateString nvarchar(50) = '2018-12-20';
declare #text nvarchar(50);
If Convert(Date, GetDate()) = Convert(Date, dateString)
set #text = "This is it"
if(datepart(MONTH,GETDATE())=12 AND datepart(DAY,GETDATE())=24)
SELECT 'it is dec 24th'
else
SELECT ' '
--- you can use datename() instead of datepart() to get month as text 12>>december
If you are using SQL Server 2012 and above, below is a shorter and efficient script:
SELECT IIF(MONTH(GETDATE()) = 12 AND DAY(GETDATE()) = 24, 'Your Text', '')
You can use the FORMAT() function, available in SQL 2012 and newer:
SELECT CASE WHEN FORMAT(GETDATE(), 'MM-dd') = '12-24'
THEN 'ALMOST XMAS'
ELSE ''
END AS TEXT
Or combined with IIF():
SELECT IIF(FORMAT(GETDATE(), 'MM-dd') = '12-24', 'ALMOST XMAS', '') AS TEXT

Automate an SSIS query for a table name having a month and year timestamp

I have a database in which a table names are associated with month and year numbers ex: datavalues_7_2017 for july, datavalues_8_2017 for august and so on.
I am using a query to retrieve certain values from the table.
SELECT o_key ,MIN(dateadd(hour, datediff(hour, 0, time), 0)) as on_time
,MAX(dateadd(hour, datediff(hour, 0, dateadd(hour, 1, time)), 0)) as off_time
,cast(time as date) as RDNG_DT ,[repeated_hour],[value]
FROM [data_values_8_2017]
WHERE value = 1 and o_key in (X,X,X,X...) and cast(time as date) = cast(getdate() as date)
GROUP BY o_key,cast(time as date),repeated_hour,value
I am using SSIS package and using this query I am loading the result into another table.
Now this table datavalues_X_2017 is bound to change every month creating a new table, and my SSIS query should be pointing to the new table.
Can someone suggest me a way where I can automate this processes.
All you need to do is create a stored procedure as a wrapper and have a date parameter passed to it as shown below. Call this procedure as part of your source.
If you do not want it as stored procedure, use the same logic and put the sql as a variable and in the expressions pass the month and year variable
create procedure dbo.usp_GetData
(
#Date datetime = null
)
as
if #Date is null
set #Date = GETDATE()
declare #Month int
,#Year int
,#sql nvarchar(max)
select #Month = DATEPART(MONTH,#Date)
,#Year = DATEPART(YEAR,#Date)
set #sql ='
select o_key
,MIN(dateadd(hour, datediff(hour, 0, time), 0)) as on_time
,MAX(dateadd(hour, datediff(hour, 0, dateadd(hour, 1, time)), 0)) as off_time
,cast(time as date) as RDNG_DT
,[repeated_hour],[value]
from [data_values_'+CAST(#Month AS VARCHAR(2))+'_'+CAST(#Year AS VARCHAR(4))+']
where value = 1
and o_key in (
X,X,X,X...
)
and cast(time as date) = cast(getdate() as date)
group by o_key
,cast(time as date)
,repeated_hour
,value
';
exec sp_executesql #sql;
go
Get dynamic SQL with Variable Expressions the following way:
Create a String variable DateSuffux which will be filled with your datevalue like "7_2017"
Create a String variable SQLQuery with properties EvaluateAsExpression=true and define the following Expression for it
"SELECT o_key ,...,[repeated_hour],[value] FROM [data_values_" +
#[User::DateSuffix] + "] WHERE ... "
Specify variable SQLQuery as a source for your Data Source or SQL Query task
You are done.
This variable expression substitutes result of the expression when the SQLQuery variable is used. The expression itself injects contents of DateSuffix string variable into a query text.

Using GETDATE() in a WHILE loop always returns the same value

I understand from sources like this that GETDATE() should always (well, eventually, depending on how fast the loop is) return a different value in a loop.
I have this TSQL:
DECLARE #WaitUntilTime DATETIME = DATEADD(SECOND, 10, GETDATE())
WHILE (DATEDIFF(SECOND, GETDATE(), #WaitUntilTime) > 0)
BEGIN
SELECT GETDATE(), #WaitUntilTime
END
But it's always outputting the same value for GETDATE(), and the loop never ends after 10 seconds like I want it to. Why?
I also found this answer which sounds like a similar case, but it talks about GETDATE() being evaluated once for a column in a SELECT query. I don't know if that applies to a while-loop as well.
By the way, I know about WAITFOR but I can't use it because I want to introduce a delay within a single batch.
DECLARE #WaitUntilTime DATETIME = DATEADD(SECOND, 10, GETDATE())
DECLARE #Dummy int
WHILE (DATEDIFF(SECOND, GetDate(), #WaitUntilTime ) > 0)
BEGIN
Set #Dummy=1
END
SELECT GetDate(), #WaitUntilTime
Returns after a 10 second delay
(No column name) (No column name)
2016-10-18 13:53:20.000 2016-10-18 13:53:20.140

SQL- COUNT all Rows with WHERE condition in all tables in database

I need a query that COUNT all row´s (with WHERE condition) in all tables in a database, where the table_names are unknown.
Reason why is: I got a "alarm_logging_system" that creates a new "archive" table every month or so, and automatically names it "AlarmLog(timestamp of last active alarm)"
So I need a query which dynamically search through all tables that exists in the database, COUNTS all row in a column with WHERE condition, and return one single value.
In example I want to get all active alarms, this month, last month, etc. Or a specific time range.
This is an example of a query I wrote to get the count for all active alarms last month
SELECT COUNT(ConditionActive)
FROM (whole database)???
WHERE (Acked=0 AND ConditionActive = 1)
AND (EventTime >= DATEADD(m,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()), 0))
AND [EventTime] <= DATEADD(d,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0))))
AS ACTIVE_LAST_MONTH
So what I need is a query, stored_procedure or a dynamic SQL query?
All the tables have the same schema and columns.
Appreciate all help!
This should demonstrate why it is not generally considered a good practice to make multiple copies of the same table and then some aggregate data from the whole collection. This just isn't how relational databases are designed to work.
This is untested because I don't have your table anywhere to work with but this should get it.
declare #SQL nvarchar(max) = ''
--This get a result set of the count for all tables.
select #SQL = #SQL + 'select count(ConditionActive) as MyCount
from [' + t.name + ']
where Acked = 0
AND ConditionActive = 1
AND EventTime >= DATEADD(month, -1, DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0))
and [EventTime] <= DATEADD(day, -1, DATEADD(month, DATEDIFF(month, 0, GETDATE()),0)) UNION ALL'
from sys.tables t
--Now we need the sum of all counts
select #SQL = 'Select sum(MyCount) from (' + LEFT(#SQL, LEN(#SQL) - 10) + ') as x'
select #SQL
--uncomment the line below when you are confident that the dynamic sql is correct.
--exec sp_executesql #SQL
--EDIT--
I took the liberty of expanding the shortcuts in your DATEADD functions. The shortcuts are hard to remember and your were using both mm and m which both mean month. It is generally a better approach to just spell out the word to remove any ambiguity.

Using dynamic values in AS portion of an SQL Server query

I'm making a query (and a long, nasty bugger it is) to return dynamically updating values from an SAP system. I've got everything figured out but how to make the column headers what I want. They need to be the name of the previous 11 months and this month (or the 3 letter abbreviation).
Currently, I just have
SELECT ... AS [OCT]
for this month, but in two days it's going to be different, and I'd like to have the query auto-update the column headers each time it is run.
I figured out that I can use the variables I have declared to use in my functions to get the name three letter name of the month:
DECLARE #last_month DATE = DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 0, 0)
SELECT CONVERT(char(3), #last_month);
to return the selected month. How do I get this to be usable in the "AS" field?
Here is what I currently have:
DECLARE #last_two_months DATE = DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 1, 0)
DECLARE #last_month DATE = DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 0, 0)
SELECT (a whole mess of things that somehow work) AS [SEPT],
Table.CurrentTotal AS [OCT];
I'd like to replace [OCT] with something that will return OCT as the column header for the next two days and then return NOV for the next month, and similarly changing [SEPT] to something that will return SEP for the next two days, then return OCT for the next month.
Use Dynamic Query
DECLARE #last_month DATE = DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 0, 0),
#alias char(3),
#sql nvarchar(max)=''
SELECT #alias= CONVERT(char(3), #last_month);
set #sql = 'SELECT ... as ['+#alias+']..'
--Print #sql
exec sp_executesql #sql
Use the Print Statement to debug the dynamic query

Resources