Сравнить два varchar2 частично - PullRequest
       21

Сравнить два varchar2 частично

0 голосов
/ 10 сентября 2018

Мне нужно сравнить два Varchar2 в PL / SQL, но в блоках по 3 символа. Например, следующие две строки: «Synch ron ize» и «f ron t» будут совпадать, поскольку обе содержат подстроку «ron».

Чтобы решить эту проблему, я мог бы получить все блоки из трех последовательных символов первой строки и найти любой из них во второй строке.

Мой вопрос: существует ли более простое / оптимизированное решение для получения того же результата в PL / SQL?

Заранее спасибо.

Ниже вы можете найти пример кода, в котором v_found будет содержать значение больше 0, если есть совпадение:

DECLARE  
    v_string1   VARCHAR2(30) := '1234567';  
    v_string2    VARCHAR2(30) := 'abcd345efg';  
    v_substring    VARCHAR2 (100);  
  v_len          PLS_INTEGER;  
  v_found        PLS_INTEGER;  
BEGIN  
  v_len := LENGTH(v_string1);  
  IF (v_len > 2 ) THEN  
    FOR i IN 1 .. v_len - 2  
    LOOP  
      v_substring := SUBSTR( v_string1, i, 3 );  
      dbms_output.put_line( v_substring );  
      v_found := INSTR( v_string2, v_substring );  
      dbms_output.put_line( 'v_string2<' || v_string2 || '>, v_substring<' || v_substring || '>, v_found <' || v_found || '>' );  
    END LOOP;  
  END IF;  
END;  

1 Ответ

0 голосов
/ 10 сентября 2018

Скажем, у вас есть строка, и вам нужно получить все подстроки из 3 символов; это может быть способ:

select substr(string1, level, 3)
from (select '1234567' string1 from dual)
connect by level +2 <= length(string1);

SUBSTR(STRING1,LEVEL,3)         
--------------------------------
123                             
234                             
345                             
456                             
567               

Вы можете использовать это, чтобы получить все подстроки из обеих строк, а затем выполнить проверку с помощью JOIN:

DECLARE  
    v_string1   VARCHAR2(30) := '1234567';  
    v_string2   VARCHAR2(30) := 'abcd345efg'; 
    v_check     number;
BEGIN    
    select count(*)
    into v_check
    from (
            select substr(v_string1, level, 3) token
            from dual
            connect by level +2 <= length(v_string1)
         ) tokens_1
         inner join 
         (
            select substr(v_string2, level, 3) token
            from dual
            connect by level +2 <= length(v_string2)
         ) tokens_2
         on (tokens_1.token = tokens_2.token);
    if v_check = 1 then
        dbms_output.put_line('MATCH');
    else
        dbms_output.put_line('NO MATCH');
    end if;
END;

Более компактный способ может быть:

select case when max(instr(string2, substr(string1, level, 3))) = 0
        then 'NO MATCH'
        else 'MATCH'
       end 
from (select '1234567' string1, 'abcd345efg' string2 from dual)
connect by level +2 <= length(string1)
...