Reputation: 611
I noticed a very interesting (and unexpected as well) thing yesterday. I was given a task (on production environment) to update three columns of TableA (I am changing the table and column names due to some obvious reasons) by getting all the values present in dummytable. The primary key of both the tables is column A. I know that this task was very simple and could be accomplished in several ways but I chose to write a stored procedure (given below) for that.
When the stored procedure was finished executing then it was noticed that columns B, C & statusCode were having the same values (i.e. thousands of records were having identical values in these three columns). Can someone tell me what went wrong?
1) What's wrong (or missing) in this stored procedure? (Dummy table had thousands of records as well) 2) What could be the best possible way of doing this task other than creating a stored procedure?
PS: I created (executed as well) this stored procedure on production environment using MySQL workbench and I got an exception during the execution of the procedure which stated something "Lost connection to MySQL server" but I guess since I was running this procedure on the remote machine then there was no interruption on the server while the procedure was executing.
Here is my stored procedure.
DELIMITER $$
CREATE DEFINER=`ABC`@`%` PROCEDURE `RetrieveExtractionData`()
BEGIN
DECLARE claimlisttraversed BOOLEAN DEFAULT FALSE;
DECLARE a VARCHAR(20);
DECLARE b INTEGER;
DECLARE c INTEGER;
DECLARE claimlist CURSOR FOR SELECT
`dummytable`.`A`,
`dummytable`.`B`,
`dummytable`.`C`
FROM `ABC`.`dummytable`;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET claimlisttraversed = TRUE;
OPEN claimlist;
claimlistloop: LOOP
FETCH claimlist INTO a, b, c;
IF claimlisttraversed THEN
CLOSE claimlist;
LEAVE claimlistloop;
END IF;
UPDATE `ABC`.`TableA`
SET
`B` = b,
`C` = c,
`statuscode` = 'Sent'
WHERE `A` = a;
END LOOP claimlistloop;
END
Upvotes: 0
Views: 163
Reputation: 3659
For your first question:
1) What's wrong (or missing) in this stored procedure? (Dummy table had thousands of records as well)
I guess you forgot to CLOSE
the CURSOR
. Right after you end the LOOP
, you should CLOSE
the CURSOR
.
END LOOP claimlistloop;
CLOSE claimlist;
END
2) What could be the best possible way of doing this task other than creating a stored procedure?
Doing that in the STORED PROCEDURE
should be fine. And also using CURSOR
would be fine since you will just execute the procedure once (I guess because this is a production fix).
But from your question, you just want to update TableA
based from the provided DummyTable
. I assume that these tables have the same columns.
So I think this query is better than the CURSOR
:
UPDATE TableA A
INNER JOIN DummyTable D ON D.A = A.A
SET A.B = D.B
, A.C = D.C
, A.statuscode = 'Sent';
But please try it first on a backup or dummy table. I haven't tested it yet.
Upvotes: 1
Reputation: 92785
1) What's wrong (or missing) in this stored procedure? (Dummy table had thousands of records as well)
2) What could be the best possible way of doing this task other than creating a stored procedure?
IMHO the most important thing that you're currently missing is that you don't need any cursors for that. Your whole stored procedure is one UPDATE
statement. Execute it alone or wrap it in a stored procedure
CREATE PROCEDURE RetrieveExtractionData()
UPDATE TableA a JOIN dummytable d
ON a.a = d.a
SET a.b = d.b, a.c = d.c, a.statuscode = 'Sent';
You don't even need to change a delimiter and use BEGIN ... END
block
Here is SQLFiddle demo.
Upvotes: 1
Reputation: 51888
Forget the cursor. In fact you should never use a cursor if it's avoidable. Cursors are incredibly slow.
Simply do
UPDATE
yourTable yt
INNER JOIN dummyTable dt ON yt.A = dt.A
SET
yt.B = dt.B,
yt.C = dt.C;
and you're fine.
Upvotes: 1