SQL Trigger for Overlapping Dates - mysql

How can I create a trigger using the below code to stop overlapping dates in my booking table? Currently it's not working and i'm getting the following error.
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 'IF EXISTS
(SELECT *
FROM booking_requests
WHERE DateOfArrival <= NEW.' at line 3
CREATE TRIGGER date_overlap
BEFORE INSERT ON hotel_booking
IF EXISTS
(
SELECT *
FROM booking_requests
WHERE DateOfArrival <= NEW.DateOfDeparture
AND DateOfDeparture >= NEW.DateOfArrival
AND (RoomNumber != NEW.RoomNumber)
)
THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'overlapping date entries are not supported.';
END IF;

IF EXISTS (
... # this part looks about right, except for the last line, which
# you only need in the update trigger and should simply say:
AND (id != NEW.id)
) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'overlapping date entries are not supported.';
END IF;
Valid for MySQL Server 5.5 and later.
This needs to be in both a BEFORE INSERT and a BEFORE UPDATE trigger.
Multi-column indexes on both (date_start,date_end) and (date_end,date_start) will allow the optimizer the best chance of identifying conflicting rows quickly, since it can search via range on either column and scan the values in other from the index directly, using it as a covering index.

Related

Ambiguous error in creating BEFORE INSERT trigger

I have a Reservation table and am creating a BEFORE INSERT trigger that checks whether a user's reservation is already in the database, i.e. prevent him from making duplicate reservations. This is done to signal the front-end that the user is unable to make a duplicate reservation.
However, mySQL raises this error: ERROR 1064 (42000) at line 3: 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 '' at line 5. For some reason when the body between BEGIN and END is empty, it doesn't raise an error.
CREATE TABLE reservation (
customer_user_id integer,
date integer,
time integer,
name varchar(100)
);
CREATE TRIGGER trigger_name
BEFORE INSERT -- error raised in this line
ON reservation FOR EACH ROW
BEGIN
DECLARE sum INT;
SELECT COUNT(*)
INTO sum
FROM reservation r
WHERE (r.customer_user_id = new.customer_user_id)
AND (r.date = new.date)
AND (r.time = new.time);
IF sum = 0 THEN
INSERT INTO reservation values (new.customer_user_id, new.date, new.time, new.name);
ELSE
RAISE NOTICE 'duplicate'
END IF;
END;
Additionally, could this trigger be a constraint on the table Reservation? E.g. (customer_user_id, date, time) UNIQUE of sorts, which would prevent adding of duplicates, but I am clueless on how to "signal" the front-end which in turn prompts the user that they cannot add a duplicate reservation.
Sorry if some parts of the code might be weird, I'm new to SQL and was taught pSQL.
Thanks in advance!

Syntax errors when trying to write MySQL trigger to substitute CHECK constraint on phpmyadmin

I'm trying to make a MySQL trigger that would act as a CHECK constraint since it is not supported in the version of MySQL I am using.
Basically I am doing a database for a library, where table bookloan is a record of all loans that have ever been made.
bookloan has 4 columns:
- borrowerNo: Id of the borrower
- copyNo: Id of the book that was rented
- dateOut: Date the book was rented
- dateDue: Date the book is due, always 14 days after dateOut
I am trying to make a restriction where a borrower can't rent more than 3 books at the same time. Here's my code for the trigger:
CREATE TRIGGER maxbooks
BEFORE INSERT OR UPDATE
ON bookloan FOR EACH ROW
BEGIN
IF COUNT(SELECT * FROM bookloan WHERE borrowerNo = NEW.borrowerNo AND dateOut <= NEW.dateOut AND dateDue > NEW.dateOut) >= 3 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Maximum number of book rentals has been reached';
END IF;
END;
Here's the error message I am getting from MySQL:
#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 'IF COUNT(SELECT * FROM bookloan WHERE borrowerNo =
NEW.borrowerNo AND dateOut <=' at line 4
I'm guessing the error is from the Count() function, but do not know how I could format it so that I get the information that I want.
Thanks!
Try using count(*) instead of using it on query results returned. Just like below:
CREATE TRIGGER maxbooks
BEFORE INSERT OR UPDATE
ON bookloan FOR EACH ROW
BEGIN
IF (SELECT COUNT(*) FROM bookloan WHERE borrowerNo = NEW.borrowerNo AND dateOut <=
NEW.dateOut AND dateDue > NEW.dateOut) >= 3 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Maximum number of book rentals has been reached';
END IF;
END;

Error for before insert or update on

I am a new to queries in dbms, so If someone could figure out what should be done here. Also, I am using Mysql.
code:
-> create trigger age_trigger before insert or update of age on employee
-> for each row
-> when( new.age <25)
-> begin
-> select 'Age can not be less than 25'
-> end;
error:
ERROR 1064 (42000): 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 'or update of age on employee for each row when(
new.age <25) begin select 'Age c' at line 1
You can't just come up with your own syntax :)
Have a look at the manual: CREATE TRIGGER Syntax
You can't specify multiple trigger_events. You need separate insert and update triggers. And this of age also has no business there.
All in all, what you're trying to do there can be done in MySQL (google for SIGNAL, if you insist), but best practice is, that this sort of logic is placed in the application layer. Don't put such logic in the database.
Below can be one of the option to implement BEFORE INSERT to obtain your desired result.
CREATE TRIGGER age_trigger
BEFORE INSERT ON table1
FOR EACH ROW
BEGIN
IF NEW.age < 25
THEN SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Age can not be less than 25';
END IF;
END;
Similar syntax can be used for before update trigger.
DEMO

MySQl I need to make a column unique only for certain values of another column

I have two columns Name,IsDelete in a table T
There can only be unique names for IsDelete=0
For IsDelete=1, there can be duplicate names.
I'm using this query
CREATE UNIQUE INDEX ix ON T(Name) WHERE IsDelete = 0;
But I'm getting the error,
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 'WHERE IsDeleted = 0 at line 1
How can I use triggers to solve this?
Unique indices must have references to ALL RECORDS.
They cannot be conditional creation of unique index construction.
The requirement you set could be covered by another table structure where the deleted or not is not part of the record.
You must redesign the data to use a master table with unique IDs and alter the current to link to the master table.
It is a basic theoretical lesson in data normalisation.
Yeah, so I got a trigger that would check for the condition to be true.
DELIMITER $$
CREATE TRIGGER testing4
BEFORE INSERT ON biomitra_user
FOR EACH ROW BEGIN
IF EXISTS (select mobile_number from biomitra_user where is_deleted=0) THEN
SIGNAL SQLSTATE '02000' SET MESSAGE_TEXT = 'Duplicate';
else
set new.mobile_number=new.mobile_number;
END IF;
END$$
DELIMITER ;
This is working fine

Ensuring String inequality in MySQL

I have a MySQL table called flights that includes fields called origin and destination which are the airport codes referenced from the airports table and which i have defined as CHAR(3). I want to be able to insert records where for obvious reasons the values in the origin and departure columns cannot be the same.
How do i accomplish this with an INSERT INTO TABLE SQL statement?
The only way you can do this in MySQL is using a trigger.
Other databases support a check constraint where you can say check (origin <> destination). MySQL accepts this syntax but unfortunately does not enforce the constraint.
You can also do this at the application layer.
Create a trigger:
CREATE TRIGGER `travels_before_insert` BEFORE INSERT ON `travels` FOR EACH ROW BEGIN
DECLARE msg VARCHAR(255);
IF NEW.source=NEW.destination THEN
set msg = "Error: You can't have same source and destination";
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg;
END IF;
END;
What it does is prevent the insert from occuring if source and destination are the same.