Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

array ou lista no Oracle usando cfprocparam


PL/SQL tem suporte a arrays desde o Oracle 8.0. Elas costumavam ser chamadas de tabelas PL/SQL que confundiam todo mundo, então agora elas são chamadas de coleções. Saiba mais.

O problema é que eles são implementados como tipos definidos pelo usuário (ou seja, objetos). Minha leitura dos documentos do ColdFusion sugere que cfprocparam suporta apenas os tipos de dados "primitivos" (number, varchar2, etc). Portanto, UDTs não são suportados.

Não tenho certeza do que você quer dizer com isso:

Se você quer dizer que deseja passar uma string de valores separados por vírgulas ....
"Fox in socks, Mr Knox, Sam-I-Am, The Lorax"

então eu tenho uma solução para você. A Oracle não fornece um Tokenizer integrado. Mas há muito tempo, John Spencer publicou uma solução feita à mão que funciona no Oracle 9i nos fóruns da OTN. Encontre aqui.

editar

Não se desespere. Os fóruns da OTN foram atualizados algumas vezes desde que John postou isso, e a formatação parece ter corrompido o código em algum lugar ao longo do caminho. Houve alguns erros de compilação que não costumava ter.

Reescrevi o código de John, incluindo uma nova função. A principal diferença é que a tabela aninhada é declarada como um tipo SQL em vez de um 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;
/

Como você pode ver, a função é apenas um wrapper para o procedimento.
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;
/

A virtude de declarar o tipo em SQL é que podemos usá-lo em uma cláusula FROM como esta:
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>