Compare time values correctly - mysql

I am having trouble comparing MySQL Time fields, I have a NOEVENTS row starting from 09:00 to 10:00 and I am trying to insert a row into another table, but I need to compare the NOEVENTS time, to the incoming Time fields. example:
I want to insert a event from 09:15 to 09:30, and another from 10:00 to 11:00, so how can I compare that? im trying this:
select count(idNOEVENTS) into existNOEVENT from NOEVENTS b where eventInitialTime && eventFinalTime between b.initialTime and b.finalTime;
if existNOEVENT>0
SET MESSAGE_TEXT = 'Error! no events allowed at this time';
The problem is when I try to insert the 09:15 to 09:30, it throws the error message shown above. Thats fine, it works, but when I try to insert the 10:00 to 11:00 event it throw the msg, and it shouldnt, how can I fix it? or compare it better?
Thanks, and sorry for my poor english.

You can do it this way
SELECT *
FROM noevents
WHERE (? > initialTime AND ? < finalTime)
OR (? > initialTime AND ? < finalTime)
Now don't use COUNT(*) to check for existence of a row(s). Use EXIST() instead.
That being said to give an idea this how you procedure code might look like
DELIMITER $$
CREATE PROCEDURE add_event(IN _start TIME, IN _end TIME)
BEGIN
IF EXISTS(SELECT *
FROM noevents
WHERE (_start > initialTime AND _start < finalTime)
OR (_end > initialTime AND _end < finalTime)) THEN
SIGNAL sqlstate '45000'
SET message_text = 'Error! no events allowed at this time';
ELSE
-- Do whatever you have to do to insert an event
SELECT 'Success: event added';
END IF;
END$$
DELIMITER ;
Here is SQLFiddle demo

Related

MySQL procedure to update a price based on a date change

