Oracle 仅用表中的单词列表替换精确的单词
这个问题是这个问题的一部分 最初的问题是一个由两部分组成的问题,一部分是,有没有更好的方法 我有可以工作的代码,但速度非常慢,每条记录大约2秒 所以我有一个表,NR_POSTAL_ABBR,它有两个字段和大约400条记录Oracle 仅用表中的单词列表替换精确的单词,oracle,Oracle,这个问题是这个问题的一部分 最初的问题是一个由两部分组成的问题,一部分是,有没有更好的方法 我有可以工作的代码,但速度非常慢,每条记录大约2秒 所以我有一个表,NR_POSTAL_ABBR,它有两个字段和大约400条记录 ReplaceWhat ReplaceWith Ave Avenue St Street 我希望能够用上表中的值替换另一个表中的地址字段 所以,如果我有一个地址123大街-它应该说123大街 如果我有12
ReplaceWhat ReplaceWith
Ave Avenue
St Street
我希望能够用上表中的值替换另一个表中的地址字段
所以,如果我有一个地址123大街-它应该说123大街
如果我有123大街——它应该保持在123大街,它不应该变成123大街
带有地址的表有几百万行,有没有快速的方法
如你所问,谢谢你。我的建议是遍历
正则表达式
,因此这里是针对您的案例的un更新代码
假设您有一个带有字段地址的表测试,您需要做的是非常简单的,创建一个符合您需求的正则表达式
因此:您需要为Street
和Avenue
更换每个St
,这是您应该做的
update test
set address =
regexp_replace(
regexp_replace(address, 'Av | Av$| Av ', ' Avenue ' ),
'St | St$| St ', ' Street ');
这里有一个例子
解释正则表达式:
regexp\u replace
基于正则表达式模式替换另一个字符串,请参见文档:
关于正则表达式,您可以在这里看到,几乎每种语言都遵循POSIX
模式,因此,一旦您学会了它,您就会很好
所以我习惯于regexp\u replace
来实现您想要的,因为您给出了两个要求。我不会写函数的参数,只写表达式
在第一个表达式中,您有'Av | Av$| Av'
,这意味着:
注:我把-
放在你看到的地方(所以忽略它)。所以我不会把它放在这里
-Av-
(末尾有空格)=在字符串上查找每个Av
后面有空格的字符串
-|-
(管道符号)=等于或
语句
-Av$-
=当Av
位于字符串末尾时,查找前面有空格的所有Av
<代码>$
-Av-
=查找所有Av
,前面有空格,后面有空格
然后,该函数将用单词Avenue
替换任何出现的问题。请注意,我在前面和后面各放了一个空格,以避免出现类似Peer-HarborAvenue
同样的解释也适用于St
string
如果你喜欢正则表达式功能,你可以在这里看到更多信息:只要根据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;
假设每个地址中只有一个缩写应该被替换,这样安全吗?不,不是)可以有超过1个,请告诉我这适合你,然后我会发布回答:如果这是一次性的,Jorge有正确的想法。您应该为
NR\u POSTAL\u ABBR
表中的所有内容编写一个正则表达式,并使用它。我恭敬地指出,解决这个问题的任何方法都将是缓慢的。正如您所指出的,地址表中的一行必须与NR_POSTAL_ABBR中的所有行(~400行)进行比较,并且这400个检查中的每一个都必须以这样的方式进行,即它只能找到独立的缩写,而不是其他单词的一部分。因此,您将进行400*(地址数=数百万行数)检查,这几乎肯定需要一段时间。祝你好运。