valores texto separar separados separada registros por partes hacer extraer espacios dinamico comas coma columnas cadena sql oracle regexp-substr

sql - separados - separar texto en columnas oracle



Dividir valores separados por comas en Oracle (2)

Tengo una columna en mi base de datos donde los valores vienen de la siguiente manera:

3862,3654,3828

En la columna ficticia cualquier no. de valores separados por comas puede venir. Intenté con la siguiente consulta, pero está creando resultados duplicados.

select regexp_substr(dummy,''[^,]+'',1,Level) as dummycol from (select * from dummy_table) connect by level <= length(REGEXP_REPLACE(dummy,''[^,]+''))+1

No estoy entendiendo el problema. ¿Alguien puede ayudar?


Dando un ejemplo PL / SQL donde se analiza sobre una tabla con un ID y nombre de columna. Esto analizará e imprimirá cada ID y el valor analizado que luego podría insertarse en una nueva tabla o utilizarse de alguna otra manera.

Entrada

Column_ID Column_Name 123 (3862,3654,3828)

Salida

Column_ID Column_Name 123 3862 123 3654 123 3828

Código PL / SQL

declare table_name1 varchar2(1000); string_to_parse varchar2(2000); -- assign string to table name string_length number := 0; -- string length for loop string_value varchar2(2000); -- string value to store value in column_id number; begin --some table in the format ''123'' as column_id, ''(3862,3654,3828)'' as column_name --remove the parenthesis or other special characters if needed update some_table t set t.column_name = regexp_replace(t.column_name,''/(|/)'',''''); commit; for i in ( select * from some_table ) loop column_id := i.column_id; --assign the id of the colors string_to_parse := i.column_name; -- assign string to be parsed if string_to_parse is null then --at this point insert into a new table, or do whatever else you need dbms_output.put_line(column_id || '' '' || string_value); else --String to parse is the comma string_to_parse := string_to_parse||'',''; string_length := length(string_to_parse) - length(replace(string_to_parse,'','','''')); -- Loop through string from parameter for i in 1 .. string_length loop -- [^,] matches any character except for the , select regexp_substr(string_to_parse,''[^,]+'',1,i) into string_value -- stores value into string_value from dual; -- dual is a dummy table to work around --at this point insert into a new table, or do whatever else you need dbms_output.put_line(column_id || '' '' || string_value); --clear out the string value string_value := null; end loop; end if; end loop; end;


Funciona perfectamente para mí -

SQL> WITH dummy_table AS( 2 SELECT ''3862,3654,3828'' dummy FROM dual 3 ) 4 SELECT trim(regexp_substr(dummy,''[^,]+'',1,Level)) AS dummycol 5 FROM dummy_table 6 CONNECT BY level <= LENGTH(REGEXP_REPLACE(dummy,''[^,]+''))+1 7 / DUMMYCOL -------------- 3862 3654 3828 SQL>

Hay muchas otras maneras de lograrlo. Leer División de cadena delimitada por comas simples en filas .

Actualización Respecto a los duplicados cuando se usa la columna en lugar de un único valor de cadena. Vimos el uso de DBMS_RANDOM en la cláusula PRIOR para deshacernos del bucle cíclico aquí

Pruebe lo siguiente,

SQL> WITH dummy_table AS 2 ( SELECT 1 rn, ''3862,3654,3828'' dummy FROM dual 3 UNION ALL 4 SELECT 2, ''1234,5678'' dummy FROM dual 5 ) 6 SELECT trim(regexp_substr(dummy,''[^,]+'',1,Level)) AS dummycol 7 FROM dummy_table 8 CONNECT BY LEVEL <= LENGTH(REGEXP_REPLACE(dummy,''[^,]+''))+1 9 AND prior rn = rn 10 AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL 11 / DUMMYCOL -------------- 3862 3654 3828 1234 5678 SQL>

Actualización 2

De otra manera,

SQL> WITH dummy_table AS 2 ( SELECT 1 rn, ''3862,3654,3828'' dummy FROM dual 3 UNION ALL 4 SELECT 2, ''1234,5678,xyz'' dummy FROM dual 5 ) 6 SELECT trim(regexp_substr(t.dummy, ''[^,]+'', 1, levels.column_value)) AS dummycol 7 FROM dummy_table t, 8 TABLE(CAST(MULTISET 9 (SELECT LEVEL 10 FROM dual 11 CONNECT BY LEVEL <= LENGTH (regexp_replace(t.dummy, ''[^,]+'')) + 1 12 ) AS sys.OdciNumberList)) LEVELS 13 / DUMMYCOL -------------- 3862 3654 3828 1234 5678 xyz 6 rows selected. SQL>