I am trying to write a procedure that update the the content in one column, based a change in date is more than 20 days. In context, the procedure decreases the price of a good if the time passed since acquired is more than 20 days.
I am using the DATEDIFF function as well as GETDATE() statement but I am really strugling. At this point I am stucked.
Can anybody tell what is wrong with my sql code?
DELIMITER //
CREATE PROCEDURE UPDATE_PRICE
DECLARE #TIMEPASSED AS TIME
SET #TIMEPASSED = GETDATE()
BEGIN
UPDATE sales SET sales.SalesPrice = sales.SalesPrice - 30
WHERE DATEDIFF(#GETDATE(), Sales.AcquisitionDate;
END;;
Any help on this one would be much appreciated
Variable declarations should be in the BEGIN/END block, but they are not really needed in this case. GETDATE() is not a MySQL function. So:
DELIMITER //
CREATE PROCEDURE UPDATE_PRICE
BEGIN
UPDATE sales s
SET s.SalesPrice = s.SalesPrice - 30
WHERE s.AcquisitionDate < CURDATE() - INTERVAL 20 day;
END;
DELIMITER ;
Try this:
DELIMITER //
CREATE PROCEDURE UPDATE_PRICE
DECLARE #TIMEPASSED AS TIME
SET #TIMEPASSED = GETDATE()
BEGIN
UPDATE sales SET sales.SalesPrice = sales.SalesPrice - 30
WHERE DATEDIFF(#GETDATE(), Sales.AcquisitionDate) > 20;
END;

SQL PROCEDURE ISSUE,not sure on placement of data

Write a stored procedure that updates the weekly duty roster for an employee and allocates him/her a maximum of 5 work shifts in a given branch. To update the roster, the procedure ensures that:
i. The employee has an existing roster allocated to her/him. In case there is no existing roster for a given employee, the procedure doesn’t update the roster, rather prints an appropriate error message.
ii. The day of current roster is shifted by one day in the updated roster. For instance, if the current roster for an employee shows work shifts from Monday to Friday, then the updated roster will allocate work shifts from Tuesday to Saturday. For simplicity, we will assume that the type and number of work shifts allocated to an employee remain
same from week to week unless an exception occurs such as overallocation. However, the manager may wish to add any extra work shifts to an employee manually.
iii. A warning message is displayed in case the allocated hours of work for an employee exceeds the standard hours of work (35 hours per week).
any help is appreciated having a lot of trouble getting this right.. MYSQL
DELIMITER //
DROP PROCEDURE IF EXISTS updateRoster
CREATE PROCEDURE UpdateWeeklyRoster (IN e CHAR(8), IN b INT)
BEGIN
-- variable declaration
DECLARE WORKING_HOURS INT(35);
DECLARE Updated_Working_Shift_ID INT;
-- cursor declaration
DECLARE c1 CURSOR FOR
EmployeeID,BranchID,WorkingShiftID;
DECLARE CONTINUE HANDLER FOR NOT FOUND set finished = 1;
-- check whether the employee exists or not
SELECT EmployeeID into e
FROM DutyRoster
WHERE EmployeeID = e;
IF e IS NULL THEN
SIGNAL SQLSTATE '45000' set MESSAGE_TEXT = 'THERE IS EXISTING ROSTER';
ELSE
-- actual part
-- delete existing tuples relevant to the given employee and branch id from the Duty Roster table
OPEN c1;
-- execute a loop
REPEAT
FETCH c1 into .... , ....., .....;
-- find the workingShiftWeekDay: assign appropriate values into Current_Week_Day
-- Find the Updated_Week_Day
SET Updated_Week_Day =
CASE Current_Week_Day
WHEN Week_day='MONDAY' THEN Updated_Week_Day='TUESDAY';
WHEN 'TUESDAY' THEN 'WEDNESDAY';
WHEN 'THURSDAY' THEN 'FRIDAY';
WHEN 'FRIDAY' THEN 'SATURDAY';
WHEN 'SATURDAY' THEN 'SUNDAY';
WHEN 'SUNDAY' THEN 'MONDAY';
ELSE .....
END CASE;
-- Find the current_duty_type
-- for the updated_week_day, find an appropriate working shift id
SELECT dutyType into WorkingShiftID
FROM WorkingShift
WHERE EmployeeID AND dutyType = CurrentDutyType;
-- insert the new record
INSERT INTO DutyRoster VALUES (e,b,Updated_Working_Shift_ID);
UNTIL ........;
END REPEAT;
CLOSE c1;
-- Checking whether an employee works for more than 35 hours
SELECT HOUR(TIMEDIFF(WorkingShiftEndTime,WorkingShiftStartTime)) INTO TOTAL, WORKING_HOURS
from WorkingShift, DutyRoster
WHERE DutyRoster, WorkingShiftID = WorkingShift, WorkingShiftID
AND EmployeeID = e;
IF TOTAL, WORKING HOURS > 35 THEN
SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = 'Employee is working over 35 hours....';
END IF;
END IF;
END
DELIMITER ;
DELIMITER //

Mysql trigger no error message but code not working

I wrote this trigger in phpMyAdmin
BEGIN
DECLARE start DATETIME;
DECLARE now DATETIME;
DECLARE date DATETIME;
SELECT `starting` INTO start FROM events WHERE events.id = NEW.event_id;
SET now = NOW();
SET date = CURDATE();
IF start > now THEN
IF DATE(start) = date THEN
SET #hours = HOUR(start - now);
IF #hours <= 1 THEN
SET #text = 'in less than an hour';
ELSE
SET #text = CONCAT('in about ', #hours, ' hours');
END IF;
INSERT INTO notifications (user_id, subject, action_id, data, seen, activates)
VALUES (NEW.user_id, NEW.event_id, 2, CONCAT('{"period":"', #text, '"}'), 0, now);
ELSE
INSERT INTO notifications (user_id, subject, action_id, data, seen, activates)
VALUES
(NEW.user_id, NEW.event_id, 2, '{"period":"tomorrow"}', 0, DATE(start - INTERVAL 1 DAY)),
(NEW.user_id, NEW.event_id, 2, '{"period":"in one hour"}', 0, start - INTERVAL 1 HOUR);
END IF;
END IF;
END
The purpose of it is to create notifications about a starting event when a user submits that he is going to be attending an event. The trigger works if the event is not today, but if the event is today I get this message
Column data cannot be NULL
Column data is in table notifications. If the event is set to start today I get column data cannot be NULL, if the event is further in future, like tomorrow I get accurate message.
Any help is greatly appreciated!
There was something wrong with this bit of code
HOUR(start - now)
I replaced it with
HOUR(TIMEDIFF(start - now))
Now everything works as expected.
I got to solve the problem with Marc B's help for which I thank him and everyone else who commented!

How to set up a WHILE loop with IF statement in MySQL?

I would like to create a stored routine for MySQL that figures out the number of business or working days for a month (Working Days are Monday thru Friday).
It's a syntax error however I don't know what the syntax error is. All it tells me is:
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use
near 'WHILE(#daycount < #totaldays) DO IF (WEEKDAY(#checkweekday) < 6)
THEN ' at line 2
My Syntax Error is in the following:
WHILE(#daycount < #totaldays) DO
IF (WEEKDAY(#checkweekday) < 6) THEN
My Code:
SELECT MONTH(CURDATE()) INTO #curmonth;
SELECT MONTHNAME(CURDATE()) INTO #curmonthname;
SELECT DAY(LAST_DAY(CURDATE())) INTO #totaldays;
SELECT FIRST_DAY(CURDATE()) INTO #checkweekday;
SELECT DAY(#checkweekday) INTO #checkday;
SET #daycount = 0;
SET #workdays = 0;
BEGIN
WHILE(#daycount < #totaldays) DO
IF (WEEKDAY(#checkweekday) < 6) THEN
SET #workdays = #workdays+1;
END IF;
SET #daycount = #daycount+1;
SELECT ADDDATE('#checkweekday', INTERVAL 1 DAY) INTO #checkweekday;
END WHILE;
END;
SELECT #workdays;
Is someone able to assist?
UPDATE
I receive the same error with the following bit of code so it probably has something to do with this:
SET #workdays = 0;
IF (WEEKDAY('2013-06-13') < 6) THEN
SET #workdays = #workdays+1;
END IF;
SELECT #workdays;
I have discovered that you cannot have conditionals outside of the stored procedure in mysql. This is why the syntax error. As soon as I put the code that I needed between
BEGIN
SELECT MONTH(CURDATE()) INTO #curmonth;
SELECT MONTHNAME(CURDATE()) INTO #curmonthname;
SELECT DAY(LAST_DAY(CURDATE())) INTO #totaldays;
SELECT FIRST_DAY(CURDATE()) INTO #checkweekday;
SELECT DAY(#checkweekday) INTO #checkday;
SET #daycount = 0;
SET #workdays = 0;
WHILE(#daycount < #totaldays) DO
IF (WEEKDAY(#checkweekday) < 5) THEN
SET #workdays = #workdays+1;
END IF;
SET #daycount = #daycount+1;
SELECT ADDDATE(#checkweekday, INTERVAL 1 DAY) INTO #checkweekday;
END WHILE;
END
Just for others:
If you are not sure how to create a routine in phpmyadmin you can put this in the SQL query
delimiter ;;
drop procedure if exists test2;;
create procedure test2()
begin
select ‘Hello World’;
end
;;
Run the query. This will create a stored procedure or stored routine named test2. Now go to the routines tab and edit the stored procedure to be what you want. I also suggest reading http://net.tutsplus.com/tutorials/an-introduction-to-stored-procedures/ if you are beginning with stored procedures.
The first_day function you need is:
How to get first day of every corresponding month in mysql?
Showing the Procedure is working
Simply add the following line below END WHILE and above END
SELECT #curmonth,#curmonthname,#totaldays,#daycount,#workdays,#checkweekday,#checkday;
Then use the following code in the SQL Query Window.
call test2 /* or whatever you changed the name of the stored procedure to */
NOTE: If you use this please keep in mind that this code does not take in to account nationally observed holidays (or any holidays for that matter).

Whats wrong with this short procedure (MySQL)

Im trying to make a procedure, which will be checking if user is already logged (he got a session, and im checking if his last action was over 15 minutes ago). My procedure looks like this:
CREATE PROCEDURE `isLogged`(in p_sessid VARCHAR(32), out res INT(1))
BEGIN
DECLARE v_customer_id INT(9);
DECLARE v_date DATE;
SELECT customer_id INTO v_customer_id FROM Sessions WHERE sessid=p_sessid;
SELECT expiry_date INTO v_date FROM Sessions WHERE sessid=p_sessid;
SET res=3;
IF v_customer_id > 0 THEN
IF UNIX_TIMESTAMP(NOW()) > UNIX_TIMESTAMP(v_date) THEN
DELETE FROM Sessions WHERE sessid=p_sessid;
SET res=1;
ELSE
UPDATE Sessions SET expiry_date=DATE_ADD(NOW(), INTERVAL 15 MINUTE) WHERE customer_id=v_customer_id;
SET res=0;
END IF;
END IF;
END
Can anyone tell, why it always return 1, what means that user is not logged anymore? I were checking manually expression UNIX_TIMESTAMP(NOW()) > UNIX_TIMESTAMP(v_date), and it gives me 0 in response, so? Whats going on?
Thanks in advance,
Marcin
The first IF statement should read like this:
UNIX_TIMESTAMP(NOW()) > UNIX_TIMESTAMP(DATE_ADD(v_date, INTERVAL 15 MINUTE))
or else NOW will always be greater than the last login date.
You may rewrite/optimize your procedure to function. For example -
CREATE FUNCTION `isLogged`(IN p_sessid VARCHAR(32))
RETURNS INT
BEGIN
DELETE FROM Sessions WHERE sessid = p_sessid AND v_date <= NOW() - INTERVAL 15 MINUTE;
IF ROW_COUNT() > 0 THEN -- check how many rows were deleted
RETURN 1;
ELSE
UPDATE Sessions SET expiry_date = NOW() + INTERVAL 15 MINUTE WHERE customer_id = v_customer_id;
IF ROW_COUNT() > 0 THEN -- check how many rows were updated
RETURN 0;
END IF;
END IF;
RETURN 3;
END
Also, you can try to debug your code to understand the error.
Omg, that was very stupid.
There was a type mismatch. v_date type was a DATE, and this is just a day! Like 2011-12-14.
Solution:
change DATE -> DATETIME.
And now everything works good.
Anyway, thank you for answers.