Oracle: Как найти и заменить текст в столбце 2 точным значением из столбца 1? - PullRequest
1 голос
/ 25 сентября 2019

У меня есть 2 текстовых столбца в таблице.Требуется сравнить эти 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>"

Ответы [ 3 ]

0 голосов
/ 26 сентября 2019

Я не знаю, как это сделать в 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>
0 голосов
/ 26 сентября 2019

Использование только 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.
0 голосов
/ 25 сентября 2019

Обновление search_text Установите text1 = text2, text2 = text1 Но, прежде чем сделать это, пожалуйста, создайте резервную копию, вы можете потерять информацию.Это работает на SQL-сервере, поэтому он определенно будет работать в Oracle.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...