0

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

使用变量限制游标中的记录

最初的问题是一个 2 部分的问题,1 部分是,有没有更好的方法来做到这一点

我有有效的代码,但它非常慢,每条记录大约 2 秒。

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

ReplaceWhat       ReplaceWith
Ave               Avenue
St                Street

我希望能够用上表中的值替换另一个表中的地址字段

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

如果我有 123 Main Street - 它应该保留 123 Main Street,它不应该变成 123 Main Streetreet

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

谢谢你

4

2 回答 2

0

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

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

所以:你需要更换每一个St,因为这是你应该做的StreetAvAvenue

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

这是一个SQLFiddle示例

解释正则表达式:

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

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

所以我习惯于regexp_replace实现你想要的,因为你给出了两个要求。我不会只写表达式的函数参数。

在您的第一个表达式中'Av | Av$| Av ',这意味着: PS.:我把-刚才给您看到的空间(所以忽略它)。所以不会让我说的。

  • -Av -(末尾有一个空格)=Av在字符串上查找每个后面有一个空格的
  • -|-(管道符号)= 等于or语句
  • - Av$-= 查找Av前面有空格的所有内容,以及Av字符串末尾的 when 。$
  • - Av -= 查找Av前面有空格和后面有空格的所有内容

    然后该函数将这些出现的任何一个替换为单词Avenue。请注意,我在前后放置了一个空格以避免类似Peer HarborAvenue

    同样的解释也适用于St字符串

    如果您喜欢正则表达式函数,可以在此处查看更多信息:Oracle 正则表达式函数

  • 于 2013-11-02T01:50:56.517 回答
    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;
    
    于 2013-11-04T19:00:04.183 回答