mysql insert trigger only if not duplicate - mysql

I am little bit confused with the usage of trigger event to get expected result
Here main table is fee. The structure is as follow
Fee
id | rn | fid | amount | f_month | year
====================================================
1 | 1 | 1 | 150000 | 1 | 1
2 | 1 | 2 | 50000 | 1 | 1
3 | 2 | 1 | 550500 | 2 | 1
4 | 2 | 2 | 200 | 2 | 1
5 | 3 | 1 | 550500 | 2 | 1
And the simply insert trigger has been used.
DROP TRIGGER IF EXISTS `insertinv`;
CREATE DEFINER=`root`#`localhost` TRIGGER `insertinv`
AFTER INSERT ON `fee` FOR EACH ROW INSERT INTO invoice VALUES(null, NEW.rn, NEW.year, '')
The output what I am getting
Invoice
inv | rn | y_d | status
==============================
1 | 1 | 1 | 0
2 | 1 | 1 | 0
3 | 2 | 1 | 0
4 | 2 | 1 | 0
5 | 3 | 1 | 0
But I want to apply condition
if fee.rn AND fee.f_month AND fee.year is same then stop to insert. I mean ignore the fee.fid.
and achieve following result. The expected one
Invoice
inv | rn | y_d | status
==============================
1 | 1 | 1 | 0
2 | 2 | 1 | 0
3 | 3 | 1 | 0
In trigger table inv is primary key and auto increment

Check if a inv exists for a matching year and rn.
If it does not exist, then use the insert statement.
Do the following:
DELIMITER $$
DROP TRIGGER IF EXISTS `insertinv` $$
CREATE DEFINER=`root`#`localhost` TRIGGER `insertinv`
AFTER INSERT ON `fee`
FOR EACH ROW
BEGIN
/* Declare a variable to store invoice id for matching year and rn */
DECLARE inv_exists INT(11) DEFAULT 0;
/* Fetch the invoice id if exists */
SELECT inv INTO inv_exists
FROM invoice
WHERE rn = NEW.rn AND
y_d = NEW.year;
/* if no invoice exists then insert into the table */
IF NOT(inv_exists > 0) THEN
/* Insert statement */
INSERT INTO invoice VALUES(null, NEW.rn, NEW.year, '') ;
END IF;
END $$
DELIMITER ;

Related

Increment value depending other one

Let's assume I have the table:
id | val_1 | val_2
1 | 1 | 0
2 | 1 | 1
3 | 1 | 2
4 | 2 | 0
val_2 should be zero at first if there was no rows with val_1 before. Otherwise it should be previous val_2 + 1 for this val_1.
I can't figure it out by myself the best way to do it. The one thing I've invented is trigger after insert, but I think here maybe some other way to do it cleaner and faster?
My code is something like:
DELIMITER $$
CREATE TRIGGER after_table_insert
AFTER INSERT
ON table FOR EACH ROW
BEGIN
UPDATE table SET val_2 = t.val_2 + 1
FROM (
SELECT val_2 FROM table WHERE val_1 = new.val_1 ORDER BY id DESC LIMIT 1
) t
WHERE id = new.id;
END$$
DELIMITER ;
I will appreciate for any help!
Have a great day/night.
You have couple of issues with such setup:
What's going on if you UPDATE or DELETE rows? It can mess up everything with val2. Be careful with that.
Val2 can always be calculated and there is no need to store it.
Having said that, below I will show you a setup with which I will store only id and val1. Then val2 will be calculated within the SELECT statement (so it will always be correct).
CREATE TABLE vals(
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
val INT NOT NULL
);
INSERT INTO vals(val) VALUES(1),(1),(1),(2);
Now what I am going to do is to use the ROW_NUMBER() function (which prints the row number) and run it over a PARTITION BY val:
SELECT id, val,
ROW_NUMBER() OVER (
PARTITION BY val
) AS val2
FROM vals;
We are almost there. Sadly it will offset them by 1 compared to what you need:
+----+-----+------+
| id | val | val2 |
+----+-----+------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 2 | 1 |
+----+-----+------+
The fix is simple. Just add "-1" to it and you are ready.
SELECT id, val,
-1+ROW_NUMBER() OVER (
PARTITION BY val
) AS val2
FROM vals;
This will produce:
+----+-----+------+
| id | val | val2 |
+----+-----+------+
| 1 | 1 | 0 |
| 2 | 1 | 1 |
| 3 | 1 | 2 |
| 4 | 2 | 0 |
+----+-----+------+
With this solution there is no need to store val2 at all (you can create it as a VIEW if you wish) and it is not vulnerable to the issue when you delete a row (it will continue to work properly).
This is one possibility
Schema (MySQL v5.7)
CREATE TABLE table1 (
`id` INTEGER,
`val_1` INTEGER,
`val_2` INTEGER
);
DELIMITER //
CREATE TRIGGER after_table_insert
BEFORE INSERT
ON table1 FOR EACH ROW
BEGIN
SET #maxval2 = 0;
SELECT max(val_2) + 1 into #maxval2 FROM table1 WHERE val_1 = new.val_1;
IF #maxval2 IS NULL THEN
SET #maxval2 = 0;
END IF;
SET NEW.val_2 = #maxval2;
END//
DELIMITER ;
INSERT INTO table1
(`id`, `val_1`, `val_2`)
VALUES
('1', '1', '0'),
('2', '1', '0'),
('3', '1', '0'),
('4', '2', '0'),
('4', '2', '0');
Query #1
SELECT * FROM table1;
| id | val_1 | val_2 |
| --- | ----- | ----- |
| 1 | 1 | 0 |
| 2 | 1 | 1 |
| 3 | 1 | 2 |
| 4 | 2 | 0 |
| 4 | 2 | 1 |
View on DB Fiddle

