Problems with triggers and constraints in mysql with phpmyadmin - mysql

I keep having error messages and i'm not sure what i'm doing wrong.
This is the class restaurant:
Restaurant (IdRestaurant, NameRest, Telephone, Address, Forks, NameCity, TypeCooking)
The objective is not allow restaurants with Forks that are not in the interval [1,5]
CREATE TRIGGER CorrecF
BEFORE INSERT ON Restaurant
FOR EACH ROW
BEGIN
IF (5 < new.Forks AND new.Forks < 1) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Forks have to be between 1-5';
END IF;
END;
Another one will be not allowing inserts of Offers that have a date less than 2 weeks from NOW().
Offer (IdOffer, Coffee, Drink, Date, Price, IdRest, Time_Zone)
CREATE TRIGGER CorrectDate BEFORE INSERT ON Offer
FOR EACH ROW IF (DATE_ADD(NOW(), INTERVAL 2 WEEK) > new.Date) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Date have to be minimum 2 weeks from now';
END IF;
END;

You don't appear to be setting delimiters see Delimiters in MySQL and your second trigger (like the first) has compound statements see https://dev.mysql.com/doc/refman/8.0/en/begin-end.html so begin..end is required

Related

Can't create MySQL Trigger with several tables

I've got a database with 3 tables:
delivery
company
details
The company table has a column with ratings from 1 to 10 and if a rating is more than 5 we can understand that this company is reliable and in detail if the price is more than 1000 it is expensive detail.
Table delivery is connecting table for company and details Now I'm trying to create a trigger that will block Insert when somebody trying to add in table delivery expensive detail with an unreliable company, but I can't understand how to create Trigger using data from different tables.
I'm using MySQL
DELIMITER //
CREATE TRIGGER before_insert_1
BEFORE INSERT
ON delivery
FOR EACH ROW
IF company.rating < 5 AND detail.Det_Price > 1000 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Unreliable company';
END IF //
DELIMITER ;
You should review https://dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html paying particular attention to the discussion of NEW. values.
A simple version of the trigger might be like
DELIMITER //
CREATE TRIGGER before_insert_1
BEFORE INSERT
ON delivery
FOR EACH ROW
begin
declare vrating int;
declare vprice int;
select company.rating into vrating from company where company.id = new.company_id;
select detail.det_price into vprice from detail where detail.? = new.?;
IF vrating < 5 AND vPrice > 1000 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Unreliable company';
END IF ;
end //
DELIMITER ;
but since you didn't publish table definitions I can't tell you exactly how the selects should be.

How can I correctly format my SQL trigger?

For some background this is part of an assignment for my Databases class. We have a set of tables that all entail towards Company information. This includes WORKS_ON which shows the hours that Employees work on specific projects. The goal of my code was to write a trigger that prevents a user from assigning more than 40 hours of total work to one employee. I intended to do this via obtaining the sum of hours that are currently in the table associated with the new row's Employee SSN(Essn). From there I meant to add the sum to the new row's hours and compare to 40. If the amount was more than 40, then a custom message is concatenated and an error is raised to the user. The professor included PHP which handles the printing of that error for me. As of now the only potential fix/error I can think of is that it is not legal to perform arithmetic within the if statement. Please let me know if you see anything I need to fix/improve.
DELIMITER &&
CREATE TRIGGER MAXTOTALHOURS
BEFORE INSERT ON WORKS_ON FOR EACH ROW
BEGIN
DECLARE sumHours integer;
DECLARE customMessage VARCHAR(100);
SELECT SUM(hours) INTO sumHours FROM WORKS_ON WHERE Essn = New.Essn;
IF (sumHours + New.hours > 40) THEN
SET customMessage = concat('You entered', New.hours, '. You currently work ', sumHours, '. You are over 40 hours!');
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = customMessage;
END IF;
END &&
DELIMITER ;

How to structure an if exists query to produce an error message

