MySql stored procedure to update the database record - mysql

I hasn't been writing any MySql stored procedures before, so I don't know them at all. I have one database table which has some records in it. The main column is dateTime - when this record was saved in the database.
I have wrote the MySql stored procedure to select every record from the specified date:
CREATE PROCEDURE getMessages(IN dateFrom DATETIME)
SELECT * FROM EsbMessage WHERE dateTime <= dateFrom;
And this is the call:
CALL getMessages('2012-10-04 13:11:09');
This works correctly, it returns me the records from the specified date.
What I need to do is:
If the record is over one week old, I need to update the other
column.
If the record is over one year old, I need to delete that record.
I can easily do this programmatically, but in this case I have to do this using stored procedure.
So I'am thinking of something like this:
CREATE PROCEDURE updateMessages(IN dateFrom DATETIME)
BEGIN
SELECT * FROM EsbMessage WHERE dateTime <= dateFrom;
#for each message
#if the message is over one week old but not over one year old:
UPDATE EsbMessage SET body = '';
#if message is over one year old:
DELETE FROM EsbMessage WHERE dateTime = #message.dateTime
END
But I don't know how to use for loop in stored procedure, and how to write if statements depending on my requirements and the other thing I don't now how to count the dates in MySql. For e.g. If I have the current date then I need to subtract the 365 days from the current date.
Could somebody help me with this issue?

You wouldn't need a loop, just have your conditions in the WHERE clause:
#if the message is over one week old but not over one year old:
UPDATE EsbMessage SET body = ''
WHERE dateTime >= DATE_SUB(NOW(),INTERVAL 1 WEEK) AND dateTime <= DATE_SUB(NOW(),INTERVAL 1 YEAR);
#if message is over one year old:
DELETE FROM EsbMessage WHERE dateTime >= DATE_SUB(NOW(),INTERVAL 1 YEAR);

How to loop and to use if clauses is described here: http://www.mysqltutorial.org/stored-procedures-loop.aspx
I would do it without loops:
CREATE PROCEDURE updateMessages(IN dateFrom DATETIME)
BEGIN
UPDATE EsbMessage SET body = '' where dateTime <= dateFrom -(86400*7); //86400 = 1 day
#if message is over one year old:
DELETE FROM EsbMessage where dateTime <= dateFrom -(86400*365);
END

Related

SQL query to select row where current date and time is between fields start and end

