MySQL: Reversed GROUP_CONCAT failed. What's wrong? - mysql

I have a table "source" with columns id and contents.
|id|contents|
|1|Digestion is the process of turning food into fuel for energy|
|2|During the digestive process, food passes down the throat|
|3|The health of your digestive system has a lot to do with lifestyle|
I want to explode this by space.
Here is my script in MySQL workbench:
CREATE PROCEDURE explode_table ()
BEGIN
DECLARE idparagraf INTEGER;
DECLARE paragraf TEXT;
DECLARE i INTEGER;
DECLARE h INTEGER;
DECLARE Frase TEXT;
DECLARE input_text TEXT;
DECLARE segmenter VARCHAR(45);
DECLARE exit_loop BOOLEAN default FALSE;
DECLARE my_cursor CURSOR FOR SELECT id, contents FROM source;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET exit_loop = TRUE;
SET h=0;
SET i=0;
SET exit_loop=FALSE;
SET segmenter=REPLACE(segmenter, ' ', ' ');
SET input_text=REPLACE(input_text, ' ', ' ');
CREATE TEMPORARY TABLE WordList
(
ID INTEGER AUTO_INCREMENT NOT NULL,
IdParagraph INTEGER,
Words TEXT,
PRIMARY KEY (ID)
);
OPEN my_cursor;
RowByRow : LOOP
FETCH my_cursor INTO idparagraf, paragraf;
IF exit_loop THEN
SELECT * FROM WordList;
CLOSE my_cursor;
LEAVE RowByRow;
END IF;
REPEAT
SET i=i+1;
SET Frase = split_string(paragraf,' ', i);
INSERT INTO WordList
(ID, IdParagraph, Words)
VALUES
(0, idparagraf, Frase);
UNTIL i = ComplexCount(paragraf,' ')
END REPEAT;
SELECT * FROM WordList;
END LOOP RowByRow;
END
Problem probably lies on DECLARE CONTINUE HANDLER FOR NOT FOUND SET exit_loop = TRUE; or "IF exit_loop THEN" or else?
Your help will be appreciated. Please help

Related

MYSQL := is not a valid at this position, expecting an identifier

The task is create a stored procedure which creates a statistic of students by city. The result should be like - -
`
delimiter $$
create procedure courcity()
begin
declare list_stud text default '';
declare _cty varchar(50);
declare _count int;
declare _name_stud varchar(50);
declare done integer default FALSE;
declare cty_cur cursor for select cty, count(*) as count from student group by cty order by cty;
declare stud_cur cursor for select name_stud from student where cty = _cty;
declare continue handler for NOT found set done = TRUE;
create temporary table return_table(
cty varchar(50),
count_stud int,
list_stud text default ''
);
begin
declare list_stud text default '';
declare _cty varchar(50);
declare _count int;
declare _name_stud varchar(50);
declare done integer default FALSE;
declare cty_cur cursor for select cty, count(*) as count from student group by cty order by cty;
declare stud_cur cursor for select name_stud from student where cty = _cty;
open cty_cur;
open stud_cur;
read_loop: LOOP
fetch cty_cur into _cty, _count;
IF done THEN
LEAVE read_loop;
read_loop1: loop
fetch stud_cur into _name_stud;
if done then leave read_loop1;
list_stud := list_stud || _name_stud || ', ';//here is the problem
end loop;
close stud_cur;
insert into return_table values (_cty, _count, list_stud);
list_stud := '';
end loop;
close cty_cur;
select * from return_table;
end;$$
delimiter ;
`
Can't create this procedure due to this problem.Can't find mistake.
IF THEN must be closed with END IF;
https://www.mysqltutorial.org/mysql-if-statement/
IF condition THEN
statements;
END IF;
|| is definitely not correct in MySQL. on the right side of := you should have a variable or a valid expression.

MySQL cursor fetch NULL

Why both my variables output NULL? SELECT part of the cursor is working properly.
CREATE PROCEDURE p2()
BEGIN
# Account table
DECLARE accountid INT;
DECLARE accountname VARCHAR(1000);
# 1. cursor finished/done variable comes first
DECLARE done INT DEFAULT 0;
# 2. the curser declaration and select
DECLARE c_account_id_name CURSOR FOR SELECT
accountid,
accountname
FROM temp.test;
# 3. the continue handler is defined last
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = TRUE;
OPEN c_account_id_name;
SET accountid = 0;
SET accountname = '';
read_loop: LOOP
FETCH c_account_id_name
INTO accountid, accountname;
IF done
THEN
LEAVE read_loop;
END IF;
SELECT accountname;
END LOOP;
END;
Variable and select attribute in cursor can't be the same...it's a MySQL bug.
This will work
DROP PROCEDURE IF EXISTS p2;
DELIMITER $$
CREATE PROCEDURE p2()
BEGIN
# Account table
DECLARE v_accountidsome INT; #pay attention
DECLARE v_accountnameelst VARCHAR(1000); #pay attention
# 1. cursor finished/done variable comes first
DECLARE v_done INT DEFAULT FALSE;
# 2. the cursor declaration and select
DECLARE c_account_id_name CURSOR FOR SELECT
accountid, #pay attention
accountname #pay attention
FROM temp.test;
# 3. the continue handler is defined last
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET v_done = TRUE;
OPEN c_account_id_name;
read_loop: LOOP
FETCH c_account_id_name
INTO v_accountidsome, v_accountnameelst;
IF v_done
THEN
LEAVE read_loop;
END IF;
SELECT v_accountidsome;
SELECT v_accountnameelst;
END LOOP;
CLOSE c_account_id_name;
END $$
DELIMITER ;
CALL p2();
Find more here

