Insert data from a table into another table when a trigger fires - mysql

I have 4 tables :
pacienti
cabinete
tmp
vizite.
DROP SCHEMA IF EXISTS tr;
CREATE SCHEMA IF NOT EXISTS tr;
USE tr;
CREATE TABLE IF NOT EXISTS pacienti
(
id_pac INT NOT NULL AUTO_INCREMENT PRIMARY KEY
Nume VARCHAR(40) DEFAULT 'anonim',
Prenume VARCHAR(40) DEFAULT 'anonim',
UNIQUE (Nume,Prenume)
) ENGINE=INNODB;
CREATE TABLE IF NOT EXISTS cabinete
(
id_cab INT NOT NULL AUTO_INCREMENT PRIMARY KEY
Denumire VARCHAR(40) DEFAULT 'nespecificat',
UNIQUE (Denumire)
) ENGINE=INNODB;
CREATE TABLE IF NOT EXISTS tmp
(
id_tmp INT(5) NOT NULL AUTO_INCREMENT PRIMARY KEY,
DataVizita VARCHAR(10),
OraIntrare TIME,
ComplDate DATETIME,
NumePacient VARCHAR(40) DEFAULT 'anonim',
PrenumePacient VARCHAR(40) DEFAULT 'anonim',
NumeMedic VARCHAR(40) DEFAULT 'nespecificat',
PrenumeMedic VARCHAR(40) DEFAULT 'nespecificat',
Cabinet VARCHAR(30) DEFAULT 'nespecificat'
);
CREATE TABLE IF NOT EXISTS vizite
(
id_viz INT(5) NOT NULL AUTO_INCREMENT PRIMARY KEY,
Data_viz DATETIME,
Medic_id INT(5) NOT NULL,
Pacient_id INT(5) NOT NULL,
Cabinet_id INT(5) NOT NULL,
FOREIGN KEY (`Medic_id`) REFERENCES `tr`.`medici`(`id_med`)
ON UPDATE RESTRICT ON DELETE CASCADE,
FOREIGN KEY (`Pacient_id`) REFERENCES `tr`.`pacienti`(`id_pac`)
ON UPDATE RESTRICT ON DELETE CASCADE,
FOREIGN KEY (`Cabinet_id`) REFERENCES `tr`.`cabinete`(`id_cab`)
ON UPDATE RESTRICT ON DELETE CASCADE
) ENGINE=INNODB;
I have a file from which I have to import the data into the tmp table.
The file (*.txt) have the next fields:
DataVizita | OraIntrare | NumePacient | PrenumePacient | NumeMedic | PrenumeMedic | Cabinet
--------------------------------------------------------------------------------------------
22/04/2005 | 01:52:34 | Huruiala |Carmen Alexandra| Garbeata | Panait | 1
05/12/2005 | 04:16:02 | Schornig | Petre | Rusu | Dragos Mihai | 2
07/11/2004 | 11:24:27 | Graur |Alexandra-Cris. | Soarece | Dan-Cristian | 4
07/05/2008 | 06:35:44 | Rudnitchi | Marian | Galescu |George Valentin| 5
.
.
.
etc…
AFTER / BEFORE I made the import in the tmp table, I have to do some operations :
Create a trigger which must concat the DataVizita and OraIntrare into a DATETIME field (I succed by creating a function which convert DataVizita to the right format and concatenate it with OraIntrare and place the result in ComplDate from tmp table.
Here is what I already did and it works:
CREATE FUNCTION formdate(ziua VARCHAR(10), timpul TIME)RETURNS DATETIME
DERMINISTIC
RETURN
CONCAT (DATE_FORMAT(STR_TO_DATE(ziua, '%d/%m/%Y' ) , '%Y-%m-%d' ),' ',timpul);
DELIMITER $$
CREATE TRIGGER upd_date BEFORE INSERT ON tmp
FOR EACH ROW
BEGIN
SET new.ComplDate = formdate(new.DataVizita,new.OraIntrare);
END$$
DELIMITER ;
The second thing I have to do is to fill the pacienti and cabinete tables with data from this file.
And this one I need it because I can’t figure it out how to do it :(
Sorry for this long presentation, but I was thinking that someone will need all the details in order to understand my question.

I have realized that actually is very simple :). The final trigger should look like this :
DROP TRIGGER IF EXISTS upd_date;
DELIMITER $$
CREATE TRIGGER upd_date BEFORE INSERT ON tmp
FOR EACH ROW
BEGIN
SET new.ComplDate=formdate(new.DataVizita,new.OraIntrare);
INSERT INTO pacienti(nume,prenume) VALUES(new.NumePacient,new.PrenumePacient)
ON DUPLICATE KEY UPDATE nume=new.NumePacient, prenume=new.PrenumePacient;
INSERT INTO cabinete(Denumire) VALUES(new.Cabinet)
ON DUPLICATE KEY UPDATE Denumire=new.Cabinet;
END$$
DELIMITER ;
Hope that helped somebody !

Related

Delete From in delete after trigger not deleting from another table

I am trying to make a DELETE TRIGGER so that when a row is deleted from a table Bike it will delete a row in another table called Available as long as it is not in a different table called in Rental. If it is in Rental table then it will cancel the delete (if that's possible I'm very new to sql).
BEGIN
DELETE FROM Available
Where old.bnumber = Available.bnumber;
END
right now I am getting
1451: Cannot delete or update a parent row: a foreign key constraint
fails (cecs535project.available, CONSTRAINT bnumber FOREIGN KEY
(bnumber) REFERENCES bike (bnumber))
bnumber is a foreign key in Available that references Bike.
Any help is appreciated.
CREATE TABLE `Bike` (
`bnumber` int NOT NULL,
`make` varchar(64) DEFAULT NULL,
`color` varchar(8) DEFAULT NULL,
`year` int DEFAULT NULL,
PRIMARY KEY (`bnumber`)
)
CREATE TABLE `Available` (
`bnumber` int NOT NULL,
`rack-id` int DEFAULT NULL,
PRIMARY KEY (`bnumber`),
KEY `bnumber_idx` (`rack-id`),
KEY `bnumber_idx1` (`bnumber`),
CONSTRAINT `bnumber` FOREIGN KEY (`bnumber`) REFERENCES `Bike` (`bnumber`),
CONSTRAINT `rack-id` FOREIGN KEY (`rack-id`) REFERENCES `Rack` (`id`)
)
CREATE TABLE `Rental` (
`date` date NOT NULL,
`time` time NOT NULL,
`bnumber` int NOT NULL,
`cust-id` int NOT NULL,
`src` int DEFAULT NULL,
PRIMARY KEY (`bnumber`,`cust-id`,`date`,`time`),
KEY `bnumber_idx` (`bnumber`),
KEY `cust-id_idx` (`cust-id`),
KEY `src_idx` (`src`),
CONSTRAINT `bike` FOREIGN KEY (`bnumber`) REFERENCES `Bike` (`bnumber`),
CONSTRAINT `cust-id` FOREIGN KEY (`cust-id`) REFERENCES `Customer` (`id`),
CONSTRAINT `src` FOREIGN KEY (`src`) REFERENCES `Rack` (`id`)
)
I am not a big fan of your current design, and I think it can be simplified. Consider just having a single table for all bike assets, with one column maintaining whether or not it be currently rented out, e.g.
Bike
id | name | type | rented (bit)
1 | bike1 | road | 1
2 | bike2 | mountain | 0
...
Now to record a bike being rented or not, you simply have to update the rented bit column above. Should you want to delete from your inventory, refraining from doing so if the bike be on loan, you can use:
DELETE
FROM Bike
WHERE rented = 0; -- AND your other conditions here
2 possible approaches
Use signal to identify where rental exists an throw an error https://dev.mysql.com/doc/refman/8.0/en/signal.html
test for rental existence in delete;
In both a before trigger is used since the constraint test occurs before an after trigger fires.
DROP TABLE IF EXISTS AVAILABLE;
drop table if exists rental;
drop table if exists BIKE;
CREATE TABLE `Bike` (
`bnumber` int NOT NULL,
`make` varchar(64) DEFAULT NULL,
`color` varchar(8) DEFAULT NULL,
`year` int DEFAULT NULL,
PRIMARY KEY (`bnumber`)
);
insert into bike values
(10,'aaa','red',2020),(20,'bbb','yell',2020);
CREATE TABLE `Available` (
`bnumber` int NOT NULL,
`rack-id` int DEFAULT NULL,
PRIMARY KEY (`bnumber`),
KEY `bnumber_idx` (`rack-id`),
KEY `bnumber_idx1` (`bnumber`),
CONSTRAINT `bnumber` FOREIGN KEY (`bnumber`) REFERENCES `Bike` (`bnumber`)#,
#CONSTRAINT `rack-id` FOREIGN KEY (`rack-id`) REFERENCES `Rack` (`id`)
) ;
insert into available values
(10,100),(20,200);
CREATE TABLE `Rental` (
#`date` date NOT NULL,
#`time` time NOT NULL,
`bnumber` int NOT NULL,
#`cust-id` int NOT NULL,
#`src` int DEFAULT NULL,
#PRIMARY KEY (`bnumber`,`cust-id`,`date`,`time`),
KEY `bnumber_idx` (`bnumber`),
#KEY `cust-id_idx` (`cust-id`),
#KEY `src_idx` (`src`),
CONSTRAINT `bike` FOREIGN KEY (`bnumber`) REFERENCES `Bike` (`bnumber`)#,
#CONSTRAINT `cust-id` FOREIGN KEY (`cust-id`) REFERENCES `Customer` (`id`),
#CONSTRAINT `src` FOREIGN KEY (`src`) REFERENCES `Rack` (`id`)
) ;
insert into rental values
(10);
Approach 1
drop trigger if exists t;
delimiter $$
create trigger t before delete on bike
for each row
begin
if exists (select 1 from rental r where r.bnumber = old.bnumber) then
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'An error occurred Rental exists';
end if;
delete a from available a where a.bnumber = old.bnumber;
end $$
delimiter ;
delete b from bike b;
ERROR 1644 (45000): An error occurred Rental exists
+---------+------+-------+------+
| bnumber | make | color | year |
+---------+------+-------+------+
| 10 | aaa | red | 2020 |
| 20 | bbb | yell | 2020 |
+---------+------+-------+------+
2 rows in set (0.001 sec)
select * from available;
+---------+---------+
| bnumber | rack-id |
+---------+---------+
| 10 | 100 |
| 20 | 200 |
+---------+---------+
2 rows in set (0.001 sec)
select * from rental;
+---------+
| bnumber |
+---------+
| 10 |
+---------+
1 row in set (0.001 sec)
Approach 2
drop trigger if exists t;
delimiter $$
create trigger t before delete on bike
for each row
begin
delete a from available a where a.bnumber = old.bnumber;
end $$
delimiter ;
delete b from bike b where
#bnumber = 10 and
not exists(select 1 from rental r where r.bnumber = b.bnumber);
select * from bike;
+---------+------+-------+------+
| bnumber | make | color | year |
+---------+------+-------+------+
| 10 | aaa | red | 2020 |
+---------+------+-------+------+
1 row in set (0.001 sec)
select * from available;
+---------+---------+
| bnumber | rack-id |
+---------+---------+
| 10 | 100 |
+---------+---------+
1 row in set (0.001 sec)
select * from rental;
+---------+
| bnumber |
+---------+
| 10 |
+---------+
1 row in set (0.001 sec)
Creating an AFTER DELETE instead could also help to skip the Foreign Key Constraint issue
CREATE TRIGGER trigger_name
AFTER DELETE
ON table_name FOR EACH ROW
trigger_body;
ref: https://www.mysqltutorial.org/mysql-triggers/mysql-after-delete-trigger/

How to concat_ws primarykey(id) and date in a new column on same table?(MySQL)

I need add a new column named date_id by using concat_ws('-', curdate,id) on a same table, the id is a primarykey and auto_increment.
How to do this?
I tried add a column and updated it. it worked, but when I insert some new row, the error showed Filed 'id' doesnot have a default value.
How to solve this?
ALTER TABLE table1 ADD date_id VARCHAR(50);
UPDATE table1 SET date_id = CONCAT_WS('-',date_format(CURDATE(),'%Y%m%d'),id);
update question
I have created a table:
USE table_name;
CREATE TABLE IF NOT EXISTS `gzsrieQA`(
`id` INT(3) UNSIGNED ZEROFILL AUTO_INCREMENT,
`record_id` VARCHAR(50),
`date` date,
`pro_name` VARCHAR(50),
`error_info` VARCHAR(255),
`error_describe` VARCHAR(255),
`reason` VARCHAR(255),
`solution` VARCHAR(255),
`solution_file` BLOB,
`solution_file_name` VARCHAR(50),
PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER table_name AUTO_INCREMENT = 001;
UPDATE table_name SET record_id = CONCAT_WS('-','SRIE-DSJ-QA',date_format(CURDATE(),'%Y%m%d'),id);
When I insert into some new data, the result showed 'record_id' is null. it means I need a trigger? But the question is if I insert lots of data, the trigger is too slow.Is there any solution to solve this if I don't use trigger?
For example:
|id|record_id|name|
|-----|-----|-----|
|001| |ABC|
|002| |xyz|
# I want to get:
|id|record_id|name|
|-----|-----|-----|
|001|ABC001|ABC|
|002|xyz002|xyz|
# and when I insert into name=AAA, the result is:
|id|record_id|name|
|-----|-----|-----|
|001|ABC001|ABC|
|002|xyz002|xyz|
|003|aaa003|AAA|
THANKS!
I tried MySQL and it allowed your statement however you can set a default and then remove it.
select version();
| version() |
| :-------- |
| 8.0.13 |
create table table1 (id int auto_increment primary key);
✓
insert into table1(id) values (NULL),(NULL),(NULL),(NULL)
✓
ALTER TABLE table1 ADD date_id VARCHAR(50) default '';
✓
UPDATE table1 SET date_id = CONCAT_WS('-',date_format(CURDATE(),'%Y%m%d'),id);
✓
select * from table1
id | date_id
-: | :---------
1 | 20190111-1
2 | 20190111-2
3 | 20190111-3
4 | 20190111-4
show create table table1
Table | Create Table
:----- | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
table1 | CREATE TABLE `table1` (<br> `id` int(11) NOT NULL AUTO_INCREMENT,<br> `date_id` varchar(50) DEFAULT '',<br> PRIMARY KEY (`id`)<br>) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
alter table table1 alter column date_id DROP DEFAULT, ALGORITHM=INPLACE, LOCK=NONE;
✓
show create table table1;
Table | Create Table
:----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
table1 | CREATE TABLE `table1` (<br> `id` int(11) NOT NULL AUTO_INCREMENT,<br> `date_id` varchar(50),<br> PRIMARY KEY (`id`)<br>) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
db<>fiddle here

Reserve/Assign a new row in another table with each row added in one

I'll like to find out if it's possible to do the following:
after insertion of data into table a, a row will be created automatically in table b and the Note_Id (its primary key) will be stored in one of the attributes (which is a foreign key that references to the primary key in table b) in table a.
CREATE TABLE table_a ( D_Id int(5) NOT NULL AUTO_INCREMENT,
User_Id int(8) not null,
Note_Id int(5) not null, -- this is the foreign key that points to table b
PRIMARY KEY (D_Id) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE table_b ( Note_Id int(5) NOT NULL AUTO_INCREMENT,
Note_Description varchar(50) null,
PRIMARY KEY (Note_Id) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Thanks!
delimiter $$
CREATE TRIGGER ins_Document
AFTER INSERT ON TABLE_A FOR EACH ROW
BEGIN
set #notenum=(Select max(Note_Id) from TABLE_B);
if(#notenum=0) then begin new.Note_Id=1;
end;
else
new.Note_Id=#notenum+1;
end if;
INSERT INTO TABLE_B (Note_Id) VALUES (NEW.Note_Id);
END$$
delimiter ;
Have a look into triggers: Create Trigger
Here you can react on events like inserts into a table and define respective actions for that.

Fill MySQL records one-to-many related tables in one action

I have two MySQL tables with an one-to-many relationship between them. For example:
CREATE TABLE test1 (
pk1 INTEGER AUTO_INCREMENT PRIMARY KEY,
testvalue1 INTEGER
);
CREATE TABLE test2 (
pk2 INTEGER AUTO_INCREMENT PRIMARY KEY,
testvalue2 VARCHAR(50),
fk2 INTEGER NOT NULL,
FOREIGN KEY (fk2) REFERENCES test1 (pk1)
);
If I want to insert records in both tables I can first insert a record in the PK table (e.g. INSERT INTO test1 SET testvalue1=100), determine the PK value (e.g. SELECT MAX(pk1) AS LastId FROM test1 or use LAST_INSERT_ID())
and finally use that value to fill the FK column in the second table.
But is it possible to achieve this all in 1 command/query/action? So let's MySQL fill in the PK- and FK-values using the AUTO INCREMENTs?
You should use two INSERT commands; or try to use an INSERT-trigger.
EDIT:
--An example with trigger:
CREATE TABLE dept(
id INT(11) NOT NULL AUTO_INCREMENT,
dept_name VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (id)
)
ENGINE = INNODB;
CREATE TABLE emp(
id INT(11) NOT NULL AUTO_INCREMENT,
emp_name VARCHAR(255) DEFAULT NULL,
dept_id INT(11) DEFAULT NULL,
PRIMARY KEY (id),
CONSTRAINT FK_emp_dept_id FOREIGN KEY (dept_id)
REFERENCES dept (id) ON DELETE RESTRICT ON UPDATE RESTRICT
)
ENGINE = INNODB;
DELIMITER $$
CREATE TRIGGER trigger1
AFTER INSERT
ON dept
FOR EACH ROW
BEGIN
INSERT INTO emp VALUES (NULL, 'Someone', NEW.id);
END
$$
DELIMITER ;
-- Try to add new department.
INSERT INTO dept VALUES(NULL, 'Sales');
-- Is there new default employee?
SELECT * FROM emp;
+----+----------+---------+
| id | emp_name | dept_id |
+----+----------+---------+
| 1 | Someone | 1 |
+----+----------+---------+

MySQL - autoincrement to guid

I have a table with an auto-increment ID field as shown below.
+------------+-------------------------------------+
| company_id | name |
+------------+-------------------------------------+
| 1 | International Client |
| 2 | Oracle |
| 3 | test |
| 4 | testabc |
| 5 | testdef |
| 6 | abcd |
+------------+-------------------------------------+
I want to update the ID column to be a GUID using the uuid() function.
Additionally, how do I update the foreign key references to the correct GUID?
Use triggers.
CREATE TABLE `tbl_test` (
`GUID` char(40) NOT NULL,
`Name` varchar(50) NOT NULL,
PRIMARY KEY (`GUID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
table and pk, now trigger..
DELIMITER //
CREATE TRIGGER `t_GUID` BEFORE INSERT ON `tbl_test`
FOR EACH ROW begin
SET new.GUID = uuid();
end//
DELIMITER ;
Now try,
insert into tbl_test(Name) value('trigger happy...');
regards,
/t
you can't use it with autoincrement
guid is char not intger
you need to insert it your self
also you will need to change the id to char(40)
insert into table_name (id,name) values (uuid(),'jon');
In mysql 8.0 you can use something like below:
For UUID without dashes:
create table temp (`company_id` VARCHAR(64) NOT NULL DEFAULT (REPLACE(UUID(),'-','')), 'name' varchar(100) NOT NULL);
For UUID with dashes:
create table temp (`company_id` VARCHAR(64) NOT NULL DEFAULT (UUID()), 'name' varchar(100) NOT NULL);
I hope this answers your question, Let me know if it is not or you need more.