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)
);
Related
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 $$
Here is a sequence of very simple sql queries (MySQl 8.0)
drop table IF EXISTS stack_Compare;
drop table IF EXISTS lastNode;
CREATE TABLE stack_Compare (Station VARCHAR(20), Track INT);
CREATE TABLE lastNode (Last_Station_ID INT, I INT);
AlTER table lastNode ADD PRimary key (I);
INSERT INTO lastNode VALUES (1, 1);
Drop trigger IF EXISTS lastAdded;
DELIMITER $$
CREATE TRIGGER lastAdded AFTER INSERT
ON stack_Compare FOR EACH ROW
BEGIN
UPDATE lastNode SET Last_Station_ID = (SELECT Station.Station_ID FROM Station, stack_Compare WHERE New.Station = Station.Name) WHERE I = 1;
END $$
DELIMITER ;
DROP PROCEDURE IF EXISTS insertStation;
DROP PROCEDURE IF EXISTS insertMain;
DELIMITER $$
SET max_sp_recursion_depth=3;
CREATE PROCEDURE insertStation (insertstationID INT, starter VARCHAR(20), destination VARCHAR(20))
this_procedure:BEGIN
DECLARE nextNode INT DEFAULT NULL;
INSERT INTO stack_Compare (Station)
SELECT Name from Station WHERE Station_ID = insertstationID;
IF insertStationID IN (SELECT Station_ID FROM Station WHERE Name = destination)
THEN LEAVE this_procedure;
END IF;
SET nextNode = (SELECT Next_Station FROM Station WHERE Station_ID = insertstationID);
IF nextNode IS NULL
THEN LEAVE this_procedure;
END IF;
IF nextNode = -1
THEN LEAVE this_procedure;
ELSE CALL insertStation (nextNode, starter, destination);
END IF;
END
$$
CREATE PROCEDURE insertMain (starter VARCHAR(20), destination VARCHAR(20))
BEGIN
DECLARE nextNode INT DEFAULT NULL;
CALL insertStation(8, starter, destination);
loop1: LOOP
SET nextNode = (SELECT Station.Next_Station FROM Station, lastNode WHERE Station.Station_ID = lastNode.Last_Station_ID);
IF nextNode IN (SELECT Station_ID FROM Station WHERE Name = destination)
THEN LEAVE loop1;
END IF;
END LOOP loop1;
END;
$$
DELIMITER ;
CALL insertMain('G1','RG');
SELECT * FROM stack_Compare;
select * from lastNode;
and the station table is
So basically the query SELECT * FROM stackCompare should give
Station
G2
RG
But it only shows G2 in there and the error is Subquery returns more than 1 row
Which I am unable to find WHY from past few hours and a big project is stuck because of this. I guess after doing many experiments that there can be a problem with the Set nextNode line.
below are the queries to create and fill table.
CREATE TABLE Station (
Station_ID INT,
Name VARCHAR(20),
Line_ID INT,
Prev_Station INT,
Next_Station INT,
Hybrid_ID INT,
PRIMARY KEY (Station_ID),
FOREIGN KEY (Line_ID) REFERENCES Line(Line_ID),
FOREIGN KEY (Hybrid_ID) REFERENCES Hybrid(Hybrid_ID)
);
ALTER TABLE Station ADD FOREIGN KEY (Prev_Station) REFERENCES Station(Station_ID);
ALTER TABLE Station ADD FOREIGN KEY (Next_Station) REFERENCES Station(Station_ID);
INSERT INTO Station VALUES
(1,'R1',1,NULL,2,NULL),
(2,'R2',1,1,3,NULL),
(3,'RG',1,-1,-1,1),
(4,'RY',1,-1,-1,2),
(5,'R3',1,4,6,NULL),
(6,'R4',1,5,NULL,NULL),
(7,'G1',3,NULL,8,NULL),
(8,'G2',3,7,3,NULL),
(9,'Y1',2,NULL,4,NULL),
(10,'Y2',2,4,11,NULL),
(11,'Y3',2,10,NULL,NULL);
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 a problem and I don't know how to solve it.
I need to create a procedure with cursor to insert into Vizite: dataora (i need a function), Medici_Idm,Pacienti_Idm,Cabinete_Idm from temporary table.My procedure doesn't work, i also use for select tables: Medici, Pacineti,Cabinete to extract id.
Table 1:
CREATE TABLE IF NOT EXISTS Vizite (
Idv INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
DataOra DATETIME,
Medici_Idm INT NOT NULL,
Pacienti_Idp INT NOT NULL,
Cabinete_Idc INT NOT NULL,
FOREIGN KEY (Medici_Idm) REFERENCES Medici(Idm),
FOREIGN KEY (Pacienti_Idp) REFERENCES Pacienti(Idp),
FOREIGN KEY (Cabinete_Idc) REFERENCES Cabinete(Idc)
) Engine=INNODB;
Table 2:
CREATE TEMPORARY TABLE IF NOT EXISTS TempVizite (
Idt INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
DataVizita VARCHAR(250),
OraIntrare TIME,
NumePacient VARCHAR(250),
PrenumePacient VARCHAR(250),
NumeMedic VARCHAR(250),
PrenumeMedic VARCHAR(250),
Cabinet VARCHAR (250));
the procedure:
DELIMITER /
CREATE PROCEDURE VARIANTA3()
BEGIN
DECLARE M_I,P_I,C_I VARCHAR(100);
DECLARE I_V INT;
DECLARE D DATE;
DECLARE O TIME;
DECLARE CURS1 CURSOR FOR -- declaram cursorul
SELECT IDT,DATAVIZITA,ORAINTRARE,NUMEMEDIC,NUMEPACIENT,CABINET FROM TEMPVIZITE;
DECLARE EXIT HANDLER FOR 1329 BEGIN END; -- declaram handler specific erorii de terminarea cursorului
OPEN CURS1;
BUCLA: LOOP
FETCH CURS1 INTO M_I,P_I,C_I,I_V,D,O;
INSERT IGNORE INTO VIZITE VALUES(I_V,#DATAORA,M_I,P_I,C_I);
SELECT TIMESTAMP(DATAVIZITA,ORAINTRARE) INTO #DATAORA;
SELECT IDM FROM MEDICI WHERE NUME = NUMEMEDIC INTO M_I;
SELECT IDP FROM PACIENTI WHERE NUME = NUMEPACIENT INTO P_I;
SELECT IDC FROM CABINETE WHERE NUME = CABIENT INTO C_I;
END LOOP;
CLOSE CURS1;
END /
DELIMITER ;
I'm trying to write a mySQL procedure with a cursor to calculate a fare. I pass in the stationid's then I figure out what zone they are in. The fare is a set value of $1 and an additional $0.20 for each zone traveled in.
The code I have so far runs but there is a problem with the cursor not fetching the values into the variables.
Any help would be greatly appreciated. Thanks
Tables:
DROP DATABASE IF EXISTS luasSystem;
CREATE DATABASE luasSystem;
USE luasSystem;
CREATE TABLE IF NOT EXISTS line
(
line_id INT NOT NULL AUTO_INCREMENT,
Line_colour CHAR(10) NOT NULL,
PRIMARY KEY (line_id)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS zone
(
zone_id INT NOT NULL AUTO_INCREMENT,
zone_name VARCHAR(20) NOT NULL,
line INT NOT NULL,
PRIMARY KEY (zone_id),
FOREIGN KEY (line) REFERENCES line(line_id) ON UPDATE CASCADE ON DELETE RESTRICT
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS station
(
station_id INT NOT NULL AUTO_INCREMENT,
station_name CHAR(20) NOT NULL,
service CHAR(20),
line INT NOT NULL,
zone INT NOT NULL,
PRIMARY KEY (station_id),
FOREIGN KEY (line) REFERENCES line(line_id) ON UPDATE CASCADE ON DELETE RESTRICT,
FOREIGN KEY (zone) REFERENCES zone(zone_id) ON UPDATE CASCADE ON DELETE RESTRICT
) ENGINE=InnoDB;
Stored Procedure:
DROP PROCEDURE IF EXISTS calculateFare;
DELIMITER //
CREATE PROCEDURE calculateFare
(
IN stationid1 INT, IN stationid2 INT
)
BEGIN
DECLARE zoneNum1 INT;
DECLARE zoneNum2 INT;
DECLARE num INT;
DECLARE fare DOUBLE;
DECLARE tableEnd BOOLEAN;
DECLARE zoneCur CURSOR FOR
SELECT zone, zone FROM station
WHERE station_name = stationid1 AND station_name = stationid2;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET tableEnd = TRUE;
OPEN zoneCur;
the_loop: LOOP
FETCH zoneCur
INTO zoneNum1, zoneNum2;
IF tableEnd THEN
CLOSE zoneCur;
LEAVE the_loop;
END IF;
SET fare = 1;
SET num = 0;
IF zoneNum1 < zoneNum2 THEN
SET num = zoneNum2 - zoneNum1;
ELSEIF zoneNum1 > zoneNum2 THEN
SET num = zoneNum1 - zoneNum2;
END IF;
SET fare = (num * 0.20) + 1;
SELECT fare;
END LOOP the_loop;
END //
DELIMITER ;
CAll calculateFare(3,5);
Wouldn't this be easier of you used decimal values instead of integers? Suggest you look at : http://dev.mysql.com/doc/refman/5.0/en/fixed-point-types.html