oracle - 将按字符排序的plsql函数

时间:2015-03-06 20:12:10

标签: oracle

我需要一个oracle -plsql函数,它将按输入的单词中的字符进行排序,它可能是单词中的几个字符,它们不是一个一个。 例如 : 搜索单词ABCD中的BD字符然后向我显示所有带BD的单词,因为你看到BD不是连续字母ABCD单词,这就是我的问题。 我需要找到用户键入的每个字符,它会给他所有结果。 以及在那里使用它的触发器是什么?

1 个答案:

答案 0 :(得分:0)

此解决方案为给定单词BASE_WORD生成所有可能的字谜,然后检查这些字谜是否与SEARCH_WORD中的字母匹配。

您必须创建表格Word,如下面的代码部分所示。可能没有桌子的解决方案是可能的,但我不确定我是否理解正确, 所以对于开始,让我们尝试这种方式。

小心,对于长度为9个字符的BASE_WORD,你得到~1000000个字谜,所以对于更长的单词,可能需要一些时间。

-- create below table, this is only needed once:
create table words (word varchar2(20), ok number(1) default 0);  

-- copy, paste and compile my procedure p_words, code at bottom

-- run procedure p_words with parameters BASE_WORD and SEARCH_WORD:
begin p_words('DBCA', 'ACD'); end;

您可以获得符合此标准的所有字词:

-- select words using this query:
select word from words where ok=1 order by word

     WORD
     ----
  1  ABCD
  2  ABDC
  3  ACBD
  4  ACD
  5  ACDB
     ...
 27  DBCA
 28  DCA
 29  DCAB
 30  DCBA

程序代码:

create or replace procedure p_words(i_base varchar2, i_search varchar2) as 
  v_sql varchar2(4000);
begin
  -- clear previous words
  delete from words;

  -- build all possible anagrams of BASE WORD and insert them into table 
  insert into words (
    select distinct replace(sys_connect_by_path(chr, '/'), '/'), 0
      from (
        select rownum rn, substr(i_base, rownum, 1) as chr 
          from dual connect by level <= length(i_base))
      connect by nocycle rn <> prior rn); 

  -- build condition part for execute immediate
  v_sql := 'update words set ok = 1 where 1=0';

  -- building rest of conditions in loop for each 
  -- possible combination of letters in SEARCH_WORD
  for o in (select * from (
      with input as (select i_search as word from dual),
      l as (select rownum rn, substr(i.word, rownum, 1) as chr 
        from input i connect by level <= length(i.word))
      select level lvl, sys_connect_by_path(chr, '%')||'%' word
        from l connect by nocycle rn <> prior rn)
    where lvl = length(i_search))
  loop
    v_sql := v_sql ||' or word like '''||o.word||'''';
  end loop;

  -- execute update on field words.OK
  execute immediate v_sql;
  commit;

end p_words;