Error in SET command in a MySQL Procedure

I wish to retrieve all distinct values of a column (Task in this case) from a table (dataset in this case). The task values will go as column name for the table that I intend to create using the procedure (albeit not defined currently but only printed). But it gives an error at the line
SET qry = CONCAT("CREATE TABLE ",tblname," ( TEAM varchar(20) PRIMARY KEY ," );
saying end was missing. When I put end it says semicolon is missing and vice-versa.
DELIMITER //
CREATE PROCEDURE `createTable` (IN tblName varchar(20))
BEGIN
DECLARE task varchar(20) DEFAULT "";
DECLARE exit_loop BOOLEAN;
SET qry = CONCAT("CREATE TABLE ",tblname," ( TEAM varchar(20) PRIMARY KEY ," );
DECLARE task_curs CURSOR FOR SELECT DISTINCT Task FROM dataset;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET exit_loop = TRUE;
OPEN task_curs;
my_loop: loop
FETCH task_curs into task;
qry=CONCAT(qry,task, ' INT DEFAULT 0, ');
IF exit_loop THEN
CLOSE task_curs;
LEAVE my_loop;
END IF;
END LOOP my_loop;
qry=TRIM(TRAILING ',' FROM qry);
qry=CONCAT(qry, ');');
SELECT qry;
END; //
DELIMITER ;
What might be possibly wrong with the syntax ? Thanks!
Try:
DELIMITER //
CREATE PROCEDURE `createTable` (IN tblName varchar(20))
BEGIN
DECLARE task varchar(20) DEFAULT "";
DECLARE exit_loop BOOLEAN;
DECLARE qry VARCHAR(500);
-- SET qry = CONCAT("CREATE TABLE ",tblname," ( TEAM varchar(20) PRIMARY KEY ," );
DECLARE task_curs CURSOR FOR SELECT DISTINCT Task FROM dataset;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET exit_loop = TRUE;
SET qry = CONCAT("CREATE TABLE ",tblname," ( TEAM varchar(20) PRIMARY KEY ," );
OPEN task_curs;
my_loop: loop
FETCH task_curs into task;
-- qry=CONCAT(qry,task, ' INT DEFAULT 0, ');
-- SET qry=CONCAT(qry,task, ' INT DEFAULT 0, ');
IF exit_loop THEN
CLOSE task_curs;
LEAVE my_loop;
END IF;
SET qry=CONCAT(qry,task, ' INT DEFAULT 0, ');
END LOOP my_loop;
-- qry=TRIM(TRAILING ',' FROM qry);
SET qry=TRIM(TRAILING ',' FROM qry);
-- qry=CONCAT(qry, ');');
SET qry=CONCAT(qry, ');');
SELECT qry;
END; //
DELIMITER ;

populating table in stored procedure, mysql

