我已经编写了此查询,但是可能找不到一些逻辑错误。游标或游标中的循环永远运行,一段时间后,我得到最大结果数达到错误。
谢谢。
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_update_productsearch_datasync`()
BEGIN
DECLARE p_searchtext longtext default '';
DECLARE p_broken_str VARCHAR(1000) default '';
DECLARE p_alternative_str VARCHAR(1000) default '';
DECLARE p_item int(11) default 0;
DECLARE search_loop_finished, alternative_search_loop_finished boolean default false;
DECLARE srchbox_cur CURSOR FOR SELECT DISTINCT item, searchbox
FROM productsearch where searchbox is not null limit 10;
DECLARE continue HANDLER for NOT found SET search_loop_finished = true;
OPEN srchbox_cur;
srchbox_loop : loop
FETCH srchbox_cur INTO p_item,p_searchtext;
set p_searchtext = replace(p_searchtext,' ','|');
IF search_loop_finished then
close srchbox_cur;
leave srchbox_loop;
END IF;
drop TABLE IF EXISTS split_vals;
create temporary TABLE split_vals(vals varchar(1000));
begin_block1: begin
DECLARE loop_idx int DEFAULT 0;
declare idx int DEFAULT 0;
declare start_idx int DEFAULT 1;
declare str varchar(500);
declare cc varchar(1);
split_val_loop : loop
SET loop_idx = loop_idx+1;
set idx=idx+1;
set str = substr(p_searchtext,start_idx,idx);
set cc = substr(p_searchtext,(start_idx+idx),1);
if cc = '|' THEN
SET idx=idx+1;
set start_idx = idx + start_idx;
set idx=0;
insert INTO split_vals VALUES (str );
set str = '';
set cc = '';
elseif loop_idx = length(p_searchtext) THEN
insert INTO split_vals VALUES (str);
leave split_val_loop;
end IF;
end LOOP split_val_loop;
END begin_block1;
-- select * from split_vals;
begin_block2 : Begin
DECLARE alternative_search_cur CURSOR FOR SELECT DISTINCT vals FROM split_vals;
DECLARE continue HANDLER for NOT found SET alternative_search_loop_finished = true;
OPEN alternative_search_cur;
alternative_search_loop : loop
FETCH alternative_search_cur INTO p_alternative_str;
IF alternative_search_loop_finished then
set alternative_search_loop_finished = false;
close alternative_search_cur;
leave alternative_search_loop;
END IF;
-- select search_b from Product_Search_Alternatives where search_a = p_alternative_str;
select p_item,p_searchtext;
/*
update productsearch
set searchbox = Concat(searchbox,' ',v_alt_txt)
where item = v_item;
*/
-- select v_alt_txt;
END loop alternative_search_loop;
end begin_block2;
END loop srchbox_loop;
END
答案 0 :(得分:0)
尽管当您寻找替代匹配字符串时,您的过程在第二个块中有一些禁用的内容,但是我不确定您要获取的内容,所以我将该块大部分注释掉了。
您实际上还没有使用该项目,因此我将其删除。如果需要它,我将重新添加变量cursor和fetch,但是还需要添加要插入到SPLIT_VALS表中的列。
我的方法是使用INSTR()函数,该函数确定给定字符串或字符的第一个位置...在这种情况下,您正在寻找PIPE字符。确定之后,我将继续从字符串中删除字符串的任何部分,而只是对其进行处理,并因此继续缩小p_searchtext字符串,直到没有剩下任何东西为止。我认为您检查每个字符的逻辑一直失败,或者没有将此类项目视为双倍空格,因此创建了双倍“ ||”字符,并在循环中进行了介绍。
除了INSTR()以外,您还可以使用SUBSTRING_INDEX(str,delim,count)进行类似操作,以获取字符串,空值或找到的IF位置...希望这对您有所帮助...
CREATE DEFINER=`root`@`localhost`
PROCEDURE `sp_update_productsearch_datasync`()
BEGIN
-- regardless of any possible results,
-- prepare temp table to store string split into word parts
drop TABLE IF EXISTS split_vals;
create temporary TABLE split_vals(vals varchar(1000));
DECLARE p_searchtext longtext default '';
DECLARE search_loop_finished boolean default false;
DECLARE srchbox_cur CURSOR FOR
SELECT DISTINCT searchbox
FROM productsearch
where searchbox is not null
limit 10;
DECLARE continue HANDLER for NOT found
SET search_loop_finished = true;
open srchbox_cur;
srchbox_loop : loop
FETCH srchbox_cur INTO p_searchtext;
-- exit immediately if no result
IF search_loop_finished then
leave srchbox_loop;
END IF;
-- preset any SPACES into a common PIPE character
set p_searchtext = rtrim(replace(p_searchtext,' ','|'));
declare str varchar(500);
declare pipePos int default 0;
split_val_loop : loop
-- if no text string left to work with, exit loop
if length(p_searchtext) = 0 THEN
leave split_val_loop;
end if;
-- does the p_searchtext have any more pipe characters left in it?
set pipePos = INSTR('|', p_searchtext);
-- in case there is a double space could create "test||strings|||more"
-- you would never want to insert a "|" string value
if pipepos = 1
set p_searchtext = substr(p_searchtext, 2);
iterate split_val_loop;
end if;
-- if not, do the insert for whatever is remaining and clear flag
-- for the split_val_loop
if pipePos = 0 then
set str = p_searchtext;
-- clear text since this was the end
set p_searchtext = '';
else
-- there IS a pipe. get portion UP TO, but not including the pipe
-- do not include the pipe character in string returned
set str = left( p_searchtext, pipePos -1);
-- remove the entire length of the found string including the pipe
set p_searchtext = SUBSTR( p_searchtext, pipePos +1)
end if
-- there HAD to be something since search text was > 0
insert INTO split_vals VALUES (str);
end loop split_val_loop;
-- I would continue ALL fetched search records and split them all first
-- so you don't keep requerying the list as it grows for each 10 records
end loop srchbox_loop;
-- close cursor once out of the loop
close srchbox_cur;
-- uncomment below to pre-check results of split values
-- select * from split_vals;
-- now the next set of processing
DECLARE alternative_search_loop_finished boolean default false;
DECLARE p_alternative_str VARCHAR(1000) default '';
DECLARE alternative_search_cur CURSOR FOR
SELECT DISTINCT vals FROM split_vals;
DECLARE continue HANDLER for NOT found
SET alternative_search_loop_finished = true;
OPEN alternative_search_cur;
alternative_search_loop : loop
FETCH alternative_search_cur INTO p_alternative_str;
IF alternative_search_loop_finished then
leave alternative_search_loop;
END IF;
-- select search_b
-- from Product_Search_Alternatives
-- where search_a = p_alternative_str;
-- select p_item, p_searchtext;
/*
update productsearch
set searchbox = Concat(searchbox,' ',v_alt_txt)
where item = v_item;
*/
-- select v_alt_txt;
end loop alternative_search_loop;
-- close cursor OUT of the loop
close alternative_search_cur;
-- end of procedure
end