Разбор строки в таблицу с использованием оракула SQL - PullRequest
0 голосов
/ 24 августа 2010

ребята. Скажем, у меня есть следующая таблица:

ID | String
---+---------  
1  | <123><345>  
2  | <1-2><45-67>  
3  | <345-321><234>

Это устаревший формат данных в моем приложении, который в настоящее время невозможно избежать. То, что мне нужно, это:

ID | String
---+---------
1  | <123>  
1  | <345>  
2  | <1-2>  
2  | <45-67>  
3  | <345-321>  
3  | <234>  

Какие-либо предложения о том, как получить этот результат, используя только простой Oracle SQL без создания каких-либо дополнительных объектов или процедур pl-sql?

Спасибо.

Ответы [ 3 ]

5 голосов
/ 24 августа 2010
select id, string
  ,substr(string, instr(string, '<', 1, element_number)
    ,instr(string, '>', 1, element_number) - instr(string, '<', 1, element_number) + 1) result
from test
cross join
(
  select level element_number from dual connect by level <=
    (select max(length(string) - length(replace(string, '<', null))) max_elements from test)
) extra_rows
where element_number <= length(string) - length(replace(string, '<', null))
order by id, element_number;
0 голосов
/ 24 августа 2010

Попробуйте:

SELECT Id, SUBSTR(String,1,INSTR(String,'>',1,1)) FROM MyTable
UNION ALL
SELECT Id, SUBSTR(String,INSTR(String,'<',1,2)) FROM MyTable

Я пользователь MS SQL Server, поэтому я не уверен, что он будет работать, но дайте мне знать ...

0 голосов
/ 24 августа 2010

Если вы все равно решили использовать хранимые процедуры, попробуйте это:

Источник: http://jasonvogel.blogspot.com/2006/11/oracle-sql-converting-one-row-into-two.html

CREATE OR REPLACE FUNCTION split (
 s_delimited_list_in     VARCHAR2,
 s_delimiter_in          VARCHAR2 := ',')
RETURN prod_types.type_string_array PIPELINED
IS
/*
@Usage Example:
select * from table(split('one,two,three'));
*/
 l_idx               PLS_INTEGER;
 l_list              VARCHAR2(32767) := s_delimited_list_in;
 l_value             VARCHAR2(32767);
 ls_delimiter        VARCHAR2(100) := NVL(s_delimiter_in,',');
BEGIN
LOOP
 l_idx := INSTR(l_list,ls_delimiter);

 IF (l_idx > 0) THEN

    PIPE ROW(SUBSTR(l_list,1,l_idx-1));
    l_list := SUBSTR(l_list,l_idx+LENGTH(ls_delimiter));

 ELSE

    PIPE ROW(l_list);
    EXIT;

 END IF;
END LOOP;

RETURN;

END SPLIT;
...