Unable to create procedure for inserting data in two tables - mysql

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

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.

How to make triggers for delete and adding with if statement MySQL?

have two table's Queue (appointment_id, actual_time) Queue_Summary (date, doctor_id, num_of_patients)
The first is all the queues there are and the second is how many queues for each doctor on a certain date. I need to build a trigger that updates the num_of_patients, every time in Queue that a queue is added I need to add to a doctor num_of_patients on that date. Also when removing.
I have just counted the number of queues given a doctor_id and date, made it into two triggers.
But the only problem I have is where do I place the if statement that checks if this date is on Queue_Summary and if not adds it.
(P.S - Im not 100% on thoes also as my database is a bit off and does tons of problems, if there are any problem in thoes statments I'll be more them happy to know)
delimiter //
CREATE TRIGGER update_queue_summary
AFTER DELETE ON queue
FOR EACH ROW
BEGIN
update queue_summary as qs set num_of_patient = (
select count(appointment_id)
from queue as q join appointment as a on appointment_id
where a.doctor_id=qs.doctor_id and date(qs.actual_time)=date(qs.date())
group by appointment_id
) where doctor_id=qs.doctor_id and date(qs.actual_time)=date(qs.date());
END;//
delimiter ;
delimiter //
CREATE TRIGGER update_queue_summary
AFTER insert ON queue
FOR EACH ROW
BEGIN
update queue_summary as qs set num_of_patient = (
select count(appointment_id)
from queue as q join appointment as a on appointment_id
where a.doctor_id=qs.doctor_id and date(qs.actual_time)=date(qs.date())
group by appointment_id
) where doctor_id=qs.doctor_id and date(qs.actual_time)=date(qs.date());
END;//
delimiter ;
You should carry out an existence test in your trigger. For example
drop table if exists queue,queue_summary;
create table queue (appointment_id int auto_increment primary key, doctor_id int,actual_time datetime);
create table Queue_Summary (date date, doctor_id int, num_of_patients int);
delimiter $$
create trigger ut after insert on queue
for each row
begin
if not exists (select 1 from queue_summary where date = date(new.actual_time) and doctor_id = new.doctor_id) then
insert into queue_summary values(date(new.actual_time),new.doctor_id,1);
else
update queue_summary
set num_of_patients = num_of_patients + 1
where date = date(new.actual_time) and doctor_id = new.doctor_id;
end if;
end $$
delimiter ;
insert into queue (doctor_id,actual_time) values(1,'2020-05-03 09:00'),(1,'2020-05-03 09:30');
select * from queue;
select * from queue_summary;
MariaDB [sandbox]> select * from queue;
+----------------+-----------+---------------------+
| appointment_id | doctor_id | actual_time |
+----------------+-----------+---------------------+
| 1 | 1 | 2020-05-03 09:00:00 |
| 2 | 1 | 2020-05-03 09:30:00 |
+----------------+-----------+---------------------+
2 rows in set (0.001 sec)
MariaDB [sandbox]> select * from queue_summary;
+------------+-----------+-----------------+
| date | doctor_id | num_of_patients |
+------------+-----------+-----------------+
| 2020-05-03 | 1 | 2 |
+------------+-----------+-----------------+
1 row in set (0.001 sec)
And a delete trigger is similar but simpler
delimiter $$
create trigger dt after delete on queue
for each row
begin
if exists (select 1 from queue_summary where date = date(OLD.actual_time) and doctor_id = old.doctor_id) then
update queue_summary
set num_of_patients = num_of_patients - 1
where date = date(old.actual_time) and doctor_id = old.doctor_id;
end if;
end $$
delimiter ;
The existence check is entirely cosmetic since a delete won't complain if there is nothing to delete.

Trigger to insert data based on a value

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

Mysql select statement only works on first iteration in while loop, insert working fine

Why is the SELECT statement inside the WHILE loop only returning value for the first iteration ?
Both of the INSERT IGNORE and the second INSERT is working, and are inserting rows equal to amount.
If I set amount to 10, I only get the results from the first inserted row. However, the procedure will INSERT amount rows to rand_strings and rand_strings_info tables.
The Procedure:
DROP PROCEDURE if exists test_while;
DELIMITER $$
CREATE PROCEDURE test_while(amount INT, description VARCHAR(255))
BEGIN
WHILE amount > 0 DO
INSERT IGNORE INTO rand_strings(rand_string) /*WORKS EVERY ITERATION*/
SELECT generate_rand_string(); /*function to generate a random string.*/
SELECT * FROM rand_strings WHERE id = LAST_INSERT_ID(); /*ONLY WORKS FIRST TIME */
INSERT INTO rand_strings_info(id, col2, col3) /*WORKS EVERY ITERATION*/
VALUES (LAST_INSERT_ID(), now(), description);
SET amount = amount - 1;
END WHILE;
END$$
DELIMITER ;
CALL test_while(10, 'This is the description of the string…')
RESULTS:
id | rand_string
1 | jgdlkjaht
Some interfaces do not show all the results as expected, but the code runs correctly.
You can see in the following SQL Fiddle that only shows the first record in the rand_strings table when stored procedure runs, but running the same code on the MySQL command line the result is as follows:
mysql> CALL `test_while`(5, 'This is the description of the string...');
+----+------------------------------------------+
| id | rand_string |
+----+------------------------------------------+
| 1 | f4c77a3155d95ad1e818b1b06a62deec8e0b6754 |
+----+------------------------------------------+
1 row in set (0.00 sec)
+----+------------------------------------------+
| id | rand_string |
+----+------------------------------------------+
| 2 | 7cbcca49596262836f5af91643303d10b3804900 |
+----+------------------------------------------+
1 row in set (0.00 sec)
+----+------------------------------------------+
| id | rand_string |
+----+------------------------------------------+
| 3 | 2ba2c7276c0b66e3dcbb971b7f54af9bced578a4 |
+----+------------------------------------------+
1 row in set (0.00 sec)
+----+------------------------------------------+
| id | rand_string |
+----+------------------------------------------+
| 4 | d52426b19a59c515b02268347c508383873d4d73 |
+----+------------------------------------------+
1 row in set (0.00 sec)
+----+------------------------------------------+
| id | rand_string |
+----+------------------------------------------+
| 5 | fbc25c6204b609e8f4f4f8a33b534bff9a011e5f |
+----+------------------------------------------+
1 row in set (0.00 sec)
Query OK, 1 row affected (0.00 sec)
UPDATE
DELIMITER $$
CREATE PROCEDURE `test_while`(`amount` INT, `description` VARCHAR(255))
BEGIN
DECLARE `_LAST_INSERT_ID`, `_first_inserted_in_this_run` INT UNSIGNED DEFAULT NULL;
CREATE TEMPORARY TABLE IF NOT EXISTS `temp_generate_rand_string` (
`insert_id` INT UNSIGNED PRIMARY KEY,
`first_inserted_in_this_run` INT UNSIGNED
) ENGINE=MEMORY;
WHILE `amount` > 0 DO
INSERT IGNORE INTO `rand_strings`(`rand_string`) /*WORKS EVERY ITERATION*/
SELECT `generate_rand_string`(); /*function to generate a random string.*/
SET `_LAST_INSERT_ID` := LAST_INSERT_ID();
IF (`_first_inserted_in_this_run` IS NULL) THEN
SET `_first_inserted_in_this_run` := `_LAST_INSERT_ID`;
END IF;
INSERT INTO `temp_generate_rand_string` (`insert_id`, `first_inserted_in_this_run`)
VALUES
(`_LAST_INSERT_ID`, `_first_inserted_in_this_run`);
-- SELECT * FROM `rand_strings` WHERE `id` = `_LAST_INSERT_ID`; /*ONLY WORKS FIRST TIME */
INSERT INTO `rand_strings_info`(`id`, `col2`, `col3`) /*WORKS EVERY ITERATION*/
VALUES (`_LAST_INSERT_ID`, NOW(), `description`);
SET `amount` := `amount` - 1;
END WHILE;
SELECT `rs`.`id`, `rs`.`rand_string`
FROM `rand_strings` `rs`
INNER JOIN `temp_generate_rand_string` `tgrs` ON
`tgrs`.`first_inserted_in_this_run` = `_first_inserted_in_this_run` AND
`rs`.`id` = `tgrs`.`insert_id`;
DELETE
FROM `temp_generate_rand_string`
WHERE `first_inserted_in_this_run` = `_first_inserted_in_this_run`;
END$$
DELIMITER ;
SQL Fiddle demo

SQL IF - ELSE Statement

I have a table like this :
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| ID | bigint(20) | NO | PRI | NULL | |
| view | bigint(20) | NO | | NULL | |
+-------+------------+------+-----+---------+-------+
Is it possible to do this with SQL's IF-ELSE statement ?
Check if there is ID=1 row in table
If there is , increase view column by 1 .
If there isn't, insert new row to table with ID=1
It should be something like this :
IF((SELECT COUNT(ID) FROM wp_viewcount WHERE ID=1) == 0)
BEGIN
INSERT INTO wp_viewcount VALUES (1,1)
END
ELSE
BEGIN
UPDATE wp_viewcount SET view=view+1 WHERE ID=1
END
The following SQL statement will result in the IF - ELSE logic you want, by using the on duplicate key syntax.
insert into wp_viewcount values(1,1) on duplicate key update view=view+1;
You can only use MySQL's if in a stored procedure. For example:
DELIMITER //
CREATE PROCEDURE `test_procedure` (IN wp_id INT)
BEGIN
IF( (SELECT COUNT(*) FROM wp_viewcount WHERE id = wp_id)<1) THEN
INSERT INTO wp_viewcount(id,view) VALUES (wp_id,1);
ELSE
UPDATE wp_viewcount SET view=view+1 WHERE ID=wp_id;
END IF;
END //
Given your use case, you might be better served by MySQL's INSERT ... ON DUPLICATE KEY UPDATE.
Why not use
if not exists (select * from wp_viewcount where id = 1)
begin
--insert logic
end
else
begin
--update logic
end