Oracle:如何用column1中的确切值搜索和替换column2中的文本?

问题描述 投票:0回答:3

我在一个表中有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>"
sql oracle replace string-matching regexp-replace
3个回答
0
投票

更新search_text设置text1 = text2,text2 = text1但是在执行此操作之前,请创建备份,您可能会丢失信息。这可以在SQL Server中使用,因此一定可以在oracle中使用。


0
投票

我不知道如何在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.

功能:嵌套循环,在text1text2字符串中逐字比较。如果它们匹配(请注意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>

0
投票

仅使用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.
© www.soinside.com 2019 - 2024. All rights reserved.