Regex 甲骨文:将许多字符串拆分为单独的单词

Regex 甲骨文:将许多字符串拆分为单独的单词,regex,oracle,split,Regex,Oracle,Split,我使用的是Oracle11g,我想将Persons表中的JobDescription列拆分为单独的单词。 也就是说,如果人员A的工作描述是专业贡献者,我想用包含工作描述中3个单词的3行填充另一个表 从另一篇文章中,我得到了以下内容,这些内容适用于较小的数据集。但我的表中只包含不到50万条记录,而且该语句已经运行了2天,而且仍在运行 INSERT INTO WORDS (PersonID, Department, Word) SELECT distinct PersonID, Department

我使用的是Oracle11g,我想将Persons表中的JobDescription列拆分为单独的单词。 也就是说,如果人员A的工作描述是专业贡献者,我想用包含工作描述中3个单词的3行填充另一个表

从另一篇文章中,我得到了以下内容,这些内容适用于较小的数据集。但我的表中只包含不到50万条记录,而且该语句已经运行了2天,而且仍在运行

INSERT INTO WORDS (PersonID, Department, Word)
SELECT distinct PersonID, Department, trim(regexp_substr(str, '[^,]+', 1, level)) 
FROM (SELECT PersonID, Department, trim(Replace(JobDescription, ' ', ',')) str 
      FROM Persons) t
CONNECT BY instr(  str  , ',', 1, level - 1) > 0;

有没有其他的方法可以更快地得到结果?

对于一次性工作,我认为没有理由不按程序进行。对于我的系统上250万行的表来说,这应该足够快250秒。如果单词长度超过40个字符,请更改varchar2变量的大小

create or replace procedure tmp_split_job as
  TYPE wtype IS TABLE OF NUMBER INDEX BY VARCHAR2(40);
  uwords wtype;
  w varchar2(40);
  i pls_integer;
  n pls_integer;
  p pls_integer;
  cursor c_fetch is select PersonID, Department, JobDescription from Persons where JobDescription is not null;
begin
  for v_row in c_fetch loop
    n := length(v_row.JobDescription);
    i := 1;
    while i <= n loop
      p := instr(v_row.JobDescription, ' ', i);
      if p > 1 then
        w := substr(v_row.JobDescription, i, p-i);
        i := p + 1;
      else
        w := substr(v_row.JobDescription, i);
        i := n + 1;
      end if;
      uwords(w) := 1;
    end loop;
    w := uwords.FIRST;
    while w is not null loop
      insert into words (PersonID, Department, Word) values (v_row.PersonID, v_row.Department, w);
      w := uwords.next(w);
    end loop;
    uwords.DELETE;
  end loop;
end;
/

exec tmp_split_job;
drop procedure tmp_split_job;

谢谢可悲的是,这不是一次性的工作,但即使是出于这个目的,这个程序也可能仍然有效。我会试试看。你的想法可能行得通,但逻辑还不太清楚。如果我传递字符串“This is the description”,我得到的结果是:This+是+descripp+descriptionFixed。我承认我没有测试这个-使用java子字符串语义start,end而不是Oracle的start,length。简单的方法是:使用未修改的版本插入到一个临时表中,然后插入单词select distinct*from tmp_words。我已经更新了答案,使用关联数组在内存中进行唯一过滤。