1

我不确定如何最好地描述我的问题

我有一张表 (NR_POSTAL_ABBR),其中包含邮政缩写及其代表的含义,例如 ST 和 STREET、AVE 和 AVENUE。我希望能够用该表中的值替换地址字段。

如果我有一个地址 123 Main ST,我希望它说 123 Main Street。我有一个执行此操作的程序(如下)。它很慢,现在我有一个包含 3M 记录的表,它必须经过 400 个缩写对,它将永远运行。

所以我正在考虑加快速度的方法。一种方法是仅遍历地址字段中具有缩写的记录,因此执行以下操作,但它不起作用,因为它位于错误的位置。

所以 2 部分问题

  1. 有没有更好的方法来实现我想要做的事情?
  2. 如果不是,那么我该如何修复以下过程,以便能够仅通过地址具有 NR_POSTAL_ABBR 表中的 ReplaceWhat 值的那些记录来限制记录

谢谢你

ETA NewAddress 字段的地址带有 .,:; 替换为空格。这样,我只能替换整个单词(st,而不是 west)的值

我想用什么替换第二个 CURSOR

     CURSOR readMainTable IS
       SELECT A.*
         FROM analyst.NR_TMP_105 A
WHERE NeweAddress LIKE '%' || VariableThatHoldsTheReplaceWhatValue || '%';

我目前拥有的程序有效,但速度很慢

DECLARE
     CURSOR getReplsStrng IS
       SELECT replacewhat
          ,replacewith
         FROM analyst.NR_POSTAL_ABBR
        WHERE ReplaceOrder = 1;

     CURSOR readMainTable IS
       SELECT A.*
         FROM analyst.NR_TMP_105 A;

     lvAddress VARCHAR2(5000);
     lvTmpAddress VARCHAR2(5000);
     lnPos NUMBER(10);
     lnPosPls NUMBER(10);
     lvPosPls VARCHAR2(500);
     lvPosMinus VARCHAR2(500);
     lnLoopCnt NUMBER := 0;
     lvCty VARCHAR2(200);
     lvBfUpd VARCHAR2(500);
     lvAfterUpd VARCHAR2(500);
BEGIN
     lnLoopCnt := 0;

     FOR getRec IN readMainTable LOOP
       lnLoopCnt := lnLoopCnt + 1;

       lvAddress := NULL;
       lvTmpAddress := NULL;

       lvAddress := getRec.NewAddress;
       lvTmpAddress := getRec.NewAddress;

       FOR getInnerRec IN getReplsStrng LOOP
         lvPosPls := NULL;
         lvPosMinus := NULL;
         lnPos := 0;
         lnPos := INSTR(UPPER(lvAddress), UPPER(getInnerRec.replacewhat), 1, 1);

         IF lnPos > 0 THEN
              NULL;

              lvPosPls := SUBSTR(UPPER(lvAddress)
                       ,((  INSTR(UPPER(lvAddress), UPPER(getInnerRec.replacewhat), 1, 1)
                          + LENGTH(UPPER(getInnerRec.replacewhat))))
                       ,1);
              lvPosMinus := SUBSTR(UPPER(lvAddress), (INSTR(UPPER(lvAddress), UPPER(getInnerRec.replacewhat), 1, 1) - 1), 1);

              IF     (   lvPosPls IS NULL
                OR lvPosPls = CHR(32))
              AND (   lvPosMinus = CHR(32)
                OR lvPosMinus = CHR(32)) THEN
                lvAddress := REPLACE(UPPER(lvAddress), UPPER(getInnerRec.replacewhat), UPPER(getInnerRec.replacewith));

                lvAddress := LOWER(lvAddress);
              ELSIF lvPosPls IS NOT NULL THEN
                NULL;
              END IF;
              BEGIN
                UPDATE analyst.NR_TMP_105 b
                SET b.NewAddress = lvAddress
                 WHERE   b.NewAddress = lvTmpAddress
                    AND b.UniqueID = getRec.UniqueID;
                COMMIT;
              EXCEPTION
                WHEN OTHERS THEN
                  DBMS_OUTPUT.put_line('Error in updating the address : ' || lvTmpAddress);
              END;
         ELSIF lnPos = 0 THEN
              NULL;
         END IF;

         lvTmpAddress := lvAddress;

         IF MOD(lnLoopCnt, 200) = 0 THEN
              COMMIT;
              NULL;
         END IF;
       END LOOP;
     END LOOP;

     COMMIT;
EXCEPTION
     WHEN OTHERS THEN
       DBMS_OUTPUT.put_line('Error in main process:' || SUBSTR(SQLERRM, 1, 200));
END;
4

1 回答 1

1

如果我得到你的第二部分,那么你可以按照以下方式做一些事情

CURSOR readMainTable IS
   SELECT DISTINCT A.*
     FROM analyst.NR_TMP_105 A
     INNER JOIN NR_POSTAL_ABBR B
     ON (A.NewAddress like ' %'||B.replacewhat||'%'
    WHERE B.ReplaceOrder = 1

这应该只为您提供需要替换的地址(或可能需要它们 - 您可能需要对其进行改进)。有没有更好的办法?也许吧,但是你如何处理这决定了你是否需要付出额外的努力。

于 2013-11-01T01:36:20.357 回答