Oracle
 sql >> Database >  >> RDS >> Oracle

array o list in Oracle usando cfprocparam

PL/SQL supporta gli array da Oracle 8.0. Un tempo venivano chiamate tabelle PL/SQL che confondevano tutti, quindi ora sono chiamate raccolte. Scopri di più.

Il problema è che sono implementati come tipi definiti dall'utente (cioè oggetti). La mia lettura dei documenti ColdFusion suggerisce che cfprocparam supporta solo i tipi di dati "primitivi" (number, varchar2, ecc.). Quindi gli UDT non sono supportati.

Non sono sicuro di cosa intendi con questo:

Se vuoi dire che vuoi passare una stringa di valori separati da virgole ....

"Fox in socks, Mr Knox, Sam-I-Am, The Lorax"

allora ho una soluzione per te. Oracle non fornisce un tokenizzatore integrato. Ma molto tempo fa John Spencer ha pubblicato una soluzione manuale che funziona in Oracle 9i sui forum OTN. Lo trovi qui.

modifica

Non disperate. I forum OTN sono stati aggiornati alcune volte da quando John lo ha pubblicato e la formattazione sembra aver danneggiato il codice da qualche parte lungo il percorso. C'erano un paio di errori di compilazione che prima non aveva.

Ho riscritto il codice di John, inclusa una nuova funzione. La differenza principale è che la tabella nidificata è dichiarata come tipo SQL anziché come tipo PL/SQL.

create or replace type tok_tbl as table of varchar2(225) 
/

create or replace package parser is

    function my_parse(
          p_str_to_search in varchar2
            , p_delimiter in varchar2 default ',')
          return tok_tbl;

    procedure my_parse(
          p_str_to_search in varchar2
          , p_delimiter in varchar2 default ','
          , p_parsed_table out tok_tbl);

end parser;
/

Come puoi vedere, la funzione è solo un wrapper della procedura.

create or replace package body parser is

    procedure my_parse ( p_str_to_search in varchar2
                          , p_delimiter in varchar2 default ','
                          , p_parsed_table out tok_tbl)
    is
        l_token_count binary_integer := 0;
        l_token_tbl tok_tbl := tok_tbl();
        i pls_integer;
        l_start_pos integer := 1;
        l_end_pos integer :=1;   
    begin

        while l_end_pos != 0
        loop
            l_end_pos := instr(p_str_to_search,p_delimiter,l_start_pos);

            if l_end_pos  != 0 then
                l_token_count := l_token_count + 1;
                l_token_tbl.extend();
                l_token_tbl(l_token_count ) :=
                    substr(p_str_to_search,l_start_pos,l_end_pos - l_start_pos);
                l_start_pos := l_end_pos + 1;
            end if;
        end loop;

        l_token_tbl.extend();
        if l_token_count = 0 then /* we haven't parsed anything so */
            l_token_count := 1;
            l_token_tbl(l_token_count) := p_str_to_search;
        else /* we need to get the last token */
            l_token_count := l_token_count + 1;
            l_token_tbl(l_token_count) := substr(p_str_to_search,l_start_pos);
        end if;
        p_parsed_table := l_token_tbl;
    end my_parse;

    function my_parse ( p_str_to_search in varchar2
                            , p_delimiter in varchar2 default ',')
                          return tok_tbl
    is
        rv tok_tbl;
    begin
        my_parse(p_str_to_search, p_delimiter, rv);
        return rv;
    end my_parse;

end parser;
/

Il vantaggio di dichiarare il tipo in SQL è che possiamo usarlo in una clausola FROM come questa:

SQL> insert into t23
  2  select trim(column_value)
  3  from table(parser.my_parse('Fox in socks, Mr Knox, Sam-I-Am, The Lorax'))
  4  /

4 rows created.

SQL> select * from t23
  2  /

TXT
------------------------------------------------------------------------------
Fox in socks
Mr Knox
Sam-I-Am
The Lorax

SQL>