sql from ottenendo "elenco separato da virgole vicino a 'xx.yy' non valido" con dbms_utility.comma_to_table




split string function oracle (2)

È perché ( riferimento al documento Oracle )

COMMA_TO_TABLE Procedure

Queste procedure converte un elenco di nomi delimitati da virgole in una tabella di nomi PL / SQL. La seconda versione supporta nomi di attributi completi.

Un "nome" a cui si fa riferimento qui è un identificativo Oracle (oggetto DB) valido, per il quale si applicano tutte le regole di denominazione. ac_Abc.88 non è un nome valido, perché in Oracle non è possibile avere un identificatore che inizi con una cifra.

Per risolvere il problema con l'analisi di stringhe di valori delimitati da virgole, utilizzare la soluzione di seguito di Lalit Kumar.

Ho una stringa come questa: str: = 'ac_Acc.88, ac_Abc.99, ac_Abc.77'. Ho bisogno di ottenere il primo elemento dopo aver diviso con la virgola (,). Quindi sto usando usando in questo modo:

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

Sto ricevendo l'errore seguente:

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

Ma se ho una stringa come questa, str: = 'ac_Abc88, ac_Abc99, ac_Abc77', lo stesso metodo funziona bene e mi dà risultati attesi.

Quindi immagino che ci sia qualcosa da correggere da considerare "." come personaggio regolare. Potete per favore suggerire come posso risolvere questo.


Vedi Come dividere la stringa delimitata da virgole in righe

1. Approccio 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. Approccio 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. Funzione tabella

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. Funzione pipelined

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






string-split