I am inserting the records in mysql database using while loop.I want to chcek the check atleast one record is inserted or not. I tried below code but ROW_COUNT() give me success, if the record is not inserted.
DELIMITER $$
DROP PROCEDURE IF EXISTS test$$
CREATE PROCEDURE test()
BEGIN
DECLARE count INT DEFAULT 0;
DECLARE res varchar(255);
WHILE count < 10 DO
/**Sql statement**/
SET count = count + 1;
END WHILE;
IF ROW_COUNT() > 0 THEN
SET res = 'success';
ELSE
SET res = 'failure';
END IF;
SELECT res;
END$$
DELIMITER ;
I have a stored procedure like the following. There is an error showing at the update statement before the cursor declaration. When I remove the cursor statement, the stored procedure works fine. Why can't be there an update statement before the cursor statement?
DROP PROCEDURE IF EXISTS GenerateAlert;
DELIMITER $$
CREATE PROCEDURE GenerateAlert()
BEGIN
DECLARE done INTEGER DEFAULT FALSE;
DECLARE temp_project_id INT DEFAULT 0;
DECLARE temp_finish_time DATETIME DEFAULT NOW();
DECLARE _message_class INT DEFAULT 3;
DECLARE proj_user_id INT DEFAULT 0;
-- get message text template
DECLARE message_template VARCHAR(255) DEFAULT
(
SELECT alert_message_template FROM alerts WHERE id = 6
);
-- get maximum allowed minutes
DECLARE allowed_time INT DEFAULT
(
SELECT alert_value_1 FROM alerts WHERE id = 4
);
-- flag all messages with class 3 to deleted = true
UPDATE messages
SET is_deleted = 1
WHERE messages_class = 3;
DECLARE _cur CURSOR FOR
SELECT d.project_id, MAX(finish_time)
FROM
client_docs AS d INNER JOIN
issues AS i ON d.project_id = i.project_id INNER JOIN
working_times AS t ON i.id = t.issue_id
WHERE
d.status = 1 AND
t.finish_time IS NOT NULL AND
t.category = 1
GROUP BY d.project_id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN _cur;
read_loop: LOOP
FETCH _cur INTO temp_project_id, temp_finish_time;
IF done THEN
LEAVE read_loop;
END IF;
-- add more minutes to finish time
SET temp_finish_time = DATE_ADD(temp_finish_time, INTERVAL allowed_time MINUTE);
IF temp_finish_time < NOW() THEN
-- this project must be alerted
-- get project user
SELECT c.staff INTO proj_user_id
FROM
projects AS p INNER JOIN
clients AS c ON p.client_id = c.id
WHERE
p.id = temp_project_id;
END IF;
END LOOP read_loop;
CLOSE _cur;
END
$$
DELIMITER ;
Found the answer: The declaration statments must come before any other transactional statement in MySQL stored procedure.
SQL, missing end, but why? Second comment in the answer.
For the following MySql script Flyway produces a MySQL syntax error while running the script directly in something like Navicat works fine. Can anyone tell me why that is?
CREATE PROCEDURE RegressionTest_Genealogy (OUT Success TINYINT)
BEGIN
DECLARE MetricVerification TINYINT;
SET Success = 0;
SELECT COUNT(MERTRICID) INTO MetricVerification FROM metrics_temp WHERE lft = 0 OR rgt = 0;
IF MetricVerification = 0 THEN
SET Success = 1;
END IF;
END
You probably need to issue a delimiter change first to make this work, as per default the delimiter is ; which is contained in your procedure body.
Try this
DELIMITER //
CREATE PROCEDURE RegressionTest_Genealogy (OUT Success TINYINT)
BEGIN
DECLARE MetricVerification TINYINT;
SET Success = 0;
SELECT COUNT(MERTRICID) INTO MetricVerification FROM metrics_temp WHERE lft = 0 OR rgt = 0;
IF MetricVerification = 0 THEN
SET Success = 1;
END IF;
END //
DELIMITER ;
i have such procedure but all the time i want to execute it i get syntax error near declaring variables... can anybody tell me what i am doint wrong
i have two tables one for questions and one for answers and excel file to migrate data to this tables.
data in excel looks like this:
ID N TITLE
3 99500 question1
4
5 answer1
6 X answer2
7 answer3
DELIMITER $$
create Procedure proc_answermigration()
begin
DECLARE #i,#n,#q,#ind,#pt varchar default '';
DECLARE #done,#aord int default 0;
DECLARE cur cursor for select ID, N, question, from test.qustionmigration;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET #done = 1;
open cur;
read_loop: Loop
fetch cur into i,n,q;
IF done THEN
LEAVE read_loop;
END IF;
if n <> '' or n <> 'X'
then
select #ind = iq.question_id, #pt = iq.points from test.qustionmigration qm
inner join ilias.qpl_questions iq on qm.question = iq.question_text
where question = q
else
insert into qpl_a_sc
(
answer_id,
question_fi,
answertext,
points,
aorder,
tstamp
)
select (select sequence from qpl_a_sc_seq),
ind,
question,
pt,
aord,
'1342884200'
from test.qustionmigration
end if;
update qpl_a_sc_seq
set sequence = sequence + 1;
if #aord = 0 then set #aord = 1;
elseif #aord = 1 then set #aord = 2;
else set #aord = 0;
end loop;
CLOSE cur;
end$$
DELIMITER ;
i corrected some statements but still it has syntax error saying:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LOOP; close cur; end' at line 52
DELIMITER $$
create Procedure proc_answermigration()
begin
DECLARE i,n,q,ind,pt varchar(500) default '';
DECLARE done,aord,c int default 0;
DECLARE cur cursor for select ID, N, question from test.qustionmigration;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
open cur;
read_loop: LOOP
fetch cur into i,n,q;
IF n <> '' or n <> 'X'
then
select ind = iq.question_id, pt = iq.points from test.qustionmigration qm
inner join ilias.qpl_questions iq on qm.question = iq.question_text
where question = q;
else
insert into qpl_a_sc
(
answer_id,
question_fi,
answertext,
points,
aorder,
tstamp
)
select (select sequence from qpl_a_sc_seq),
ind,
question,
pt,
aord,
'1342884200'
from test.qustionmigration;
end IF;
update qpl_a_sc_seq
set sequence = sequence + 1;
if aord = 0 then set aord = 1;
elseif aord = 1 then set aord = 2;
else set aord = 0;
set c = c + 1;
IF done = 1 THEN
LEAVE read_loop;
END IF;
END LOOP;
close cur;
end$$
DELIMITER ;
Your last IF ELSE block is missing its END IF:
if #aord = 0 then set #aord = 1;
elseif #aord = 1 then set #aord = 2;
else set #aord = 0;
/* END IF either belongs here or after following statements, depending on your intended logic */
/* Either way, this block is unclosed when you close the loop */
end if
When the parser reads the END LOOP;, it is looking for the END IF, and reports a syntax error at LOOP.
You can't DECLARE user variables (those beginning with a #). Just SET them, or else use local variables (not beginning with a #).
I have the following bunch of code trying to update a field using 2 cursors the one inside the other. I use the first cursor just to get an id value (1st cursor) and then I get a list of other id values based on that id (2nd cursor). The problem is that the result set from the 2nd cursor contains the last id twice! I can't find the bug! Something in the loop, something in the termination variable for the 2 cursors?
Any help more than welcome! Thanks in advance!
DELIMITER $$
DROP PROCEDURE IF EXISTS updateNumberOfPoisForPlacesWithChildren$$
CREATE PROCEDURE updateNumberOfPoisForPlacesWithChildren()
BEGIN
DECLARE single_place_id INT(11);
DECLARE single_unique_parents_id INT(11);
DECLARE done, temp_number_of_pois, sum_number_of_pois INT DEFAULT 0;
DECLARE unique_parents_ids CURSOR FOR SELECT DISTINCT `parent_id` FROM `places` WHERE `parent_id` IS NOT NULL;
DECLARE temp_places_ids CURSOR FOR SELECT `id` FROM `places` WHERE `parent_id` = single_unique_parents_id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN unique_parents_ids;
main_loop_for_parent_ids : LOOP
SET sum_number_of_pois = 0;
IF done = 1 THEN
CLOSE unique_parents_ids;
LEAVE main_loop_for_parent_ids;
END IF;
IF NOT done = 1 THEN
FETCH unique_parents_ids INTO single_unique_parents_id;
OPEN temp_places_ids;
main_loop_for_places : LOOP
IF done = 1 THEN
CLOSE temp_places_ids;
LEAVE main_loop_for_places;
END IF;
IF NOT done = 1 THEN
FETCH temp_places_ids INTO single_place_id;
SELECT COUNT(`id`) INTO temp_number_of_pois FROM `pois` WHERE `place_id` = single_place_id;
SET sum_number_of_pois = sum_number_of_pois + temp_number_of_pois;
END IF;
END LOOP;
UPDATE `places` SET `number_of_pois`=sum_number_of_pois WHERE `id` = single_unique_parents_id;
END IF;
END LOOP;
END$$
DELIMITER ;
I think your problem is about here...
IF NOT done = 1 THEN
FETCH temp_places_ids INTO single_place_id;
SELECT COUNT(`id`) INTO temp_number_of_pois FROM `pois` WHERE `place_id` = single_place_id;
SET sum_number_of_pois = sum_number_of_pois + temp_number_of_pois;
END IF;
The FETCH sets DONE to be 1 when it exhausts the result set, but you proceed because you've already passed the DONE test.
Perhaps...
FETCH temp_places_ids INTO single_place_id;
IF NOT done = 1 THEN
SELECT COUNT(`id`) INTO temp_number_of_pois FROM `pois` WHERE `place_id` = single_place_id;
SET sum_number_of_pois = sum_number_of_pois + temp_number_of_pois;
END IF;