Search code examples
oracle-databaseplsqlpattern-matchingbigdatastring-matching

How to compare items in an array to those in a database column using regular expressions?


I'm trying to take a list of elements in an array like this:

['GRADE', 'GRATE', 'GRAPE', /*About 1000 other entries here ...*/ ]

and match them to their occurrences in a column in an Oracle database full of entries like this:

1|'ANTERIOR'
2|'ANTEROGRADE'
3|'INGRATE'
4|'RETROGRADE'
5|'REIGN'
...|...
/*About 1,000,000 other entries here*/

For each entry in that array of G words, I'd like to loop through the word column of the Oracle database and try to find the right-sided matches for each entry in the array. In this example, entries 2, 3, and 4 in the database would all match.

In any other programming language, it would look something like this:

for entry in array:
  for each in column:
    if entry.right_match(each):
      print entry

How do I do this in PL/SQL?


Solution

  • In PL/SQL it can be done in this way:

    declare
       SUBTYPE my_varchar2_t IS varchar2( 100 );
       TYPE Roster IS TABLE OF my_varchar2_t;  
       names Roster := Roster( 'GRADE', 'GRATE', 'GRAPE');
    begin
      FOR c IN ( SELECT id, name FROM my_table )
      LOOP
          FOR i IN names.FIRST .. names.LAST LOOP 
             IF regexp_like( c.name,   names( i )  ) THEN
                  DBMS_OUTPUT.PUT_LINE( c.id || '  ' || c.name );
             END IF;
          END LOOP;
      END LOOP;
    end;
    /
    

    but this is row by row processing, for large table it would be very slow.

    I think it might be better to do it in a way shown below:

    create table test123 as
    select 1 id ,'ANTERIOR' name from dual union all
    select 2,'ANTEROGRADE' from dual union all
    select 3,'INGRATE' from dual union all
    select 4,'RETROGRADE' from dual union all
    select 5,'REIGN' from dual ;
    
    create type my_table_typ is table of varchar2( 100 );
    /
    
    select *
    from table( my_table_typ( 'GRADE', 'GRATE', 'GRAPE' )) x
    join test123 y on regexp_like( y.name, x.column_value ) 
    ;
    
    COLUMN_VALUE  ID         NAME      
    ------------- ---------- -----------
    GRADE                  2 ANTEROGRADE 
    GRATE                  3 INGRATE     
    GRADE                  4 RETROGRADE