regexp_substr parse into instr array sql oracle plsql string-split

parse - substring pl sql



obtener "lista separada por comas cerca de ''xx.yy'' no vĂ¡lida" con dbms_utility.comma_to_table (2)

Es porque ( referencia de doc Oracle )

COMMA_TO_TABLE Procedimientos

Estos procedimientos convierten una lista de nombres delimitada por comas en una tabla de nombres PL / SQL. La segunda versión admite nombres de atributos totalmente calificados.

Un "nombre" al que se hace referencia aquí es un identificador válido de Oracle (objeto DB), para el cual se aplican todas las reglas de denominación. ac_Abc.88 no es un nombre válido, porque en Oracle no puedes tener un identificador que empiece con un dígito.

Para resolver su problema con el análisis de cadenas de valores delimitados por comas, use la siguiente solución de Lalit Kumar.

Tengo una cadena como esta: str: = ''ac_Abc.88, ac_Abc.99, ac_Abc.77''. Necesito obtener el primer elemento después de dividir con coma (,). Así que estoy usando usando esto:

str VARCHAR2(500); dbms_utility.comma_to_table ( list => regexp_replace(str,''(^|,)'',''/1'') , tablen => l_count , tab => l_array );

Estoy recibiendo el siguiente error:

ORA-20001: comma-separated list invalid near bc.88 ORA-06512: at "SYS.DBMS_UTILITY", line 239 ORA-06512: at "SYS.DBMS_UTILITY", line 272

Pero si tengo una cadena como esta, str: = ''ac_Abc88, ac_Abc99, ac_Abc77'', el mismo método funciona bien y me da los resultados esperados.

Así que supongo que hay algo que debe corregirse para considerar "." como personaje regular. ¿Puede sugerir por favor cómo puedo solucionar esto?


Consulte Cómo dividir la cadena delimitada por comas en filas

1. Enfoque REGEXP_SUBSTR

SQL> WITH DATA AS( 2 SELECT ''ac_Abc.88,ac_Abc.99,ac_Abc.77'' str FROM dual) 3 SELECT regexp_substr(str,''[^,]+'',1,level) str 4 FROM DATA 5 CONNECT BY regexp_substr(str, ''[^,]+'', 1, level) IS NOT NULL 6 / STR ----------------------------- ac_Abc.88 ac_Abc.99 ac_Abc.77 SQL>

2. enfoque XML

SQL> SELECT EXTRACT (VALUE (d), ''//row/text()'').getstringval () str 2 FROM 3 (SELECT XMLTYPE ( ''<rows><row>'' 4 || REPLACE (''ac_Abc.88,ac_Abc.99,ac_Abc.77'', '','', ''</row><row>'') 5 || ''</row></rows>'' ) AS xmlval 6 FROM DUAL 7 ) x, 8 TABLE (XMLSEQUENCE (EXTRACT (x.xmlval, ''/rows/row''))) d 9 / STR -------------------- ac_Abc.88 ac_Abc.99 ac_Abc.77

3. Función de tabla

SQL> CREATE TYPE test_type 2 AS 3 TABLE OF VARCHAR2(100) 4 / Type created. SQL> SQL> CREATE OR REPLACE 2 FUNCTION comma_to_table( 3 p_list IN VARCHAR2) 4 RETURN test_type 5 AS 6 l_string VARCHAR2(32767) := p_list || '',''; 7 l_comma_index PLS_INTEGER; 8 l_index PLS_INTEGER := 1; 9 l_tab test_type := test_type(); 10 BEGIN 11 LOOP 12 l_comma_index := INSTR(l_string, '','', l_index); 13 EXIT 14 WHEN l_comma_index = 0; 15 l_tab.EXTEND; 16 l_tab(l_tab.COUNT) := SUBSTR(l_string, l_index, l_comma_index - l_index); 17 l_index := l_comma_index + 1; 18 END LOOP; 19 RETURN l_tab; 20 END comma_to_table; 21 / Function created. SQL> sho err No errors. SQL> SQL> SELECT * FROM TABLE(comma_to_table(''ac_Abc.88,ac_Abc.99,ac_Abc.77'')) 2 / COLUMN_VALUE -------------------------------------------------------------------------------- ac_Abc.88 ac_Abc.99 ac_Abc.77 SQL>

4. Función segmentada

SQL> CREATE OR REPLACE 2 FUNCTION comma_to_table( 3 p_list IN VARCHAR2) 4 RETURN test_type PIPELINED 5 AS 6 l_string LONG := p_list || '',''; 7 l_comma_index PLS_INTEGER; 8 l_index PLS_INTEGER := 1; 9 BEGIN 10 LOOP 11 l_comma_index := INSTR(l_string, '','', l_index); 12 EXIT 13 WHEN l_comma_index = 0; 14 PIPE ROW ( SUBSTR(l_string, l_index, l_comma_index - l_index) ); 15 l_index := l_comma_index + 1; 16 END LOOP; 17 RETURN; 18 END comma_to_table; 19 / Function created. SQL> sho err No errors. SQL> SQL> SELECT * FROM TABLE(comma_to_table(''ac_Abc.88,ac_Abc.99,ac_Abc.77'')) 2 / COLUMN_VALUE -------------------------------------------------------------------------------- ac_Abc.88 ac_Abc.99 ac_Abc.77