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