Trigger to insert data based on a value - mysql

We have 3 tables:
punches-table :
ID user_code (columns )
2 10
Employees_table :
Id user_code(columns )
5 10
I want a trigger that once a new record is inserted to punches_table will search for the same user_code in employees table and than insert the 2 id values into:
Punches-employees-relation_table:
ID employees_id punches_id
1 2 5
Update
Thanks for the answer, I am getting 1064 error, I guess I have MariaDB and the code is not good for MariaDB.
Here is what I am trying to do: First I would like to say that at the first time I did not put the exact tables and fields names.
So to put thing in order: The first table name is a123_employees_punches
Fields:
id (char(36))
user_code (int(255))
The 2nd table is abc12_employees_cstm
Fields:
id_c (char(36))
usercode_c (varchar(255))
The 3rd table is abc12_employees_a123_employees_punches_1_c
fields:
abc12_employees_a123_employees_punches_1abc12_employees_ida (varchar(36))
abc12_empl4863punches_idb (varchar(36))
Environment:
Server: Localhost via UNIX socket
Server type: MariaDB
Server version: 5.5.64-MariaDB - MariaDB Server
Protocol version: 10
User: root#localhost
Server charset: UTF-8 Unicode (utf8)
The goal is to have a trigger that once a new record is inserted into a123_employees_punches table to obtain the matching id_c from abc12_employees_cstm table based on the new user_code inserted and matching usercode_c.
And then will insert into 2 fields in the abc12_employees_a123_employees_punches_1_c table (abc12_employees_a123_employees_punches_1abc12_employees_ida (varchar(36)) and abc12_empl4863punches_idb (varchar(36))
I tried this so far:
CREATE TRIGGER relate_punch_to_employee AFTER INSERT on a123_employees_punches
FOR EACH ROW
BEGIN
SELECT id_c INTO #id FROM a123_employees_punches_cstm WHERE usercode_c = NEW. user_code ;
INSERT into abc12_employees_a123_employees_punches_1_c (abc12_employees_a123_employees_punches_1abc12_employees_ida, abc12_empl4863punches_idb) VALUES (#id, NEW.id);
END$$
but it gives me the following error:
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 4

Your tables and fields don't look correct and you didn't provide the create table, so you must check the tables and statements below if they work
DELIMITER $$
CREATE TRIGGER after_punches_table_insert
AFTER INSERT
ON punches_table
FOR EACH ROW
BEGIN
SELECT Id INTO #id
FROM Employees_table
WhERE user_code = NEW. user_code ;
INSERT INTO Punches_employees_relation_table (employees_id, punches_id)
VALUES(NEW.ID,#id);
END$$
DELIMITER ;
select version();
| version() |
| :-------------------------------------- |
| 10.3.16-MariaDB-1:10.3.16+maria~stretch |
CREATE TABLE Punches_employees_relation_table (
`employees_id` INTEGER,
`punches_id` INTEGER
);
✓
CREATE TABLE Employees_table (
`Id` INTEGER,
`user_code` INTEGER
);
✓
INsERT INTO Employees_table (
`Id` ,
`user_code`
) VALUES (1,100);
✓
SELECT * FROM Employees_table;
Id | user_code
-: | --------:
1 | 100
CREATE TABLE punches_table (
`ID` INTEGER,
`user_code` INTEGER
);
✓
CREATE TRIGGER after_punches_table_insert
AFTER INSERT
ON punches_table
FOR EACH ROW
BEGIN
SET #id2 = NEW.user_code;
SELECT Id INTO #id
FROM Employees_table
WhERE user_code = NEW.user_code ;
INSERT INTO Punches_employees_relation_table (employees_id, punches_id)
VALUES(#id,NEW.ID);
END;
✓
InsERT punches_table (ID,user_code) VALUES (3,100);
✓
SELECT * FROM Punches_employees_relation_table;
employees_id | punches_id
-----------: | ---------:
1 | 3
db<>fiddle here

Related

MySql error 1064 on trigger createion with if statement

Below is the code. All I want to do is check if a quote exists and, if not, insert the record into another table.
DROP TRIGGER IF EXISTS `CB2`;
CREATE TRIGGER CB2
AFTER UPDATE
ON `quotes` FOR EACH ROW
BEGIN
IF (SELECT quoteID FROM booking WHERE quoteID <> new.`quoteID`) THEN
INSERT INTO `booking`(`Book_ID`, `Date`, `CustomerID`, `CustodianID`, `cusCntNum`, `Service`, `sAddress`, `Size`, `Comments`, `Frequency`, `Duration`, `Bdrms`, `Bathrm`, `Living Spaces`, `AppointmentStartDate`, `Time`, `ServiceDay`, `AddOns`, `Fee`, `quoteID`, `uBookingID`) VALUES (NULL, CURRENT_DATE, new.CustAccNum, new.CustodianNum, new.Contact_Number, new.ServType,new.Address, new.CommercialSize, new.Comments, new.Frequency, new.Duration, new.Bedrooms, new.Bathrooms, new.lSpaces, new.AppointmentDate, new.AppointmentTime ,DAYOFWEEK(new.AppointmentTime), new.sAddOns, new.Fee, new.quoteID,'');
END IF;
END
You need DELIMITER so that mysql can identify whyt belongs to the trigger
DROP TRIGGER IF EXISTS `CB2`;
DELIMITER //
CREATE TRIGGER CB2
AFTER UPDATE
ON `quotes` FOR EACH ROW
BEGIN
IF (SELECT quoteID FROM booking WHERE quoteID <> new.`quoteID`) THEN
INSERT INTO `booking`
(`Book_ID`, `Date`, `CustomerID`, `CustodianID`, `cusCntNum`, `Service`, `sAddress`, `Size`, `Comments`, `Frequency`, `Duration`, `Bdrms`, `Bathrm`, `Living Spaces`, `AppointmentStartDate`, `Time`, `ServiceDay`, `AddOns`, `Fee`, `quoteID`, `uBookingID`) VALUES
(NULL, CURRENT_DATE, new.CustAccNum, new.CustodianNum, new.Contact_Number, new.ServType,new.Address, new.CommercialSize, new.Comments, new.Frequency, new.Duration, new.Bedrooms, new.Bathrooms, new.lSpaces, new.AppointmentDate, new.AppointmentTime ,DAYOFWEEK(new.AppointmentTime), new.sAddOns, new.Fee, new.quoteID,'');
END IF;
END//
DELIMITER ;
You do need to set delimiters but you also need an existence check. Using a simplified version of your model
drop table if exists quotes,booking;
create table quotes(quoteid int, val int);
create table booking(quoteid int,val int);
drop trigger if exists t;
delimiter $$
CREATE TRIGGER t
AFTER UPDATE
ON `quotes` FOR EACH ROW
BEGIN
insert into debug_table(msg) values (new.quoteid);
IF not exists (SELECT quoteID FROM booking WHERE quoteID = new.`quoteID`) THEN
INSERT INTO `booking`( `quoteID`,val) VALUES (new.quoteid,new.val);
END if;
end $$
delimiter ;
truncate debug_table;
insert into quotes(quoteid) values (1),(2);
update quotes set val = 10 where quoteid = 1;
update quotes set val = 20 where quoteid = 1;
MariaDB [sandbox]> select * from booking;
+---------+------+
| quoteid | val |
+---------+------+
| 1 | 10 |
+---------+------+
1 row in set (0.001 sec)
MariaDB [sandbox]>
MariaDB [sandbox]> select * from debug_table;
+----+------+
| id | msg |
+----+------+
| 1 | 1 |
| 2 | 1 |
+----+------+
2 rows in set (0.001 sec)
You don't need the debug table but it provides proof that the trigger fired twice as expected.
BTW I'm not convinced that your logic is sound.

Using join in update command in trigger

I have 3 tables
'stockMedicina' (farmaciaID,seriemedicina,stock)
'Factura' (farmaciaid,facturaid)
'DetalleFactura' (facturaid,seriemedicina,cantidad)
and i want to update the inventory of stockMedicina which is an int named stock when i insert a new value to detalleFactura. So when i insert a new value in detalleFactura i want to update the inventory of the farmaciaid which is on the factura table to decrease the amount of stock. I have this code but it doesn't work, and i don't know what to do now. :(
DELIMITER $$;
CREATE TRIGGER diminuirStock
AFTER INSERT ON detalleFactura
FOR EACH ROW
BEGIN
UPDATE stockmedicina sm
INNER JOIN factura fa ON sm.farmaciaid = fa.farmacia
INNER JOIN detalleFactura df ON sm.seriemedicina = df.seriemedicina AND fa.facturaID=df.facturaID
SET sm.stock = sm.stock - NEW.cantidad
WHERE sm.FarmaciaID = fa.Farmacia and sm.seriemedicina=NEW.facturaID
END$$
DELIMITER ;
Any thought or help about it would be really helpful :c
Some of your columns have the false column name
Schema (MySQL v8.0)
CREATE TABLE stockMedicina (farmaciaID INT,seriemedicina INT ,stock INT);
INSERT INTO stockMedicina VALUES (1,1,10);
CREATE TABLE Factura (farmaciaid INT, faturaid INT);
INSERT INTO Factura VALUES (1,1);
CREATE TABLE DetalleFactura (facturaid INT ,seriemedicina INT ,cantidad INT);
DELIMITER $$
CREATE TRIGGER diminuirStock
AFTER INSERT ON DetalleFactura
FOR EACH ROW
BEGIN
UPDATE stockMedicina sm
INNER JOIN Factura fa ON sm.farmaciaID = fa.farmaciaid
INNER JOIN DetalleFactura df ON sm.seriemedicina = df.seriemedicina AND fa.faturaid=df.facturaID
SET sm.stock = sm.stock - NEW.cantidad
WHERE sm.FarmaciaID = fa.farmaciaid and sm.seriemedicina=NEW.facturaid;
END$$
DELIMITER ;
INSERT INTO DetalleFactura VALUES (1,1,2)
Query #1
SELECT * FROM stockMedicina;
| farmaciaID | seriemedicina | stock |
| ---------- | ------------- | ----- |
| 1 | 1 | 8 |
View on DB Fiddle

Unable to create procedure for inserting data in two tables

I have two tables tbl_pattern and tbl_pattern_features
I would like to insert the data into tbl_pattern_features against the last_insert_id of tbl_pattern.
Here is the query:
BEGIN
DROP INDEX fld_pattern_name ON tbl_pattern;
CREATE INDEX fld_pattern_name ON tbl_pattern (fld_pattern_name);
DECLARE #NewID INT(10)
IF pAction = "INSERT" THEN
INSERT INTO tbl_pattern(fld_pattern_name, fld_pattern_category, fld_pattern_utqg, pattern_image, fld_pattern_title, fld_pattern_description)
VALUES (ppattern_name, ppattern_category, ppattern_utqg, ppattern_image, ppattern_title, ppattern_descrip);
SELECT #NewID = SCOPE_IDENTITY();
INSERT INTO tbl_pattern_features(fld_pattern_id, fld_feature_name, fld_feature_description, feature_image)
VALUES (#NewID, ffeature_name, ppattern_utqg, ffeature_descrip, ffeature_image);
END IF;
END
MySQL doesn't have SCOPE_IDENTITY(). The function you are looking for is LAST_INSERT_ID()
SELECT LAST_INSERT_ID() as id
will return
+----+
| id |
+----+
| 1 |
+----+

MYSQL: INSERT + ON DUPLICATE KEY UPDATE + SELECT in *one* prepared statement? [duplicate]

Is it possible to insert a row and get the values inserted in the same query?
Something like...
INSERT INTO `items` (`item`, `number`, `state`)
(SELECT '3', `number`, `state` FROM `item_bug` WHERE `id`='3')
And then, get ID and execute a
SELECT * FROM `items` WHERE `id`='$id'
But using only one query.
Execute your insert statement and then you can do this:
SELECT * FROM `items` WHERE `id`= LAST_INSERT_ID()
you can call a stored procedure which will perform the insert and return a resultset in a single call from your app layer to mysql:
Stored procedure call
mysql> call insert_user('bar');
+---------+----------+
| user_id | username |
+---------+----------+
| 1 | bar |
+---------+----------+
1 row in set (0.02 sec)
$sqlCmd = sprintf("call insert_user('%s')", ...);
Simple example:
drop table if exists users;
create table users
(
user_id int unsigned not null auto_increment primary key,
username varchar(32) unique not null
)
engine=innodb;
drop procedure if exists insert_user;
delimiter #
create procedure insert_user
(
in p_username varchar(32)
)
begin
declare v_user_id int unsigned default 0;
insert into users (username) values (p_username);
set v_user_id = last_insert_id();
-- do more stuff with v_user_id e.g. logs etc...
select * from users where user_id = v_user_id;
end#
delimiter ;
call insert_user('bar');
No, it's not possible in MySQL (unlike PostgreSQL, SQL Server and PL/SQL in Oracle).
You will have to do it in separate queries.
You can do this using multiple statements if you like to choose that route. Firstly when you connect to your database make sure that multiple statements is set to true:
var connection = mysql.createConnection({
host: databaseHost,
user: databaseUser,
password: databasePassword,
database: databaseName,
multipleStatements: true
});
Then you can just define your sql as:
var sql = "your insert statement; your select statement";
Just separate individual statements using the semi colon. Your select result will be results[1] in this example.
if you are using php then
instead of this you can use
mysql_insert_id();
which will give the id of last inserted record.
The other data will be same as inserted.
Only id will change which you can get by mysql_insert_id()
So you do not need to run second query.

MySql: Insert a row and get the content

Is it possible to insert a row and get the values inserted in the same query?
Something like...
INSERT INTO `items` (`item`, `number`, `state`)
(SELECT '3', `number`, `state` FROM `item_bug` WHERE `id`='3')
And then, get ID and execute a
SELECT * FROM `items` WHERE `id`='$id'
But using only one query.
Execute your insert statement and then you can do this:
SELECT * FROM `items` WHERE `id`= LAST_INSERT_ID()
you can call a stored procedure which will perform the insert and return a resultset in a single call from your app layer to mysql:
Stored procedure call
mysql> call insert_user('bar');
+---------+----------+
| user_id | username |
+---------+----------+
| 1 | bar |
+---------+----------+
1 row in set (0.02 sec)
$sqlCmd = sprintf("call insert_user('%s')", ...);
Simple example:
drop table if exists users;
create table users
(
user_id int unsigned not null auto_increment primary key,
username varchar(32) unique not null
)
engine=innodb;
drop procedure if exists insert_user;
delimiter #
create procedure insert_user
(
in p_username varchar(32)
)
begin
declare v_user_id int unsigned default 0;
insert into users (username) values (p_username);
set v_user_id = last_insert_id();
-- do more stuff with v_user_id e.g. logs etc...
select * from users where user_id = v_user_id;
end#
delimiter ;
call insert_user('bar');
No, it's not possible in MySQL (unlike PostgreSQL, SQL Server and PL/SQL in Oracle).
You will have to do it in separate queries.
You can do this using multiple statements if you like to choose that route. Firstly when you connect to your database make sure that multiple statements is set to true:
var connection = mysql.createConnection({
host: databaseHost,
user: databaseUser,
password: databasePassword,
database: databaseName,
multipleStatements: true
});
Then you can just define your sql as:
var sql = "your insert statement; your select statement";
Just separate individual statements using the semi colon. Your select result will be results[1] in this example.
if you are using php then
instead of this you can use
mysql_insert_id();
which will give the id of last inserted record.
The other data will be same as inserted.
Only id will change which you can get by mysql_insert_id()
So you do not need to run second query.