I have created a procedure which I am using to insert new columns into a table, and I have done an IF statement to basically say that if the date entered is before current date or not at least 30 days in the future then throw an error, now I want to create an IF statement that will only insert a new column if one of the rows exists... there are only three possible courses that are in the table so the procedure asks for a course code and a date, can someone push me in the right direction for how to structure my IF statement to give an error when one of the three codes are not entered?
I don't know what keywords to use.
Here is my IF statement for the date checking:
IF (give_date < DATE_ADD(CURDATE(), INTERVAL 1 MONTH)) OR (give_date <= CURDATE()) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Please Enter A Date Over One Month';
ELSEIF (WEEKDAY(give_date) = 5 )THEN SET loop_date = DATE_ADD(give_date, INTERVAL 2 DAY);
ELSEIF (WEEKDAY(give_date) = 6 )THEN SET loop_date = DATE_ADD(give_date, INTERVAL 1 DAY);
ELSE SET loop_date = give_date;
END IF;
I am trying to do something like this...
IF (new_code, EXISTS IN (module (course_code)) THEN
SIGNAL SQLSTATE '45000'SET MESSAGE_TEXT = 'Please Check Entered Course And Try Again';
END IF;
Also tried doing this but getting an error saying the subquery returns more than one row...
IF give_code != ( SELECT course_code FROM module WHERE course_code = ('WSD' OR 'DDM' OR 'NSF'))THEN
SIGNAL SQLSTATE '45000'SET MESSAGE_TEXT = 'Please Check Entered Course And Try Again'; END IF;
Got it working by doing it like this:
IF give_code NOT IN ( SELECT course_code FROM module WHERE course_code = ('WSD' OR 'DDM' OR 'NSF'))THEN
SIGNAL SQLSTATE '45000'SET MESSAGE_TEXT = 'Please Check Entered Course And Try Again'; END IF;
Does it work for you?
IF ( SELECT count(*) FROM module WHERE course_code in ('WSD','DDM','NSF')) > 0
THEN
SIGNAL SQLSTATE '45000'SET MESSAGE_TEXT = 'Please Check Entered Course And Try Again';
END IF;

How to fix Syntax Error in DATEDIFF trigger

Can anyone see what is wrong with this code?
Everything was working fine until I added the trigger to calculate the difference between two dates. First of all I altered the table just incase anyone wondered.
ALTER TABLE bookings
ADD COLUMN TheDuration varchar(10);
Then my triggers are as follows...
DELIMITER //
CREATE TRIGGER check_licence /*This trigger will approve customers with a valid licence */
BEFORE UPDATE ON customers
FOR EACH ROW
BEGIN
SET NEW.Status = CASE WHEN NEW.valid_licence = 'Yes'
THEN 'Approved'
ELSE 'Unapproved' /*So if a Customer has a valid licence, He will be automatically approved. */
/*But if he doesn't he will become unapproved[WORKING]*/
SET NEW.TheDuration = DATEDIFF(NEW.bookings.end_date, NEW.bookings.start_date) -- -- TO CALCULATE DURATION BETWEEN 2 DATES
END;
//
DELIMITER ;
The problem lays within
SET NEW.TheDuration = DATEDIFF(NEW.bookings.end_date, NEW.bookings.start_date) -- -- TO CALCULATE DURATION BETWEEN 2 DATES
As everything was working before I added this.
Same here...
DELIMITER //
CREATE TRIGGER Carperperson /* This Trigger Blocks a customer from renting two cars on the same name twice on one day. */
BEFORE INSERT ON bookings /*E.g. Mr.ABC cannot rent a Ford and a Nissan on the same day. Has to return first car first.[WORKING]*/
FOR EACH ROW
BEGIN
IF EXISTS (
SELECT 1
FROM bookings
WHERE NEW.customer_id = bookings.customer_id
AND ((new.start_date >= bookings.start_date
and new.start_date < bookings.end_date)
or (new.end_date > bookings.start_date
and new.end_date < bookings.end_date))
) THEN
SIGNAL SQLSTATE '45000'
set message_text='You can only book one car per single customer a day!' ; /* This triggers only allows to rent a car for 7 days, not more, not less[WORKING]*/
END IF;
IF ( NEW.end_date > NEW.start_date + INTERVAL 7 DAY ) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = '7 is the maximum. Please choose an earlier date.'; /*The end_date is more than seven days after start_date*/
END IF;
SET NEW.TheDuration = DATEDIFF(NEW.bookings.end_date, NEW.bookings.start_date) -- -- TO CALCULATE DURATION BETWEEN 2 DATES
END;
//
DELIMITER ;
Problem lays within...
SET NEW.TheDuration = DATEDIFF(NEW.bookings.end_date, NEW.bookings.start_date) -- -- TO CALCULATE DURATION BETWEEN 2 DATES

Set a limit occurrence for a value in a mysql table

So let's say i have a table that has a column "id_author" , i'd like to set a limit for the occurrence of the same value ; example : can't have more than 3 same "id_author" values so when i insert the 4th one it's refused.
Is there a way to implement this? Thanks
You can use a trigger before insert, that will throw a signal in case it violates your condition:
CREATE TRIGGER tooManyRecords
BEFORE INSERT ON yourTable
FOR EACH ROW
BEGIN
DECLARE counter INTEGER;
SELECT COUNT(*) INTO counter FROM yourTable
WHERE id_author = NEW.id_author;
IF counter >= 3 THEN
SIGNAL SQLSTATE '45000' SET message_text = 'there are already 3 records for the provided id';
END