Mysql:根据另一个表的信息替换一个表中的字符串

时间:2014-06-01 05:51:02

标签: mysql sql string sql-update str-replace

我有以下问题,这将是很长的,我想在我的问题中准确地告诉我对我的问题的所有了解。

我有一个表,field_body_value,有两个字段,body_value和body_summary,包含格式为" / webfm_send / ### 34;的字符串。其中#是一个数字。

我有另一个名为webfm_file的表,其中我有两个字段,其中包含字符串替换信息:第一个名为fid,它是我之前提到的数字#,第二个叫做fpatch,给了我一个保存路径的字符串(例如/data/html/files/file1.pdf),它必须替换第一个表中的/ webfm_send /#。数字#超过webfm_file的记录,但有跳转,即它们增加但缺少#所以最终的#不等于webfm_file中的记录数

所以我认为策略是建立一个遍历第二个表的过程,并在序列的每一步检索fid / fpath对,搜索" / webfm_send / fid"在第一个表中,并在第一个表中用fpath替换它。

所以这是我能用我的编码到达的目的:

BEGIN
  DECLARE v1 INT DEFAULT 0;
  SELECT COUNT(*) INTO @numrec FROM `webfm_file`;
  WHILE v1 < @numrec DO
    SELECT fpath,fid INTO @path,@file FROM `webfm_file` LIMIT v1,1;
    SET @webfm = concat('/webfm_send/',@file);
    SET @cpath = concat('/',@path);
    UPDATE `field_data_body`
    SET body_value = replace(body_value, @webfm, @cpath),  
    body_summary = replace(body_summary, @webfm, @cpath)
    WHERE body_value LIKE concat('%',@webfm,'%') OR 
    body_summary LIKE concat('%',@webfm,'%');
    SET v1 = v1 + 1;
  END WHILE;
END

让我解释一下我认为我正在使用上面的代码:

1)我检索循环的webfm_file中的记录数。

2)第一个SELECT从webfm_file获取fpath / fid中的一对,使用LIMIT v1,1我一次只检查一条记录,我检查它是否正常工作,while循环遍历webfm_file的每条记录,记录是正确检索。

3)接下来的两个&#34;设置&#34;修复一对字符串@file / @path来创建@webfm whith是它在body_body_value中写入body_value的方式,并在@cpath前面放一个斜杠,这是我最终需要这个字符串的方式。

4)然后是UPDATE,它实际上会替换字符串,如果它在body_body_ body或body_ummary of field_body_data中找到它。

预期:/ webfm_send /#的每个实例都被webfm_file中#(fid)的相应fpath对替换

我实际得到的:/ webfm_send /#的所有外观,无论#的值是否被webfm_file的记录1中的fpath值替换。

我尝试过的事情:

1)取出&#34; WHERE&#34; UPDATE语句中的子句,我认为并不是绝对必要的,因为替换函数已经负责找到匹配但可以加快速度。相同的结果

2)将循环重新绑定到webfm_file的单个记录上。这里它可以替换相应的单个检索对fid / fpath,在body_value和body_summary的两个实例中,在field_body_data中,其中fid =#出现在字符串webfm_send /#

感谢您在此之前解释我的解释,并提前感谢任何提示。

1 个答案:

答案 0 :(得分:0)

您可以使用游标迭代替换字符串。 (使用group_concat有更快的方法,并且在通用语言而不是存储过程中更容易实现)。一般的游标方法是:

drop procedure if exists proc;
delimiter //

create procedure proc()
begin
  declare done boolean default 0;
  declare path varchar(255);
  declare id int;
  declare cur cursor for select fpath, fid from webfm_file order by fid desc;
  declare continue handler for sqlstate '02000' set done = 1;

  open cur;

  block: loop
    fetch cur into path, id;

    if done then
      leave block;
    end if;

    set @from = concat('/webfm_send/', id);

    update field_data_body set
      body_value = replace(body_value, @from, path),
      body_summary = replace(body_summary, @from, path);
  end loop;

  close cur;
end//

delimiter ;

call proc();