代码之家  ›  专栏  ›  技术社区  ›  fmedv

SQL用符号替换HTML实体编号/代码

  •  0
  • fmedv  · 技术社区  · 6 年前

    有两个源表。

    T1级:

     ID |          Short          |        Long
    ------------------------------------------------------
    001 | Captain's Shield™ | Cool item©
    002 | Someones's Hammer®  | Even cooler item©
    

    如您所见,T1可能包含HTML实体号/代码。


      HTML  | Symbol 
    ----------------------------------
    ™ |  ™
    ®   |  ®
    ©  |  ©
    

    T2包含“所有”可能的数字/代码。


    我想做的是替换“Short”和“Long”列中出现的所有实体。

     ID |          Short          |        Long
    ------------------------------------------------------
    001 |    Captain's Shield™    | Cool item©
    002 |    Someones's Hammer®   | Even cooler item©
    

    下面是一些我尝试过但未能使其正常工作的示例代码:

    UPDATE T1, T2
    SET 
    T1.Short = replace(T1.Short, T2.HTML, T2.Symbol), 
    T1.Long = replace(T1.Long, T2.HTML, T2.Symbol)
    WHERE UseRegExp(T1.Short, "^.*&((#[0-9]{1,5})|[a-zA-Z]{1,10});.*$")<>"" Or UseRegExp(T1.Long, "^.*&((#[0-9]{1,5})|[a-zA-Z]{1,10});.*$")<>"";
    

    1 回复  |  直到 6 年前
        1
  •  0
  •   fancyPants    6 年前

    您的方法不起作用,因为结果实际上写在语句的末尾,而不是在处理每一行之后。这样,每次处理一行时,只替换与该行关联的符号。在下一行中,原始行将再次作为源,而上一行中的替换将被忽略,因此实际上您永远不会替换所有符号。

    您需要做的是多次更新表,每次都使用不同于T2的行。或者更好的是,如果T2中的所有条目不太多的话,您需要为自己构建一个包含这些条目的语句。

    您可以构建这样一个语句:

    select concat(
      repeat('replace(', count(*))
      , 't1.Short, '
      , group_concat(concat('\'', HTML, '\',\'', Symbol, '\')'))
      )
    from t2;
    

    replace(replace(replace(t1.Short, '&trade;','™'),'&reg;','®'),'&copy;','©')
    

    ( sqlfiddle )

    或者使用这个为动态sql构建一个字符串(阅读更多关于这个的内容) here )或者只需构建一次,复制它并执行查询。你的问题是

    update T1 set 
    Short = replace(replace(replace(T1.Short, '&trade;','™'),'&reg;','®'),'&copy;','©'),
    Long = replace(replace(replace(T1.Long, '&trade;','™'),'&reg;','®'),'&copy;','©');