如何使用可变长度字符串标记列

时间:2013-11-09 18:33:58

标签: java sql oracle plsql

我有一个关于在列中标记字符串的问题 我有像

这样的表格
id  list
1   i love dogs
2   i like cats and dogs  

等等

应该转换为

id  list
1   i
1   love
1   dogs
2   i
2   like
2   cates
2   and
2   dogs

我如何标记这个?我尝试在游标和过程

中使用此代码
SELECT id, regexp_substr(str, '[^ ]+', 1, level) TOKEN
    from test
CONNECT by level <= length(regexp_replace (str, '[^ ]+')) + 1;

但是从java调用时这很慢。还有其他选择吗?

由于 阿尼尔

1 个答案:

答案 0 :(得分:1)

正如我在评论中提到的,您可以尝试使用substrinstr函数代替regexp_substr,也许您可​​以接受性能:

CREATE TABLE test_list_tab (
  id NUMBER,
  str VARCHAR2(100)
);

CREATE TABLE test_tokens_tab (
  id NUMBER,
  token VARCHAR2(100)
);

INSERT INTO test_list_tab VALUES (1, 'i love dogs');
INSERT INTO test_list_tab VALUES (2, 'i like cats and dogs');
INSERT INTO test_list_tab VALUES (3, 'i');
INSERT INTO test_list_tab VALUES (4, 'abc');
INSERT INTO test_list_tab VALUES (5, 'abc i');
INSERT INTO test_list_tab VALUES (6, NULL);

DECLARE
  v_token test_list_tab.str%TYPE;
  v_space_position NUMBER := 1;
  v_prev_space_position NUMBER := 1;
BEGIN
  FOR v_rec IN (SELECT id, str FROM test_list_tab WHERE str IS NOT NULL)
  LOOP
    v_prev_space_position := 0;

    LOOP
      v_space_position := instr(v_rec.str, ' ', v_prev_space_position + 1);
      IF v_space_position > 0 THEN
        v_token := substr(v_rec.str, v_prev_space_position + 1, v_space_position - v_prev_space_position - 1);
      ELSE
        v_token := substr(v_rec.str, v_prev_space_position + 1);
      END IF;

      INSERT INTO test_tokens_tab VALUES (v_rec.id, v_token);

      v_prev_space_position := v_space_position;
      EXIT WHEN v_space_position = 0;
    END LOOP;
  END LOOP;

  COMMIT;
END;

SELECT id, token FROM test_tokens_tab;

输出:

        ID TOKEN 
---------- -------
         1 i       
         1 love    
         1 dogs    
         2 i       
         2 like    
         2 cats    
         2 and     
         2 dogs    
         3 i       
         4 abc     
         5 abc     
         5 i