MySQL stored procedure to insert or update table - mysql

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?

Related

Create trigger before insert in table

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

MYSQL trying to get other attributes from max value

I have this trigger
DELIMITER $$
CREATE TRIGGER before_bid_insert
BEFORE INSERT ON Bids
FOR EACH ROW
BEGIN
IF NEW.amount > (SELECT B.amount, B.vin FROM Bids B WHERE B.vin = NEW.vin AND B.amount = (SELECT MAX(amount) from Bids)) THEN
INSERT INTO Notifications (buyer, outbidded, vin, amount) values (NEW.buyer, B.buyer, NEW.vin, NEW.amount);
END IF ;
END$$
DELIMITER ;
With tables
CREATE TABLE Auctions
(seller VARCHAR(100),
vin VARCHAR(20),
brand VARCHAR(20),
cartype VARCHAR(20),
model VARCHAR(20),
color VARCHAR(20),
minprice int,
dt DATETIME,
PRIMARY KEY (vin, seller)
);
CREATE TABLE Bids
(buyer VARCHAR(20),
vin VARCHAR(20),
amount int,
autobid int,
upperlimit int,
PRIMARY KEY(buyer, vin, amount),
FOREIGN KEY (vin) REFERENCES Auctions(vin)
);
CREATE TABLE Notifications
(buyer VARCHAR(20),
outbidded VARCHAR(20),
vin VARCHAR(20),
amount int,
PRIMARY KEY(vin, buyer),
FOREIGN KEY (vin) REFERENCES Bids(vin),
FOREIGN KEY (buyer) REFERENCES Bids(buyer)
);
However whenever I run it, it says operand should contain 1 columns.
What i'm trying to do is, if the row thats being inserted has a higher amount value than any row already in the bids table with the same VIN as the new row, then insert the values into notifications.
You can do this to help with both your issues:
SELECT B.amount INTO #amount, B.buyer INTO #buyer
FROM Bids B WHERE B.vin = NEW.vin AND B.amount = (SELECT MAX(amount) from Bids)
IF NEW.amount > #amount THEN
INSERT INTO Notifications (buyer, outbidded, vin, amount)
values (NEW.buyer, #buyer, NEW.vin, NEW.amount);
Also, not sure but I feel you should have another check in SELECT MAX(amount) from Bids query to include a WHERE clause to check for vin.

How can I avoid duplicate values in my result set?

CREATE TABLE student
(
s_id int(10) NOT NULL AUTO_INCREMENT,
s_roll_no int(30),
s_name varchar(30),
s_gender varchar(4) not null,
class int(2) not null,
PRIMARY KEY (s_id)
);
CREATE TABLE attendance_date
(
date_today varchar(10),
PRIMARY KEY (date_today)
);
CREATE TABLE attendance_today
(
s_id int(10),
s_roll_no int(30),
s_name varchar(30),
s_gender varchar(4),
class int(2),
date_today varchar(10),
attendance_status varchar(2) not null default 'P'
);
delimiter $$
create trigger after_insertion_into_attendance_date
after insert on attendance_date
for each row
begin
insert into attendance_today(s_id, s_roll_no, s_name, s_gender, class, date_today)
select * from student cross join attendance_date order by date_today, s_id;
end$$
delimiter ;
INSERT INTO student
VALUES
(1,1,'Mridul Kumar','M',1),
(2,2,'Harish Paul','M',1),
(3,3,'Imtiaz Hossain','M',1);
INSERT INTO attendance_date
VALUES
('1st Jan'),
('2nd Jan');
now,
select * from attendance_today;
giving duplicates after every insertion, is there any way to avoid such duplicates inside trigger?
I'm not looking for
select distinct * from attendance_today;
after the trigger gets activated.
This will prevent duplicate values from being inserted
insert into attendance_today(s_id, s_roll_no, s_name, s_gender, class, date_today)
select *
from student cross join attendance_date ad
WHERE NOT EXISTS (
SELECT null FROM attendance_today at
WHERE ad.s_id = at.s_id and ad.date_today = at.date_today
)
order by date_today, s_id;
Try this:
begin
insert into attendance_today(s_id, s_roll_no, s_name, s_gender, class, date_today)
select * from student cross join attendance_date group by s_id order by date_today, s_id;
end$$

Stored procedure to select column from table and insert to multiple table in mysql

I want to select values from basic2 and insert into basic3 and basic4 using stored procedure.
These are the table definitions:
create table basic2(
id int AUTO_INCREMENT,
name varchar(50),
address varchar(50),
PRIMARY KEY (id)
);
create table basic3(
id int AUTO_INCREMENT,
name varchar(50),
address varchar(50),
PRIMARY KEY (id)
);
create table basic4(
id int AUTO_INCREMENT,
name varchar(50),
address varchar(50),
PRIMARY KEY (id)
);
this is the new_person store procedure
drop procedure if exists new_person;
DELIMITER //
CREATE PROCEDURE new_person
select (id, name,address)
from basic2;
BEGIN
START TRANSACTION;
INSERT INTO basic3 (id,name,address)
VALUES(LAST_INSERT_ID(),bname,baddress);
INSERT INTO basic4 (id,name,address)
VALUES(LAST_INSERT_ID(),bname,baddress);
COMMIT;
END//
DELIMITER;
We can do it by two way one for using cursor and another is using SELECT with insert i thing for you SELECT is better
Like this
INSERT INTO basic3 (name,address)
SELECT name, address FROM basic2;

inner join gives in mysql gives error code 1052

I created a database with following tables :
CREATE SCHEMA IF NOT EXISTS `facturatiedatabase` ;
USE `facturatiedatabase` ;
DROP TABLE IF EXISTS tblAddress ;
DROP TABLE IF EXISTS tblContact ;
DROP TABLE IF EXISTS tblCustomers ;
CREATE TABLE tblCustomers (
customerID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(30) NOT NULL,
lastname VARCHAR(30) NOT NULL,
vat VARCHAR(30) NOT NULL,
customerVisible varchar(1) NOT NULL DEFAULT 'T'
) ENGINE=InnoDB;
CREATE TABLE tblContact (
contactID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(100),
phone VARCHAR(100),
customerID int,
CONSTRAINT FK_customerID_Contact FOREIGN KEY (customerID) REFERENCES tblCustomers(customerID)
) ENGINE=InnoDB;
CREATE TABLE tblAddress (
addressID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
street VARCHAR(100),
houseNumber VARCHAR(15),
city VARCHAR (100),
country VARCHAR (100),
customerID int,
CONSTRAINT FK_customerID_Adress FOREIGN KEY (customerID) REFERENCES tblCustomers(customerID)
) ENGINE=InnoDB;
INSERT INTO tblCustomers (firstname, lastname,vat)
VALUES ("John","Doe","UV45856855");
INSERT INTO tblContact (customerID,phone, email)
VALUES ((SELECT DISTINCT LAST_INSERT_ID() FROM tblCustomers), "0000001","Johndoe#gmail.com");
INSERT INTO tblAddress (customerID,street,housenumber,city,country)
VALUES ((SELECT DISTINCT LAST_INSERT_ID() FROM tblCustomers), "berkenlaan","1a","Harelbeke","Belgie");
But when i try following inner join it gives me the following error :
LIMIT 0, 1000 Error Code: 1052. Column 'customerID' in field list is ambiguous 0.000 sec.
SELECT customerID, firstname, lastname, vat,email
FROM tblCustomers
INNER JOIN tblContact on tblCustomers.customerID = tblContact.contactID
The error message says it all: the column name customerID is contained in both tables. So which value should mysql select? That is ambiguous, therefore the error.
Have a try with this variant:
SELECT tblCustomers.customerID AS customerID, firstname, lastname, vat,email
FROM tblCustomers
INNER JOIN tblContact on tblCustomers.customerID = tblContact.contactID
(or pick that other tables's column with the same if you need that one...)
And, frankly, I doubt your ON clause is the one you want to use. Shouldn't that be ON tblCustomers.customerID = tblContact.customerID instead?