separar por ocurrencias funciones funcion ejemplos delimitada contar comas caracteres caracter cadena buscar string oracle plsql split tokenize

string - por - ¿Hay una función para dividir una cadena en PL/SQL?



separar cadena oracle (10)

A continuación encontrará un ejemplo que puede ser útil

--1ª subcadena

select substr(''alfa#bravo#charlie#delta'', 1, instr(''alfa#bravo#charlie#delta'', ''#'', 1, 1)-1) from dual;

--2ª subcadena

select substr(''alfa#bravo#charlie#delta'', instr(''alfa#bravo#charlie#delta'', ''#'', 1, 1)+1, instr(''alfa#bravo#charlie#delta'', ''#'', 1, 2) - instr(''alfa#bravo#charlie#delta'', ''#'', 1, 1) -1) from dual;

--3ª subcadena

select substr(''alfa#bravo#charlie#delta'', instr(''alfa#bravo#charlie#delta'', ''#'', 1, 2)+1, instr(''alfa#bravo#charlie#delta'', ''#'', 1, 3) - instr(''alfa#bravo#charlie#delta'', ''#'', 1, 2) -1) from dual;

--4ª subcadena

select substr(''alfa#bravo#charlie#delta'', instr(''alfa#bravo#charlie#delta'', ''#'', 1, 3)+1) from dual;

Atentamente

Emanuele

Necesito escribir un procedimiento para normalizar un registro que tenga múltiples tokens concatenados por un char. Necesito obtener estos tokens dividiendo la cadena e insertando cada uno como un nuevo registro en una tabla. ¿Oracle tiene algo así como una función de "división"?



Hay apex_util.string_to_table - ver mi respuesta a esta question .

Además, antes de la existencia de la función anterior, una vez publiqué una solución aquí en mi blog .

Actualizar

En versiones posteriores de APEX, apex_util.string_to_table está en deprecated , y se prefiere una función similar apex_string.split .


Hay una manera simple amigos. Use la función REPLACE. Aquí hay un ejemplo de cadena separada por comas lista para pasar a la cláusula IN.

En PL / SQL:

StatusString := REPLACE(''Active,Completed'', '','', '''''','''''');

En SQL Plus:

Select REPLACE(''Active,Completed'', '','', '''''','''''') from dual;



Puede usar regexp_substr (). Ejemplo:

create or replace type splitTable_Type is table of varchar2(100); declare l_split_table splitTable_Type; begin select regexp_substr(''SMITH,ALLEN,WARD,JONES'',''[^,]+'', 1, level) bulk collect into l_split_table from dual connect by regexp_substr(''SMITH,ALLEN,WARD,JONES'', ''[^,]+'', 1, level) is not null; end;

La consulta itera a través de la cadena separada por comas, busca la coma (,) y luego divide la cadena tratando la coma como delimitador. Devuelve la cadena como una fila, cada vez que golpea un delimitador.

level in statement regexp_substr(''SMITH,ALLEN,WARD,JONES'',''[^,]+'', 1, level) hace referencia a una pseudocolumna en Oracle que se usa en una consulta jerárquica para identificar el nivel de jerarquía en formato numérico: nivel en conectar por


Puede usar una combinación de SUBSTR e INSTR de la siguiente manera:

Ejemplo de cadena: field = ''DE124028#@$1048708#@$000#@$536967136#@$''

El separador es # @ $.

Para obtener el ''1048708'', por ejemplo:

Si el campo es de longitud fija (7 aquí):

substr(field,instr(field,''#@$'',1,1)+3,7)

Si el campo es de longitud variable:

substr(field,instr(field,''#@$'',1,1)+3,instr(field,''#@$'',1,2) - (instr(field,''#@$'',1,1)+3))

Probablemente debería examinar las funciones SUBSTR e INSTR para obtener más flexibilidad.


Si APEX_UTIL no está disponible, tiene una solución usando REGEXP_SUBSTR() .

Inspirado en http://nuijten.blogspot.fr/2009/07/splitting-comma-delimited-string-regexp.html :

DECLARE I INTEGER; TYPE T_ARRAY_OF_VARCHAR IS TABLE OF VARCHAR2(2000) INDEX BY BINARY_INTEGER; MY_ARRAY T_ARRAY_OF_VARCHAR; MY_STRING VARCHAR2(2000) := ''123,456,abc,def''; BEGIN FOR CURRENT_ROW IN ( with test as (select MY_STRING from dual) select regexp_substr(MY_STRING, ''[^,]+'', 1, rownum) SPLIT from test connect by level <= length (regexp_replace(MY_STRING, ''[^,]+'')) + 1) LOOP DBMS_OUTPUT.PUT_LINE(CURRENT_ROW.SPLIT); MY_ARRAY(MY_ARRAY.COUNT) := CURRENT_ROW.SPLIT; END LOOP; END; /


Tienes que hacer tu propio. P.ej,

/* from :http://www.builderau.com.au/architect/database/soa/Create-functions-to-join-and-split-strings-in-Oracle/0,339024547,339129882,00.htm select split(''foo,bar,zoo'') from dual; select * from table(split(''foo,bar,zoo'')); pipelined function is SQL only (no PL/SQL !) */ create or replace type split_tbl as table of varchar2(32767); / show errors create or replace function split ( p_list varchar2, p_del varchar2 := '','' ) return split_tbl pipelined is l_idx pls_integer; l_list varchar2(32767) := p_list; l_value varchar2(32767); begin loop l_idx := instr(l_list,p_del); if l_idx > 0 then pipe row(substr(l_list,1,l_idx-1)); l_list := substr(l_list,l_idx+length(p_del)); else pipe row(l_list); exit; end if; end loop; return; end split; / show errors; /* An own implementation. */ create or replace function split2( list in varchar2, delimiter in varchar2 default '','' ) return split_tbl as splitted split_tbl := split_tbl(); i pls_integer := 0; list_ varchar2(32767) := list; begin loop i := instr(list_, delimiter); if i > 0 then splitted.extend(1); splitted(splitted.last) := substr(list_, 1, i - 1); list_ := substr(list_, i + length(delimiter)); else splitted.extend(1); splitted(splitted.last) := list_; return splitted; end if; end loop; end; / show errors declare got split_tbl; procedure print(tbl in split_tbl) as begin for i in tbl.first .. tbl.last loop dbms_output.put_line(i || '' = '' || tbl(i)); end loop; end; begin got := split2(''foo,bar,zoo''); print(got); print(split2(''1 2 3 4 5'', '' '')); end; /


function numinstr(p_source in varchar2,p_token in varchar2) return pls_integer is v_occurrence pls_integer := 1; v_start pls_integer := 1; v_loc pls_integer; begin v_loc:=instr(p_source, p_token, 1, 1); while v_loc > 0 loop v_occurrence := v_occurrence+1; v_start:=v_loc+1; v_loc:=instr(p_source, p_token, v_start, 1); end loop; return v_occurrence-1; end numinstr; -- -- -- -- function get_split_field(p_source in varchar2,p_delim in varchar2,nth pls_integer) return varchar2 is v_num_delims pls_integer; first_pos pls_integer; final_pos pls_integer; len_delim pls_integer := length(p_delim); ret_len pls_integer; begin v_num_delims := numinstr(p_source,p_delim); if nth < 1 or nth > v_num_delims+1 then return null; else if nth = 1 then first_pos := 1; else first_pos := instr(p_source, p_delim, 1, nth-1) + len_delim; end if; if nth > v_num_delims then final_pos := length(p_source); else final_pos := instr(p_source, p_delim, 1, nth) - 1; end if; ret_len := (final_pos - first_pos) + 1; return substr(p_source, first_pos, ret_len); end if; end get_split_field;