array or list into Oracle using cfprocparam

后端 未结 1 1046
盖世英雄少女心
盖世英雄少女心 2021-01-14 10:58

I have a list of values I want to insert into a table via a stored procedure. I figured I would pass an array to oracle and loop through the array but I don\'t see how to pa

相关标签:
1条回答
  • 2021-01-14 11:11

    PL/SQL has supported arrays since Oracle 8.0. They used to be called PL/SQL tables which confused the heck out of everybody, so now they are called collections. Find out more.

    The problem is, that they are implemented as User-Defined Types (i.e. objects). My reading of the ColdFusion documents suggests that cfprocparam only supports the "primitive" datatypes (number, varchar2, etc). So UDTs are not supported.

    I'm not sure what you mean by this:

    I'd pass a list but I don't see how to work with the list to turn it into an array using PL/SQL

    If you mean you want to pass a string of comma separated values ....

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

    then I have a workaround for you. Oracle doesn't provide a built-in Tokenizer. But a long time ago John Spencer published a hand-rolled solution which works in Oracle 9i on the OTN forums. Find it here.

    edit

    but... Oracle hates me

    Do not despair. The OTN forums have been upgraded a few times since John posted that , and the formatting seems to have corrupted the code somewhere along the way. There were a couple of compilation errors which it didn't use to have.

    I have rewritten John's code, including a new function. THe main difference is that the nested table is declared as a SQL type rather than a PL/SQL type.

    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;
    /
    

    As you can see, the function is just a wrapper to the procedure.

    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;
    /
    

    The virtue of declaring the type in SQL is that we can use it in a FROM clause like this:

    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> 
    
    0 讨论(0)
提交回复
热议问题