Can't create MySQL Trigger with several tables - mysql

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.

Related

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 ;

mysql: I didn't update the table defining the trigger in the trigger, but i got the similar error

I have three tables. They are called book, reader, borrow.
The function of my trigger: insert borrowing records into the borrow table. But before inserting, we have to check the status of the reader's library card and the status of the book. Only when they are all normal can we lend the book to the reader, that is, change the status of the borrowed book in the book table to "borrowed", and then insert the borrowing record into the borrow table. However, some errors occurred when updating the book table.
Please look at my note 1, which reported me such an error: [stored trigger is already used by statement which invoked stored trigger]. I know that the trigger of MySQL can't modify the defined table, so I think this error is very puzzling. Then I created a new account table and added the sentence marked in Note 2 to the trigger. It works properly. So this mistake really confused me.
I would be very grateful if you could help me. Followings is my code:
DROP TRIGGER IF EXISTS before_insert_borrow;
CREATE TRIGGER before_insert_borrow BEFORE INSERT ON borrow
FOR EACH ROW
BEGIN
DECLARE cst VARCHAR(10);
DECLARE b_cts VARCHAR(10);
SELECT Card_status FROM reader WHERE read_no = NEW.read_no INTO cst;
SELECT B_status FROM book WHERE book_no = NEW.book_no INTO b_cts;
IF cst = 'loss' THEN
SIGNAL SQLSTATE '09000' SET MESSAGE_TEXT = 'your card is lost……';
ELSEIF b_cts = 'checked' THEN
SIGNAL SQLSTATE '09000' SET MESSAGE_TEXT = 'the book you want has been checked out.';
END IF;
UPDATE book SET B_status = 'checked' WHERE book_no = NEW.book_no; -- 1
UPDATE account SET total = total + 1000 WHERE id =1; -- 2
END;
-- test data
INSERT INTO borrow(read_no,book_no)VALUES('001','B17682');

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 maximum limits in mysql sql database

I have 2 tables. Concerts / Tickets
I want to set Concert 1 to have maximum of 100 tickets and Concert 2 to have maximum of 200 tickets. so like have a concert_id be linked with a maximum number of ticket_id.
How can I do this in mysql? thanks
You can write triggers:
delimiter //
drop trigger if exists limitInsertsTrigger //
create trigger limitInsertsTrigger before insert on tickets
for each row
begin
declare msg varchar(128);
if (select count(*) from tickets where concert_id = new.concert_id)>
(select max_tickets_number from concert where id=new.concert_id)
then
set msg = concat('MyTriggerError: Trying to insert too many tickets');
signal sqlstate '45000' set message_text = msg;
end if;
end //
Remember to have a max_tickets_number column in the concert table.

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 //