Can anyone shed light on why this will not loop through the function and populate the temp table? Ive tried a number of things and at best can only get the first value to populate. I'm trying to take a value and a ":" separated string (queried in this procedure) to populate a table so I can reference it in a larger query. The function SPLIT_STR works great on its own but I cant seem to increment value "a" so that it separates ALL values per field per value.
BEGIN
DECLARE platform_val VARCHAR(255);
DECLARE productName_val VARCHAR(255);
DECLARE no_more_rows BOOLEAN;
DECLARE num_rows INT DEFAULT 0;
DECLARE loop_cntr INT DEFAULT 0;
DECLARE str VARCHAR(255);
DECLARE a INT DEFAULT 1;
DECLARE cur1 CURSOR FOR SELECT
ProductName,
ProductPlatforms
FROM Feed
limit 10;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_more_rows = TRUE;
OPEN cur1;
select FOUND_ROWS() into num_rows;
the_loop: LOOP
FETCH cur1
INTO productName_val,
platform_val;
SET str = platform_val;
WHILE a< num_rows DO
SET str=SPLIT_STR(str,":",a);
insert into temp values (productName_val, str);
SET a=a+1;
END WHILE;
END LOOP the_loop;
END
This is the idea I came up with
CREATE PROCEDURE `col2lines`()
BEGIN
declare v_platform,v_productName,v_platformAll varchar(255) default null;
declare v_finished int default 0;
declare curs cursor for select ProductName,ProductPlatforms from Feed limit 10;
declare continue handler for not found set v_finished = 1;
drop temporary table if exists temp_table;
create temporary table temp_table (
productName varchar(255),
platform varchar(255)
);
open curs;
parent: LOOP
fetch curs into v_productName, v_platformAll;
if (v_finished = 1) then LEAVE parent; end if;
child: LOOP
set v_platform = substring_index(v_platformAll, '::', 1);
set #strlen = char_length(v_platform);
if (#strlen > 0) then
insert into temp_table values (v_productName, v_platform);
set v_platformAll = substr(v_platformAll, #strlen + 3);
iterate child;
end if;
LEAVE child;
END LOOP child;
iterate parent;
END LOOP parent;
close curs;
select * from temp_table;
END

mySQL (stored procedure) cursor infinite loop on last row

I have following code: Problem is on the last row of creature_y loop doesn't end and inserts same values (with increased guid) infinitely.
I tried few ways with changing continue handler but seems it is not that.
DELIMITER $$
DROP PROCEDURE IF EXISTS creature_copy
$$
CREATE PROCEDURE creature_copy ()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE new_guid INT(10);
-- Creature definition
DECLARE y_guid INT(10);
DECLARE y_id mediumint(8);
DECLARE y_map int(5);
DECLARE y_modelid mediumint(8);
DECLARE y_position_x float(10);
DECLARE y_position_y float(10);
DECLARE y_position_z float(10);
DECLARE y_orientation float(10);
DECLARE y_spawntimesecs INT(10);
DECLARE y_curhealth INT(10);
DECLARE y_curmana INT(10);
DECLARE y_MovementType tinyint(3);
-- waypoints definition
DECLARE w_id INT(10);
DECLARE w_point mediumint(8);
DECLARE w_position_x float(10);
DECLARE w_position_y float(10);
DECLARE w_position_z float(10);
DECLARE w_orientation float(10);
-- Generate creatures map
DECLARE creature_sel CURSOR FOR
SELECT guid,id, map, modelid, position_x, position_y, position_z, orientation, spawntimesecs, curhealth, curmana, MovementType
FROM creature_y;
-- Generate waypoints map
DECLARE waypoint_sel CURSOR FOR
SELECT id, point, position_x, position_y, position_z, orientation
FROM creature_movement
WHERE creature_movement.id = y_guid;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN creature_sel;
-- Cleanup tables before re-running
TRUNCATE creature_t;
TRUNCATE waypoint_data;
-- Set starting guid before loop
SET new_guid = 504115;
creature_loop:LOOP
if done = 1 THEN
-- set done = 0;
CLOSE creature_sel;
LEAVE creature_loop;
end if;
SET new_guid = new_guid + 1;
FETCH creature_sel INTO y_guid, y_id, y_map, y_modelid, y_position_x, y_position_y, y_position_z, y_orientation, y_spawntimesecs, y_curhealth, y_curmana, y_MovementType;
INSERT INTO creature_t(guid, id, map, modelid, position_x, position_y, position_z, orientation, spawntimesecs, curhealth, curmana, MovementType) VALUES(new_guid, y_id, y_map, y_modelid, y_position_x, y_position_y, y_position_z, y_orientation, y_spawntimesecs, y_curhealth, y_curmana, y_MovementType);
OPEN waypoint_sel;
waypoint_loop:LOOP
FETCH waypoint_sel INTO w_id, w_point, w_position_x, w_position_y, w_position_z, w_orientation;
IF done = 1 THEN
SET done = 0;
LEAVE waypoint_loop ;
END IF;
INSERT INTO waypoint_data(id, point, position_x, position_y, position_z, orientation) VALUES (new_guid, w_point, w_position_x, w_position_y, w_position_z, w_orientation);
END LOOP waypoint_loop;
CLOSE waypoint_sel;
END LOOP creature_loop;
CLOSE creature_sel;
END;
I have found solution to this.
To use 2 different continue handlers (to see whether cursor is at end) you need to split code into blocks
BLOCK1: BEGIN
DECLARE done INT DEFAULT 0;
-- First cursor
DECLARE sel CURSOR FOR
SELECT column
FROM table;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN sel;
sel_loop:LOOP
if done = 1 THEN
set done = 0;
CLOSE sel;
LEAVE sel_loop;
end if;
FETCH sel INTO variable1;
-- Do something in loop
-- Start second code-block
BLOCK2: BEGIN
DECLARE done2 INT DEFAULT 0;
-- define second cursor
DECLARE sel2 CURSOR FOR
SELECT column
FROM table
WHERE column = condition;
-- define second handler
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done2 = 1;
-- now you can make second cursor loop and it will finish properly.
OPEN sel2;
sel2_loop:LOOP
FETCH sel2 INTO variable2;
IF done2 = 1 THEN
SET done2 = 0;
LEAVE sel2_loop ;
END IF;
-- do something in second loop
END LOOP waypoint_loop;
CLOSE waypoint_sel;
-- End your code blocks and close first loop / cursor
END BLOCK2;
END LOOP sel_loop;
CLOSE sel;
END BLOCK1