I have an SQL table containing fields with date and time with columns start and end as DateTime.
What I want is a query that will select the row where the current date and time is between the value of start and end fields plus the type is WE.
Example:
If current date and time is 2022-05-18 15:30:00, row number 39 should be displayed as a result.
So far, this is the code I came up with but it returns zero result:
select * from `examdates` where (NOW() between `start` and `end`) and `type`='WE'
I also tried some answers I found in this forum like
select * from `examdates` where NOW() >= `start` and NOW() <=`end` and `type`='WE'
but result is still
Thanks!
Test this:
SELECT *
FROM `examdates`
WHERE CONVERT_TZ(NOW(), ##time_zone, '+00:00') BETWEEN `start` AND `end`
and `type`='WE'
The function retrieves server timezone info from session variable and converts the server local datetime to GMT time zone. If the values in the table are ones of some another timesone then adjust 3rd function parameter accordingly.
See https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=b054129c8210336d70b6f0a4ecc50b5d

Looking for MySQL Default yesterday date

I am using MySql via terminal. Below is the command I have used to create table but it is showing date in YYYY-MM-DD HH:MM:SS (example: 2018-05-25 14:12:47)
create table test (foo int, ts timestamp default CURRENT_TIMESTAMP);
But I want by default it take yesterday date every time I insert data in (YYYY-MM-DD) format.
Please help me to find the command.
Thanks,
Amit
According to the official MySQL documentation https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-add, you can do like this:
If you want to store the "yesterday" on creation:
ts TIMESTAMP NOT NULL DEFAULT NOW() - INTERVAL 1 DAY
If you want to store the "yesterday" on every update:
ts TIMESTAMP NOT NULL DEFAULT NOW() ON UPDATE NOW() - INTERVAL 1 DAY
According to this answer Select records from NOW() -1 Day:
NOW() returns a DATETIME.
And INTERVAL works as named, e.g. INTERVAL 1 DAY = 24 hours.
So if your script is cron'd to run at 03:00, it will miss the first
three hours of records from the 'oldest' day.
To get the whole day use CURDATE() - INTERVAL 1 DAY. This will get
back to the beginning of the previous day regardless of when the
script is run.
Hope it helps!
DEFAULT values in MySQL must be constants. They can't be functions or expressions (with the exception of CURRENT_TIMESTAMP).
Source: http://dev.mysql.com/doc/refman/5.6/en/data-type-defaults.html
In addition you can add a trigger to your table for your requirement
Simply Create a Table without constraint
create table test (foo int, ts timestamp );
Then add a trigger to this table
CREATE TRIGGER settime
BEFORE INSERT on test
FOR EACH ROW BEGIN
IF new.`ts ` is null THEN
SET new.`ts ` = DATE_ADD(NOW(), INTERVAL -1 DAY);
END IF;
END;

mysql stored procedure doesn't work for the last day of month

I am on a MySQL DB. I have a scheduled event that calls a procedure every night and inserts some data based on the previous day in a table.
All works fine except for the last day of a month. The procedure delivers an empty set. I have tried to run the procedure also without scheduling, and I get an empty set as well. So I think there is something fishy in the procedure itself (how I define "datum" aka date f.e.), not in the scheduling. Any ideas fix this or do it right? THANKS!
| data | |
CREATE DEFINER=`developer`#`localhost` PROCEDURE `data`(p_start_date DATE, p_end_date DATE)
BEGIN
DECLARE datum DATE;
SET datum = p_start_date;
WHILE datum < p_end_date DO
INSERT INTO DB_name.table_name select ... where ... and a.entrydate>=datum - 1 and a.entrydate<datum group by date(a.entrydate);
SET datum = DATE_ADD(datum, INTERVAL 1 DAY);
END WHILE;
END | utf8 | utf8_general_ci | utf8_general_ci |
a.entrydate>=datum - 1? Since datum is a date, you're going to end up with a float for that result, e.g. select now()-1 comes back as 20140303090955.0000.
perhaps you want
... where ... and a.entrydate >= (datum - INTERVAL 1 DAY)
instead.

How to calculate date using interval from table

I have a table with a start_date, end_date and an interval. I would like to update end_date with the value of start_date and the interval.
create table date_test (
start_date date,
end_date date,
date_interval varchar(45)
);
The values I am using for date_interval are like - INTERVAL 1 WEEK, + INTERVAL 1 MONTH.
I would like to do something like:
UPDATE date_test SET end_date = date( concat( start_date, " ", date_interval));
but I get this warning:
1292 Truncated incorrect date value: '2012-01-01 - INTERVAL 1 week'
How can I force this date to get evaluated before updating?
Jonathan Leffler said :
Nearly; there's a crucial difference between the manual page and the question, though. The manual discusses DATE_ADD(date_value, INTERVAL '1' DAY) etc, whereas the question would be having a 'string' value as the second parameter. I fear the question would need a function to convert the string into an INTERVAL type. There doesn't appear to be a 'TO_INTERVAL' function in MySQL.
Here is a function that will take the date as first parameter and the string interval as second parameter.
Simply add the following stored procedure to your database :
CREATE PROCEDURE my_date_add(d DATE, i VARCHAR(50))
BEGIN
DECLARE sign CHAR(1);
DECLARE x INT;
SET sign = SUBSTRING_INDEX(i, ' ', 1);
SET x = SUBSTRING_INDEX(SUBSTRING_INDEX(i, ' ', -2), ' ', 1);
IF sign = '-' THEN
SET x = -x;
END IF;
CASE SUBSTRING_INDEX(i, ' ', -1)
WHEN 'DAY' THEN SELECT DATE_ADD(d, INTERVAL x DAY);
WHEN 'WEEK' THEN SELECT DATE_ADD(d, INTERVAL x WEEK);
WHEN 'MONTH' THEN SELECT DATE_ADD(d, INTERVAL x MONTH);
END CASE;
END
Then you should be able to update your table like this :
UPDATE date_test SET end_date = my_date_add(start_date, date_interval);
What you want to do is :
UPDATE date_test SET end_date = DATE_ADD(start_date, date_interval);
But I'm not sure that using date_interval as the second parameter will work, tell us if it does.
You will find a lot of useful examples in the MySQL documentation, see DATE_ADD() function description.
MySQL does not support values evaluating. So, you cannot use an UPDATE statement directly.
In this case I'd suggest you these ways:
Write a SELECT...INTO OUTFILE statement that would generate a list of UPDATE statemants and output all this statements into the file, then just run this sript.
Or write a stored procedure that would open a cursor on date_test table, in a loop generate and execute UPDATE statements for each record, one by one, using prepared statements.
Ask, if you have a questions about the solutions.

Compare datetime in stored procedure

I have a sql 2008 database and I am creating a stored procedure that shall check if a datetime is more than 3 hours old but I don't know how to do it.
Do you have some way to do it?
the datetime is a field in the table.
BR
Rather than applying DATEDIFF to the column value, which will negate an index, I suggest using a comparison of the column to an expression (which can use an index).
If you want this as a filter:
SELECT columns
FROM dbo.table
WHERE DateTimeColumn < DATEADD(HOUR, -3, CURRENT_TIMESTAMP);
(If you want only the rows that are newer than 3 hours old, change < to > or >=.)
If you want to return all rows with a column showing whether it is more than 3 hours old:
SELECT columns, [3HoursOld] = CASE
WHEN DateTimeColumn < DATEADD(HOUR, -3, CURRENT_TIMESTAMP)
THEN 'Yes, older than 3 hours.'
ELSE 'No, not older than 3 hours.'
END
FROM dbo.table;
Take at look at the DATEDIFF function.
DATEDIFF ( datepart , startdate , enddate )
You would then use with datepart set to hh and the enddate set to the current time. To get the current database time you could use GETDATE(). Compare the result with 3 since it will return the number of hours passed.
#date is the date you want to compare
declare #date datetime
set #date= '2012-02-15 14:20:42.797'
SELECT DateDiff(hh, DATEADD(hh,-3,#date), GETDATE()) --if it's > 3
you better create a Boolean function that does the trick that you can use where ever you like