仅使用表格中的单词列表替换精确单词

时间:2013-11-01 19:49:07

标签: oracle

这个问题是这个问题的一部分

limit records in cursor by using a variable

原始问题是一个2部分问题,1部分是,有更好的方法来做这个

我的代码可以正常工作,但速度非常慢,每条记录大约需要2秒。

所以我有一张表NR_POSTAL_ABBR,它有2个字段和大约400条记录

ReplaceWhat       ReplaceWith
Ave               Avenue
St                Street

我希望能够使用上表中的valules替换另一个表中的Address字段

所以,如果我有一个地址123 Main St - 它应该说123 Main Street

如果我有123大街 - 它应该留在123大街,它不应该成为123 Main Streetreet

地址表有几百万行,有没有快速的方法呢?

谢谢

2 个答案:

答案 0 :(得分:0)

所以你问。我的建议是通过regular expressions所以这里是你的案例的更新代码。

假设你有一个带有字段地址的表测试,你需要做的很简单,创建一个符合你要求的正则表达式。

所以:你需要替换StStreet Av的每个Avenue,这是你应该做的。

update test
   set address = 
   regexp_replace(
           regexp_replace(address, 'Av | Av$| Av ', ' Avenue ' ),
                           'St | St$| St ', ' Street ');

这是一个SQLFiddle示例

解释正则表达式:

regexp_replace根据正则表达式模式替换另一个字符串,请参阅文档:REGEXP_REPLACE

关于正则表达式,你可以在这里看到它Regular Expressions Wiki几乎每种语言都遵循POSIX模式,所以一旦你学会了它就会很好。

所以我习惯regexp_replace来达到你想要的效果,因为你提出了两个要求。我不会仅仅根据表达式来写函数的参数。

在第一个表达式中,您有'Av | Av$| Av ',表示: PS。:我只是将-放到你看空间(所以忽略它)。所以不要让我说出来。

  • -Av -(末尾有空格)=在字符串后面找一个空格Av
  • -|-(管道标志)=等于or语句
  • - Av$- =查找前面有空格的所有Av以及Av位于字符串末尾的时间。 $
  • - Av - =查找前面有空格的所有Av

    后面的空格

    然后该函数用单词Avenue替换任何一个发生的事件。请注意,我在前面和后面放了一个空格以避免Peer HarborAvenue

    之类的内容

    同样的解释是St字符串

    如果您喜欢正则表达式功能,可以在此处查看更多内容:Oracle Regular Expressions Functions

  • 答案 1 :(得分:0)

    根据Jorge的回复发布自动版本,以防有人需要。

        DECLARE
         ReplOrder NUMBER;
    BEGIN
         ReplOrder := 1;
    
    
         DECLARE
           CURSOR getReplsStrng IS
             SELECT replacewhat
                ,replacewith
               FROM analyst.NR_POSTAL_ABBR
              WHERE ReplaceOrder = ReplOrder;
         BEGIN
           FOR getInnerRec IN getReplsStrng LOOP
             --        DBMS_OUTPUT.put_line('replace what ' || getInnerRec.replacewhat);
             --        DBMS_OUTPUT.put_line('Replace Order ' || ReplOrder);
    
    
             UPDATE NR_TMP_106 tmp
                SET NewAddress = LOWER(REGEXP_REPLACE(LOWER(NewAddress)
                                      ,   '$'
                                    || getInnerRec.replacewhat
                                    || ' | '
                                    || getInnerRec.replacewhat
                                    || '$| '
                                    || getInnerRec.replacewhat
                                    || ' '
                                      ,' ' || getInnerRec.replacewith || ' '))
              WHERE     1 = 1
                 AND (   tmp.NewAddress LIKE '%' || CHR(32) || '' || getInnerRec.replacewhat || '' || NULL || '%'
                      OR tmp.NewAddress LIKE '%' || CHR(32) || '' || getInnerRec.replacewhat || '' || CHR(32) || '%'
                      OR tmp.NewAddress LIKE '%' || NULL || '' || getInnerRec.replacewhat || '' || CHR(32) || '%');
    
             COMMIT;
           END LOOP;
         END;
    
    
         ReplOrder := 2;
    
    
         DECLARE
           CURSOR getReplsStrng IS
             SELECT replacewhat
                ,replacewith
               FROM analyst.NR_POSTAL_ABBR
              WHERE ReplaceOrder = ReplOrder;
         BEGIN
           FOR getInnerRec IN getReplsStrng LOOP
             --        DBMS_OUTPUT.put_line('replace what ' || getInnerRec.replacewhat);
             --        DBMS_OUTPUT.put_line('Replace Order ' || ReplOrder);
    
    
             UPDATE NR_TMP_106 tmp
                SET NewAddress = LOWER(REGEXP_REPLACE(LOWER(NewAddress)
                                      ,   '$'
                                    || getInnerRec.replacewhat
                                    || ' | '
                                    || getInnerRec.replacewhat
                                    || '$| '
                                    || getInnerRec.replacewhat
                                    || ' '
                                      ,' ' || getInnerRec.replacewith || ' '))
                    WHERE     1 = 1
                          AND (   tmp.NewAddress LIKE '%' || CHR(32) || '' || getInnerRec.replacewhat || '' || NULL || '%'
                               OR tmp.NewAddress LIKE '%' || CHR(32) || '' || getInnerRec.replacewhat || '' || CHR(32) || '%'
                               OR tmp.NewAddress LIKE '%' || NULL || '' || getInnerRec.replacewhat || '' || CHR(32) || '%');
    
             COMMIT;
           END LOOP;
         END;
    END;