How do I update a column based on the previous value?

I have read a lot of answers here but I couldn't adapt to my needs.
I have this table below where I would like to update the BALANCE column:
balance = old.balance + new.amount
+----+----------------+---------+------------+-------------+---------------------+------------------+--------+----------+---------+
| ID | TRANSACTION_ID | BANK_ID | ACCOUNT_ID | CUSTOMER_ID | CREATED | DESCRIPTION | AMOUNT | CURRENCY | BALANCE |
+----+----------------+---------+------------+-------------+---------------------+------------------+--------+----------+---------+
| 1 | T1 | 2 | 2 | 1 | 2018-04-22 00:00:00 | TRANSACTION TEST | 100.00 | GBP | NULL |
| 2 | T2 | 2 | 2 | 1 | 2018-04-22 00:00:00 | TRANSACTION TEST | 125.00 | GBP | NULL |
| 3 | T3 | 2 | 2 | 1 | 2018-04-22 00:00:00 | TRANSACTION TEST | -73.00 | GBP | NULL |
+----+----------------+---------+------------+-------------+---------------------+------------------+--------+----------+---------+
This is the result I would like is shown below:
I got it executing:
SET #balance:=0;
UPDATE TRANSACTIONS SET BALANCE = (#balance := #balance + AMOUNT) WHERE ID > 0;
There is no way to fire the statement above after a new column inserted?
+----+----------------+---------+------------+-------------+---------------------+------------------+--------+----------+---------+
| ID | TRANSACTION_ID | BANK_ID | ACCOUNT_ID | CUSTOMER_ID | CREATED | DESCRIPTION | AMOUNT | CURRENCY | BALANCE |
+----+----------------+---------+------------+-------------+---------------------+------------------+--------+----------+---------+
| 1 | T1 | 2 | 2 | 1 | 2018-04-22 00:00:00 | TRANSACTION TEST | 100.00 | GBP | 100.00 |
| 2 | T2 | 2 | 2 | 1 | 2018-04-22 00:00:00 | TRANSACTION TEST | 125.00 | GBP | 225.00 |
| 3 | T3 | 2 | 2 | 1 | 2018-04-22 00:00:00 | TRANSACTION TEST | -73.00 | GBP | 152.00 |
+----+----------------+---------+------------+-------------+---------------------+------------------+--------+----------+---------+
I tried using trigger:
DELIMITER $$
CREATE TRIGGER updateBalance AFTER INSERT ON TRANSACTIONS
FOR EACH ROW
BEGIN
SET NEW.BALANCE = BALANCE + NEW.AMOUNT;
END $$
DELIMITER ;
And I got the error:
Error Code: 1362. Updating of NEW row is not allowed in after trigger
I am new in SQL and MySQL and I believe this is a common task for advanced users.
Values that can be calculated from other (materialized) values shouldn't be materialized as this can lead to inconsistencies.
Remove the column all together.
ALTER TABLE transactions
DROP balance;
And create a view instead:
CREATE VIEW transactions_with_balance
AS
SELECT t1.*,
(SELECT sum(t2.amount)
FROM transactions t2
WHERE t2.bank_id = t1.bank_id
AND t2.account_id = t1.account_id
AND t2.id <= t1.id) balance
FROM transactions t1;
db<>fiddle
If you're using MySQL version 8 or higher you can also replace the subquery by the windowed version of sum()
CREATE VIEW transactions_with_balance
AS
SELECT t1.*,
sum(amount) OVER (PARTITION BY t1.bank_id,
t1.account_id
ORDER BY t1.id) balance
FROM transactions t1;
db<>fiddle
The column customer_id also seems misplaced in the table as I suppose there is an account table where the customer that account belongs to is stored in a foreign key to the customer table. So you can get the customer via the accoount_id.
You can do this with a BEFORE INSERT trigger, summing all the transaction amounts for the given CUSTOMER_ID and adding the new AMOUNT value to get the balance:
DELIMITER $$
CREATE TRIGGER updateBalance BEFORE INSERT ON transactions
FOR EACH ROW
BEGIN
SET NEW.BALANCE = NEW.AMOUNT +
COALESCE((SELECT SUM(AMOUNT)
FROM transactions
WHERE CUSTOMER_ID = NEW.CUSTOMER_ID), 0);
END $$
DELIMITER ;
Demo on dbfiddle
Note you may want to further qualify the sum with
AND BANK_ID = NEW.BANK_ID
and/or
AND ACCOUNT_ID = NEW.ACCOUNT_ID
as necessary to distinguish exactly which records to read the previous transactions from.

Join a table and calculate a percentage from this new table

I'm trying to make a report of financial datas for my company:
I have actually two two tables:
___BillableDatas:
|--------|------------|----------|----------|--------------|---------------------|
| BIL_Id | BIL_Date | BIL_Type | BIL_Rate | BIL_Quantity | BIL_ApplicableTaxes |
|--------|------------|----------|----------|--------------|---------------------|
| 1 | 2017-01-01 | Night | 95 | 1 | 1 |
| 2 | 2017-01-02 | Night | 95 | 1 | 1 |
| 3 | 2017-01-15 | Night | 105 | 1 | 1 |
| 4 | 2017-01-15 | Item | 8 | 2 | 1,2 |
| 5 | 2017-02-14 | Night | 95 | 1 | 1 |
| 6 | 2017-02-15 | Night | 95 | 1 | 1 |
| 7 | 2017-02-16 | Night | 95 | 1 | 1 |
| 8 | 2017-03-20 | Night | 89 | 1 | 1 |
| 9 | 2017-03-21 | Night | 89 | 1 | 1 |
| 10 | 2017-03-21 | Item | 8 | 3 | 1,2 |
|--------|------------|----------|----------|--------------|---------------------|
___SalesTaxes:
|--------|------------|
| STX_Id | STX_Amount |
|--------|------------|
| 1 | 14.00 |
| 2 | 5.00 |
|--------|------------|
I need to know for each month the sum of my revenue with and without taxes.
Actually I can make the report but don't know how to loop into the ___SalesTaxes table.
What I have actually:
SELECT month(BIL_Date) AS month,
sum(BIL_Rate * BIL_Quantity) AS sumval
FROM `___BillableDatas`
WHERE BIL_Date BETWEEN "2017-01-01" AND "2017-12-31"
AND BIL_Type = "Night" OR BIL_Type = "Item"
GROUP BY year(BIL_Date), month(BIL_Date)
Thanks for your help.
as kbball mentioned you have an unresolved many to many relationship in your main table. A proper table should never be designed to have more than one value per field. Resolving many to many relationships is quite simple. You will need to create a new table something like bill_taxType or some relation like that. The new table would have two fields as well as the standard primary key, it will have bill_id and applicable tax id. In the case of your 1,2 fields like bill id 4 in the new table it will look like
primary key, bill id, applicable tax id
1 4 1
2 4 2
In your final query you will join all three together on the appropriate primary key-foreign key relationship. This final query should have the data that you need.
This will work, I've created following example will help you lot for debugging and implementation. try to implement as below :
If(OBJECT_ID('tempdb..#___BillableDatas') Is Not Null)
Begin
Drop Table #___BillableDatas
End
If(OBJECT_ID('tempdb..#___SalesTaxes') Is Not Null)
Begin
Drop Table #___SalesTaxes
End
CREATE TABLE #___BillableDatas
(
BIL_Id INT IDENTITY (1,1),
BIL_Date DATETIME,
BIL_Type VARCHAR(50),
BIL_Rate FLOAT,
BIL_Quantity INT,
BIL_ApplicableTaxes VARCHAR(10)
);
INSERT INTO #___BillableDatas (BIL_Date,BIL_Type,BIL_Rate,BIL_Quantity,BIL_ApplicableTaxes)
VALUES ('2017-01-01','Night',95,1,'1'),
('2017-01-02','Night',95,1,'1'),
('2017-01-15','Night',105,1,'1'),
('2017-01-15','Item',8,2,'1,2'),
('2017-02-14','Night',95,1,'1'),
('2017-02-15','Night',95,1,'1'),
('2017-02-16','Night',95,1,'1'),
('2017-03-20','Night',89,1,'1'),
('2017-03-21','Night',89,1,'1'),
('2017-03-21','Item',8,1,'1,2')
CREATE TABLE #___SalesTaxes
(
STX_Id INT IDENTITY (1,1),
STX_Amount FLOAT
);
INSERT INTO #___SalesTaxes (STX_Amount) VALUES (14.00),(5.00)
-----------------------------------------------------------------
SELECT * FROM #___BillableDatas
SELECT * FROM #___SalesTaxes
SELECT MONTH(BD.BIL_Date) AS [Month],SUM(BD.BIL_Rate * BD.BIL_Quantity) AS 'Without Tax'
,(SUM(BD.BIL_Rate * BD.BIL_Quantity)+((SUM(BD.BIL_Rate * BD.BIL_Quantity)/100)*BD.Tax1)) AS 'With Tax 1'
,(SUM(BD.BIL_Rate * BD.BIL_Quantity)+((SUM(BD.BIL_Rate * BD.BIL_Quantity)/100)*BD.Tax2)) AS 'With Tax 2'
FROM
(
SELECT *,
(SELECT ST1.STX_Amount FROM Func_Split(BIL_ApplicableTaxes,',') AS F LEFT JOIN #___SalesTaxes AS ST1 ON F.Element=ST1.STX_Id WHERE F.Element='1') AS Tax1 ,
(SELECT ST1.STX_Amount FROM Func_Split(BIL_ApplicableTaxes,',') AS F LEFT JOIN #___SalesTaxes AS ST1 ON F.Element=ST1.STX_Id WHERE F.Element='2') AS Tax2
FROM #___BillableDatas) AS BD
WHERE BD.BIL_Date BETWEEN '2017-01-01' AND '2017-12-31' AND BD.BIL_Type = 'Night' OR BD.BIL_Type = 'Item'
GROUP BY YEAR(BD.BIL_Date), MONTH(BD.BIL_Date),BD.Tax1,BD.Tax2
You will require function Func_Split for above solution, use this :
CREATE FUNCTION [dbo].[func_Split]
(
#DelimitedString varchar(8000),
#Delimiter varchar(100)
)
RETURNS #tblArray TABLE
(
ElementID int IDENTITY(1,1), -- Array index
Element varchar(1000) -- Array element contents
)
AS
BEGIN
-- Local Variable Declarations
-- ---------------------------
DECLARE #Index smallint,
#Start smallint,
#DelSize smallint
SET #DelSize = LEN(#Delimiter)
-- Loop through source string and add elements to destination table array
-- ----------------------------------------------------------------------
WHILE LEN(#DelimitedString) > 0
BEGIN
SET #Index = CHARINDEX(#Delimiter, #DelimitedString)
IF #Index = 0
BEGIN
INSERT INTO
#tblArray
(Element)
VALUES
(LTRIM(RTRIM(#DelimitedString)))
BREAK
END
ELSE
BEGIN
INSERT INTO
#tblArray
(Element)
VALUES
(LTRIM(RTRIM(SUBSTRING(#DelimitedString, 1,#Index - 1))))
SET #Start = #Index + #DelSize
SET #DelimitedString = SUBSTRING(#DelimitedString, #Start , LEN(#DelimitedString) - #Start + 1)
END
END
RETURN
END

How i can add more condition to mysql query?

Table name is Sample
id name status date
1 ddd 1 2015-03-11
2 dddd 1 2015-03-12
3 dfdfgfg 0 2015-03-11
4 ererre 1 2015-03-19
5 eeeerer 0 2015-03-03
Here is the table, - this is query I am adding to get the result. I want the result from the table where date should not be expired if the status is set to 1 and no condition if the status is zero. So it should display. So I made the query like this
select * from sample where status='1' AND date>Now() OR status='0'
I am getting the result as like this which is correct
3 dfdfgfg 0 2015-03-11
4 ererre 1 2015-03-19
5 eeeerer 0 2015-03-03
But I want to add more queries to the same, how i can add more condition to above query?
You have to put the old condition and the new one in parenthesis , then use an AND to link them:
select * from sample
where (status='1' AND date>Now() OR status='0')
AND (new condition 1)
AND (new condition 2) ...
SELECT * FROM TABLE_NAME WHERE expiry_date > NOW()
Try using Union / Union All which soever suffice your requirement
Sample code with example from your data
create table sample(id INT,name CHAR(10), status INT, date_e DATE);
INSERT INTO sample VALUES(1, 'ddd',1,'2015-03-11');
INSERT INTO sample VALUES(2, 'dddd',1,'2015-03-12');
INSERT INTO sample VALUES(3, 'dfdfgfg',0,'2015-03-11');
INSERT INTO sample VALUES(4, 'ererre',1,'2015-03-19');
INSERT INTO sample VALUES(5, 'eeeerer',0,'2015-03-03');
SELECT * FROM sample;
+------+---------+--------+------------+
| id | name | status | date_e |
+------+---------+--------+------------+
| 1 | ddd | 1 | 2015-03-11 |
| 2 | dddd | 1 | 2015-03-12 |
| 3 | dfdfgfg | 0 | 2015-03-11 |
| 4 | ererre | 1 | 2015-03-19 |
| 5 | eeeerer | 0 | 2015-03-03 |
+------+---------+--------+------------+
5 rows in set (0.00 sec)
mysql> select * from sample where status='1' AND date_e>Now()
-> UNION ALL
-> select * from sample where status='0';
+------+---------+--------+------------+
| id | name | status | date_e |
+------+---------+--------+------------+
| 4 | ererre | 1 | 2015-03-19 |
| 3 | dfdfgfg | 0 | 2015-03-11 |
| 5 | eeeerer | 0 | 2015-03-03 |
+------+---------+--------+------------+
3 rows in set (0.00 sec)

Find and Delete Duplicate rows in MySQL

I'm having trouble finding duplicates in a database table with the following setup:
==========================================================================
| stock_id | product_id | store_id | stock_qty | updated_at |
==========================================================================
| 9990 | 51 | 1 | 13 | 2014-10-25 16:30:01 |
| 9991 | 90 | 2 | 5 | 2014-10-25 16:30:01 |
| 9992 | 161 | 1 | 3 | 2014-10-25 16:30:01 |
| 9993 | 254 | 1 | 18 | 2014-10-25 16:30:01 |
| 9994 | 284 | 2 | 12 | 2014-10-25 16:30:01 |
| 9995 | 51 | 1 | 11 | 2014-10-25 17:30:02 |
| 9996 | 90 | 2 | 5 | 2014-10-25 17:30:02 |
| 9997 | 161 | 1 | 3 | 2014-10-25 17:30:02 |
| 9998 | 254 | 1 | 16 | 2014-10-25 17:30:02 |
| 9999 | 284 | 2 | 12 | 2014-10-25 17:30:02 |
==========================================================================
Stock updates are imported into this table every hour, I'm trying to find duplicate stock entries (any rows which have a matching product id and store id) so I can delete the oldest. The query below is my attempt, by comparing product ids and store ids on a join like this I can find one set of duplicates:
SELECT s.`stock_id`, s.`product_id`, s.`store_id`, s.`stock_qty`, s.`updated_at`
FROM `stock` s
INNER JOIN `stock` j ON s.`product_id`=j.`product_id` AND s.`store_id`=j.`store_id`
GROUP BY `stock_id`
HAVING COUNT(*) > 1
ORDER BY s.updated_at DESC, s.product_id ASC, s.store_id ASC, s.stock_id ASC;
While this query will work, it doesn't find ALL duplicates, only 1 set, which means if an import goes awry and isn't noticed until the morning, there's a possibility that we'll be left with tons of duplicate stock entries. My MySQL skills are sadly lacking and I'm at a complete loss about how to find and delete all duplicates in a fast, reliable manner.
Any help or ideas are welcome. Thanks
You can use this query:
DELETE st FROM stock st, stock st2
WHERE st.stock_id < st2.stock_id AND st.product_id = st2.product_id AND
st.store_id = st2.store_id;
This query will delete older record having same product_id and store_id and will keep latest record.
A self join on store_id, product_id and 'is older' in combination with DISTINCT should give you all rows where also a newer version exists:
> SHOW CREATE TABLE stock;
CREATE TABLE `stock` (
`stock_id` int(11) NOT NULL,
`product_id` int(11) DEFAULT NULL,
`store_id` int(11) DEFAULT NULL,
`stock_qty` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`stock_id`)
> select * from stock;
+----------+------------+----------+-----------+---------------------+
| stock_id | product_id | store_id | stock_qty | updated_at |
+----------+------------+----------+-----------+---------------------+
| 1 | 1 | 1 | 1 | 2001-01-01 12:00:00 |
| 2 | 2 | 2 | 1 | 2001-01-01 12:00:00 |
| 3 | 2 | 2 | 1 | 2002-01-01 12:00:00 |
+----------+------------+----------+-----------+---------------------+
> SELECT DISTINCT s1.stock_id, s1.store_id, s1.product_id, s1.updated_at
FROM stock s1 JOIN stock s2
ON s1.store_id = s2.store_id
AND s1.product_id = s2.product_id
AND s1.updated_at < s2.updated_at;
+----------+----------+------------+---------------------+
| stock_id | store_id | product_id | updated_at |
+----------+----------+------------+---------------------+
| 2 | 2 | 2 | 2001-01-01 12:00:00 |
+----------+----------+------------+---------------------+
> DELETE stock FROM stock
JOIN stock s2 ON stock.store_id = s2.store_id
AND stock.product_id = s2.product_id
AND stock.updated_at < s2.updated_at;
Query OK, 1 row affected (0.02 sec)
> select * from stock;
+----------+------------+----------+-----------+---------------------+
| stock_id | product_id | store_id | stock_qty | updated_at |
+----------+------------+----------+-----------+---------------------+
| 1 | 1 | 1 | 1 | 2001-01-01 12:00:00 |
| 3 | 2 | 2 | 1 | 2002-01-01 12:00:00 |
+----------+------------+----------+-----------+---------------------+
Or you can use a stored Procedure:
DELIMITER //
DROP PROCEDURE IF EXISTS removeDuplicates;
CREATE PROCEDURE removeDuplicates(
stockID INT
)
BEGIN
DECLARE stockToKeep INT;
DECLARE storeID INT;
DECLARE productID INT;
-- gets the store and product value
SELECT DISTINCT store_id, product_id
FROM stock
WHERE stock_id = stockID
LIMIT 1
INTO
storeID, productID;
SELECT stock_id
FROM stock
WHERE product_id = productID AND store_id = storeID
ORDER BY updated_at DESC
LIMIT 1
INTO
stockToKeep;
DELETE FROM stock
WHERE product_id = productID AND store_id = storeID
AND stock_id != stockToKeep;
END //
DELIMITER ;
And afterwards call it for every pair of the product id and store id via a cursor procedure:
DELIMITER //
CREATE PROCEDURE updateTable() BEGIN
DECLARE done BOOLEAN DEFAULT FALSE;
DECLARE stockID INT UNSIGNED;
DECLARE cur CURSOR FOR SELECT DISTINCT stock_id FROM stock;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := TRUE;
OPEN cur;
testLoop: LOOP
FETCH cur INTO stockID;
IF done THEN
LEAVE testLoop;
END IF;
CALL removeDuplicates(stockID);
END LOOP testLoop;
CLOSE cur;
END//
DELIMITER ;
And then just call the second procedure
CALL updateTable();