我在一个表中有2个文本列。要求是比较这两列,并检查是否有任何文本匹配,并将其替换为第一列中的文本。我们必须注意这个情况。
CREATE TABLE search_text(
id NUMBER(20,0),
text1 varchar2(1000),
text2 varchar2(1000));
INSERT INTO search_text VALUES
(
100,
'Inband signaling used in transmission that reduces the available user bandwidth from 1.544 to 1.536 Mbps.',
'USER Bandwidth >inband Signaling< (TRansmission>'
);
替换后text2列的预期结果是
"user bandwidth >Inband signaling< (transmission>"
更新search_text设置text1 = text2,text2 = text1但是在执行此操作之前,请创建备份,您可能会丢失信息。这可以在SQL Server中使用,因此一定可以在oracle中使用。
我不知道如何在SQL中执行此操作,但是-如果PL / SQL可以,请问是否有帮助。
表内容:
SQL> select * from search_text;
ID TEXT1 TEXT2
---- ---------------------------------------- ----------------------------------------
100 Inband signaling used in transmission th USER Bandwidth >inband Signaling< (TRans
at reduces the available user bandwidth mission>
from 1.544 to 1.536 Mbps.
功能:嵌套循环,在text1
和text2
字符串中逐字比较。如果它们匹配(请注意lower
功能以及regexp_substr
会删除>
,(
等),请执行替换。
SQL> create or replace function f_replace (par_id in number)
2 return varchar2
3 is
4 l_text search_text.text2%type;
5 l_fir varchar2(100);
6 l_sec varchar2(100);
7 begin
8 select text2
9 into l_text
10 from search_text
11 where id = par_id;
12
13 for cur_fir in (select regexp_substr(text1, '[^ ]+', 1, level) val
14 from search_text
15 where id = par_id
16 connect by level <= regexp_count(text1, ' ') + 1
17 )
18 loop
19 for cur_sec in (select regexp_substr(text2, '[^ ]+', 1, level) val
20 from search_text
21 where id = par_id
22 connect by level <= regexp_count(text2, ' ') + 1
23 )
24 loop
25 l_fir := regexp_substr(cur_fir.val, '\w+');
26 l_sec := regexp_substr(cur_sec.val, '\w+');
27 l_text := case when lower(l_sec) = lower(l_fir)
28 then replace(l_text, l_sec, l_fir)
29 else l_text
30 end;
31 end loop;
32 end loop;
33
34 return l_text;
35 end;
36 /
Function created.
测试:
SQL> select f_replace(100) result from dual;
RESULT
------------------------------------------------------------------
user bandwidth >Inband signaling< (transmission>
SQL>
仅使用SQL。分层查询将字符串分成多行,然后逐字替换。然后,聚合函数将获得最后一行,其中包含所有单词的累积替换:
with t (id, word, text1, text2, replaced_text2, lvl) as
(
select id,
regexp_substr(text1, '[[:alpha:]\'']+', 1, 1, 'i'),
text1,
text2,
regexp_replace(text2,
'([^[:alpha:]]+|^)' || regexp_substr(text1, '[[:alpha:]\'']+', 1, 1, 'i') || '([^[:alpha:]]+|$)',
'\1' || regexp_substr(text1, '[[:alpha:]\'']+', 1, 1, 'i') || '\2',
1, 1, 'i'),
1 lvl
from search_text
union all
select s.id,
regexp_substr(s.text1, '[[:alpha:]\'']+', 1, t.lvl + 1, 'i'),
s.text1,
s.text2,
regexp_replace(t.replaced_text2,
'([^[:alpha:]]+|^)' || regexp_substr(s.text1, '[[:alpha:]\'']+', 1, t.lvl + 1, 'i') || '([^[:alpha:]]+|$)',
'\1' || regexp_substr(s.text1, '[[:alpha:]\'']+', 1, t.lvl + 1, 'i') || '\2',
1, 0, 'i'),
t.lvl + 1
from search_text s, t
where t.id = s.id
and regexp_count(s.text1, '[[:alpha:]\'']+') >= t.lvl + 1
)
select t.id,
t.text1,
t.text2,
max(t.replaced_text2) keep (dense_rank first order by t.lvl desc) replaced_text2
from t
group by t.id, t.text1, t.text2
order by id;
示例执行:
FSITJA@db01> with t (id, word, text1, text2, replaced_text2, lvl) as
2 (
3 select id,
4 regexp_substr(text1, '[[:alpha:]\'']+', 1, 1, 'i'),
5 text1,
6 text2,
7 regexp_replace(text2,
8 '([^[:alpha:]]+|^)' || regexp_substr(text1, '[[:alpha:]\'']+', 1, 1, 'i') || '([^[:alpha:]]+|$)',
9 '\1' || regexp_substr(text1, '[[:alpha:]\'']+', 1, 1, 'i') || '\2',
10 1, 1, 'i'),
11 1 lvl
12 from search_text
13 union all
14 select s.id,
15 regexp_substr(s.text1, '[[:alpha:]\'']+', 1, t.lvl + 1, 'i'),
16 s.text1,
17 s.text2,
18 regexp_replace(t.replaced_text2,
19 '([^[:alpha:]]+|^)' || regexp_substr(s.text1, '[[:alpha:]\'']+', 1, t.lvl + 1, 'i') || '([^[:alpha:]]+|$)',
20 '\1' || regexp_substr(s.text1, '[[:alpha:]\'']+', 1, t.lvl + 1, 'i') || '\2',
21 1, 0, 'i'),
22 t.lvl + 1
23 from search_text s, t
24 where t.id = s.id
25 and regexp_count(s.text1, '[[:alpha:]\'']+') >= t.lvl + 1
26 )
27 select t.id,
28 t.text1,
29 t.text2,
30 max(t.replaced_text2) keep (dense_rank first order by t.lvl desc) replaced_text2
31 from t
32 group by t.id, t.text1, t.text2
33 order by id;
ID TEXT1 TEXT2 REPLACED_TEXT2
---- ---------------------------------------- ---------------------------------------- ----------------------------------------
100 Inband signaling used in transmission th USER Bandwidth >inband Signaling< (TRans user bandwidth >Inband signaling< (trans
at reduces the available user bandwidth mission> mission>
from 1.544 to 1.536 Mbps.