I created a trigger before inserting into the employee table to calculate its age, but trying to insert into the employee table returns the following erro Error Code: 1442. Can't update table 'employee' in stored function/trigger because it is already used by statement which invoked this stored function/trigger
CREATE TABLE IF NOT EXISTS person (
ssn INT(20) NOT NULL,
name_person VARCHAR(200) NOT NULL,
birth_date DATE NOT NULL,
PRIMARY KEY (ssn))
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS employee (
ssn_employee INT(20) NOT NULL,
job_title VARCHAR(100) NOT NULL,
age INT(10) DEFAULT NULL,
PRIMARY KEY(ssn_employee),
FOREIGN KEY (ssn_employee)
REFERENCES person (ssn)
ON UPDATE CASCADE)
ENGINE = InnoDB;
DELIMITER $$
CREATE TRIGGER employeeAge
BEFORE INSERT ON employee
FOR EACH ROW
BEGIN
DECLARE dob DATE;
DECLARE ssn_employee1 int;
SELECT new.ssn_employee INTO ssn_employee1;
SELECT person.birth_date into dob FROM person WHERE ssn = ssn_employee1;
UPDATE employee
SET new.age = DATEDIFF(dob, GETDATE());
END
DELIMITER;$$
Thank you guys. I'm a beginner and the tips clarified. I did this:
```lang_sql
DELIMITER $$
CREATE TRIGGER employeeAge
BEFORE INSERT ON employee
FOR EACH ROW
BEGIN
DECLARE dob DATE;
DECLARE ssn_employee1 int;
SELECT new.ssn_employee INTO ssn_employee1;
SELECT person.birth_date into dob FROM person WHERE ssn = ssn_employee1;
SET new.age = TIMESTAMPDIFF(YEAR, dob, NOW());
END;
DELIMITER $$
Related
I would like to create a trigger on the FRIENDS table so that friend pairs are ordered and there aren't duplicate entries with the same friends. The following trigger is throwing a syntax error at BEGIN IF (:new.USER1_ID > :new.USER2_ID) ... -- how is this trigger supposed to be formatted?
CREATE TABLE USERS (
USER_ID INTEGER NOT NULL,
FIRST_NAME VARCHAR(100) NOT NULL,
LAST_NAME VARCHAR(100) NOT NULL,
YEAR_OF_BIRTH INTEGER,
MONTH_OF_BIRTH INTEGER,
DAY_OF_BIRTH INTEGER,
SSN INTEGER,
EMAIL VARCHAR(100),
PHONE INTEGER,
PWD VARCHAR(100),
ADDRESS VARCHAR(500),
PRIMARY KEY(USER_ID)
);
CREATE TABLE FRIENDS (
USER1_ID INTEGER,
USER2_ID INTEGER,
FOREIGN KEY (USER1_ID) REFERENCES USERS(USER_ID) ON DELETE CASCADE,
FOREIGN KEY (USER2_ID) REFERENCES USERS(USER_ID) ON DELETE CASCADE,
PRIMARY KEY(USER1_ID, USER2_ID),
CHECK(USER1_ID!=USER2_ID)
);
CREATE TRIGGER FRIENDS_TRIGGER
BEFORE INSERT ON FRIENDS FOR EACH ROW
BEGIN
DECLARE TEMP INTEGER
BEGIN
IF (:new.USER1_ID > :new.USER2_ID) THEN
SET TEMP = :new.USER1_ID
SET :new.USER1_ID = :new.USER2_ID
SET :new.USER2_ID = TEMP
END IF
END
/
There are several problems. You need to terminate statements with semicolons, and so you also need to change the delimiter so the entire create trigger is treated as a single statement. :new should also be NEW. And you have an extra BEGIN thrown in there.
DELIMITER //
CREATE TRIGGER FRIENDS_TRIGGER
BEFORE INSERT ON FRIENDS
FOR EACH ROW
BEGIN
DECLARE TEMP INTEGER;
IF (NEW.USER1_ID > NEW.USER2_ID) THEN
SET TEMP = NEW.USER1_ID;
SET NEW.USER1_ID = NEW.USER2_ID;
SET NEW.USER2_ID = TEMP;
END IF;
END; //
DELIMITER ;
I have the following table..
create table Reservation(
Reservation_number int not null auto_increment,
Flight_id int not null,
Number_of_passengers int,
Contact_Passport_number int,
primary key(Reservation_number),
foreign key(Flight_id) references Flight(Flight_id),
foreign key(Contact_Passport_number) references Contact(Contact_Passport_number)
);
.. the following stored procedure
delimiter //
create procedure addContact(
in reservation_nr int,
in passport_number int,
in email varchar(30),
in phone bigint)
begin
declare PassNumCheck int;
declare ResNumCheck int;
select Passengers.Passport_number into PassNumCheck
from Passengers
where Passengers.Passport_number = passport_number;
select Reservation_number into ResNumCheck
from Reservation
where Reservation_number = reservation_nr;
if (ResNumCheck is null) then
select "The given reservation number does not exist" as message;
elseif (PassNumCheck is null) then
select "The person is not a passenger of the reservation" as message;
else
insert into Contact(Contact_Passport_number,Phone_number,E_mail)
values (passport_number,phone,email);
update Reservation
set Contact_Passport_number = passport_number
where Reservation_number = reservation_nr;
end if;
end;
//
delimiter ;
..and the following procedure call
CALL addContact(#a,00000001,"frodo#magic.mail",080667989);
I am getting the following error " Error Code: 1054. Unknown column 'Reservation_number' in 'where clause' " when i try to execute the procedure call.
Update..
I also have the following trigger and table
drop trigger if exists ticketnumber;
delimiter //
create trigger ticketnumber
after update on Reservation
for each row
begin
declare ticket_number bigint;
set ticket_number=rand();
update Ticket set Ticket_number=ticket_number
where Reservation.Reservation_number=NEW.Reservation_number;
end;
//
delimiter ;
create table Ticket(
Booking_id int not null,
Passport_number int not null,
Ticket_number int,
primary key(Booking_id,Passport_number),
foreign key(Booking_id) references Booking(Booking_id),
foreign key(Passport_number) references Passengers(Passport_number)
);
I am working with an overlap super/subtype relationship dealing with person(s) in my DB. What I would like to do is have the overlapping subtypes insert new rows when the supertype gains a new row. I have attached my LRD to clarify the relationship. LRD
I would like to create a trigger that inserts new person rows into the correct subtype based on the attributes employee/user in the person table.
The code I have attempted so far gives me an error upon inserting rows into person noting "employee column does not exist". I would assume this is because this code is trying to use the if statement for the subtypes where it is in fact absent.
I would appreciate any feedback.
Table Details
CREATE TABLE PERSON
(person_id int(10) not null AUTO_INCREMENT,
first_name varchar(15) not null,
last_name varchar(15) not null,
employee char(1),
participant char(1),
CONSTRAINT person_pk PRIMARY KEY (person_id))
ENGINE=InnoDB;
CREATE TABLE EMPLOYEE
(eperson_id int(10) not null AUTO_INCREMENT,
enterprise_email varchar(30),
manager_id int(10),
CONSTRAINT employee_pk PRIMARY KEY (eperson_id),
CONSTRAINT employee_fk1 FOREIGN KEY(eperson_id) REFERENCES PERSON(person_id) ON update cascade,
CONSTRAINT employee_fk2 FOREIGN KEY(manager_id) REFERENCES EMPLOYEE(eperson_id) ON update cascade)
ENGINE=InnoDB;
CREATE TABLE PARTICIPANT
(pperson_id int(10) not null AUTO_INCREMENT,
city varchar(30),
state varchar(2),
zip int(5),
sign_up_date date,
termination_date date,
CONSTRAINT participant_pk PRIMARY KEY (pperson_id),
CONSTRAINT participant_fk FOREIGN KEY(pperson_id) REFERENCES PERSON(person_id) ON update cascade)
ENGINE=InnoDB;
Trigger Code
DELIMITER //
CREATE TRIGGER subtype_creator
AFTER INSERT ON PERSON
FOR EACH ROW
BEGIN
IF (employee = āeā ) THEN
INSERT INTO EMPLOYEE
SET eperson_id = NEW.person_id,
last_name = NEW.last_name,
enterprise_email = NULL,
manager_id = NULL;
IF (participant = āpā )THEN
INSERT INTO PARTICIPANT
SET pperson_id = NEW.person_id,
city=NULL,
state = NULL,
zip = NULL,
sign_up_date =NULL,
termination_date = NULL;
END IF;
END IF;
END//
DELIMITER ;
This may work for you.
First off, I think to have the AUTO_INCREMENT attribute on columns EMPLOYEE.eperson_id and PARTICIPANT.pperson_id is not needed.
Since both of those columns are FOREIGN KEYS and are referencing back to the person_id column of table PERSON, they need to have, and will be getting, their values from that column through the TRIGGER anyway so no need to autoincrement them in the tables.
So I would change that.
This TRIGGER should work with populating both tables EMPLOYEE and PARTICIPANT after INSERT on table PERSON:
DELIMITER //
CREATE TRIGGER subtype_creator
AFTER INSERT ON PERSON
FOR EACH ROW
BEGIN
INSERT INTO EMPLOYEE(eperson_id, enterprise_email, manager_id)
VALUES(NEW.person_id, NULL, NULL);
INSERT INTO PARTICIPANT(pperson_id, city, state, zip, sign_up_date, termination_date)
VALUES(NEW.person_id, NULL, NULL, NULL, NULL, NULL);
END//
DELIMITER ;
Hope this helps you.
I ended up figuring out two methods to solve my issue. I ended up altering my 'employee' and 'participant' into boolean/tinyint data types.
CREATE TABLE PERSON
(person_id int(10) not null AUTO_INCREMENT,
first_name varchar(15) not null,
last_name varchar(15) not null,
employee tinyint(1),
participant tinyint(1),
CONSTRAINT person_pk PRIMARY KEY (person_id))
ENGINE=InnoDB;
After that alteration I decided to try and break up the one trigger into two. This was successful.
Type 1
DELIMITER //
CREATE TRIGGER employee_creator
AFTER INSERT ON PERSON
FOR EACH ROW
BEGIN
IF (NEW.employee = 1 ) THEN
INSERT INTO EMPLOYEE
SET eperson_id = NEW.person_id,
last_name = NEW.last_name,
enterprise_email = NULL,
manager_id = NULL;
END IF;
END//
DELIMITER ;
DELIMITER //
CREATE TRIGGER participant_creator
AFTER INSERT ON PERSON
FOR EACH ROW
BEGIN
IF (NEW.participant =0 )THEN
INSERT INTO PARTICIPANT
SET pperson_id = NEW.person_id,
city=NULL,
state = NULL,
zip = NULL,
sign_up_date =NULL,
termination_date = NULL;
END IF;
END//
DELIMITER ;
After inplementing that first option I realized the ELSEIF would allow me to not split the two and create a single trigger.
Type 2
DELIMITER //
CREATE TRIGGER employee_creator
AFTER INSERT ON PERSON
FOR EACH ROW
BEGIN
IF (NEW.employee = 1 ) THEN
INSERT INTO EMPLOYEE
SET eperson_id = NEW.person_id,
last_name = NEW.last_name,
enterprise_email = NULL,
manager_id = NULL;
ELSEIF (NEW.participant =0 )THEN
INSERT INTO PARTICIPANT
SET pperson_id = NEW.person_id,
city=NULL,
state = NULL,
zip = NULL,
sign_up_date =NULL,
termination_date = NULL;
END IF;
END//
DELIMITER ;
I have two tables:
CREATE TABLE EMPLOYEE (
EMPLOYEE_ID bigint NOT NULL AUTO_INCREMENT,
EMPLOYEE_NO VARCHAR(30),
EMPLOYEE_TYPE VARCHAR(20),
PRIMARY KEY(EMPLOYEE_ID)
);
CREATE TABLE EMP_DETAIL(
EMPLOYEE_ID BIGINT NOT NULL ,
INS_ID VARCHAR(20) ,
SALARY int,
PRIMARY KEY(EMPLOYEE_ID ,INS_ID),
FOREIGN KEY(EMPLOYEE_ID) REFERENCES EMPLOYEE(EMPLOYEE_ID)
);
I want to insert a value in the emp table and the emp_detail table. If the employee already exists, then only insert a record in the emp_details table.
This is the stored procedure:
CREATE PROCEDURE INSERTEMP(
IN EMPLOYEE_NO VARCHAR(30),
IN EMPLOYEE_TYPE VARCHAR(20),
IN INS_ID VARCHAR(20),
IN SALARY INT
)
BEGIN
DECLARE EMPLOYEE_ID BIGINT;
SET #EMPLOYEE_ID= (SELECT IFNULL((SELECT EMPLOYEE_ID FROM EMPLOYEE WHERE EMPLOYEE_NO=EMPLOYEE_NO AND EMPLOYEE_TYPE=EMPLOYEE_TYPE) ,'0'));
IF #EMPLOYEE_ID=0 THEN
INSERT INTO EMPLOYEE (EMPLOYEE_NO ,EMPLOYEE_TYPE ) VALUES (EMPLOYEE_NO,EMPLOYEE_TYPE);
SET #EMPLOYEE_ID=(SELECT LAST_INSERT_ID());
END IF;
INSERT INTO EMP_DETAIL(EMPLOYEE_ID,INS_ID,SALARY) VALUES (#EMPLOYEE_ID,INS_ID,SALARY);
END
If I call the procedure:
CALL INSERTEMP(100, 'PERM','AAA',100);
first execute it created id as 1 in emp table if execute it in second time also insert with new id and third time it fails.
Can someone help?
I have a problem with my trigger code.
After I wrote my trigger I wrote Insert to test the trigger. But my Insert gets error as
Error Code:1109. Unknown table employees in field list.
If I put the insert before the trigger-everything works perfect. But I want this Insert to test the trigger.
drop database if exists kontrolno;
create database kontrolno;
use kontrolno;
CREATE TABLE departments(
id TINYINT UNSIGNED PRIMARY KEY,
name CHAR(12) NOT NULL,
min_salary SMALLINT UNSIGNED NOT NULL,
max_salary SMALLINT UNSIGNED NOT NULL
) ENGINE=InnoDB;
CREATE TABLE employees(
id SMALLINT UNSIGNED PRIMARY KEY,
name VARCHAR(255) NOT NULL,
salary SMALLINT UNSIGNED NOT NULL,
department_id TINYINT UNSIGNED,
constraint FOREIGN KEY (department_id)
REFERENCES departments(id)
) ENGINE=InnoDB;
insert into departments(id,name,min_salary,max_salary)
values(1,"qa", 800,2000),
(2,"jd",1200,3500);
DROP TRIGGER if exists checkSalary;
delimiter |
create trigger checkSalary before Insert on employees
for each row
begin
if(employees.salary>max_salary OR employees.salary<min_salary)
then signal sqlstate '45000' set MESSAGE_TEXT="the salary is not valide";
end if;
end;
|
delimiter ;
insert into employees(id,name,salary,department_id)
values(1,"ivan", 200,1);
You had mistakes in your trigger code.
The trigger code should be:
DROP TRIGGER if exists checkSalary;
delimiter |
create trigger checkSalary before Insert on employees
for each row
begin
if(new.salary>(select max_salary from departments where id=new.department_id)
OR
new.salary<(select min_salary from departments where id=new.department_id) )
then signal sqlstate '45000' set MESSAGE_TEXT="the salary is not valid";
end if;
end;
|
delimiter ;