数组或列表导入Oracle中使用cfprocparam [英] array or list into Oracle using cfprocparam

查看:230
本文介绍了数组或列表导入Oracle中使用cfprocparam的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个值列表,我想通过存储过程插入到表中。
我想我会传递一个数组到oracle和循环通过数组,但我不知道如何传递一个数组到Oracle。我会通过一个列表,但我不明白如何使用列表,将它变成一个数组使用PL / SQL(我是相当新的PL / SQL)。我接近这个错误的方式?

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 pass an array into Oracle. 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 (I'm fairly new to PL/SQL). Am I approaching this the wrong way?

使用Oracle 9i和CF8。

Using Oracle 9i and CF8.

EDIT

也许我在想这个错误的方式?我确定我不在这里做任何新的...
我想我会将列表转换为关联数组,然后循环数组,因为Oracle似乎不能很好地与列表(在我的限制观察)。

Perhaps I'm thinking about this the wrong way? I'm sure I'm not doing anything new here... I figured I'd convert the list to an associative array then loop the array because Oracle doesn't seem to work well with lists (in my limited observation).

我正在尝试添加产品,然后为管理团队添加记录。

- 产品表

I'm trying to add a product, then add records for the management team.
-- product table

productName ='foo'
productDescription ='bar'
...
...
etc

productName = 'foo' productDescription = 'bar' ... ... etc

- managementteam表只有从下拉列表中选择的用户的产品ID和用户ID。

-- The managementteam table just has the id of the product and id of the users selected from a drop down.

用户ID通过像1,3,6,20这样的列表传递

The user IDs are passed in via a list like "1,3,6,20"

如何将记录添加到管理团队表中?

How should I go about adding the records to the management team table?

理论上我通过一个列表 1,2,3,4到inserts.addProduct。

inserts.addProduct应调用tools.listToArray并返回一个数组。

inserts.addProduct重新创建一个带有* delim的列表作为测试。

CREATE OR REPLACE PACKAGE工具AS

In theory I pass a list "1,2,3,4" to inserts.addProduct.
inserts.addProduct should call tools.listToArray and return an array.
inserts.addProduct recreates a list with a * delim as a test.
CREATE OR REPLACE PACKAGE tools AS

  TYPE array_type is TABLE OF VARCHAR2(225) INDEX BY BINARY_INTEGER;

  FUNCTION listToArray(in_list IN VARCHAR,
                     in_delim IN VARCHAR2 DEFAULT ',') 
  RETURN array_type;

END tools;



CREATE OR REPLACE PACKAGE BODY tools
AS

FUNCTION listToArray(in_list IN VARCHAR,
                         in_delim IN VARCHAR2 DEFAULT ',') 
    RETURN array_type

    IS
    l_token_count BINARY_INTEGER := 0;
    -- l_token_tbl type_array; 
    i pls_integer;
    l_start_pos INTEGER := 1;
    l_end_pos INTEGER :=1;
    p_parsed_table array_type;

    BEGIN -- original work by John Spencer  
       WHILE l_end_pos <> 0 LOOP
          l_end_pos := instr(in_list,in_delim,l_start_pos);
          IF l_end_pos <> 0 THEN
             l_token_count  := l_token_count  + 1;
             p_parsed_table(l_token_count ) :=
                      substr(in_list,l_start_pos,l_end_pos - l_start_pos);
             l_start_pos := l_end_pos + 1;
          END IF;
       END LOOP;
       IF l_token_count = 0 THEN /* We haven't parsed anything so */ 
          l_token_count := 1;
          p_parsed_table(l_token_count) := in_list;
       ELSE  /* We need to get the last token */ 
          l_token_count := l_token_count + 1;
          p_parsed_table(l_token_count) := substr(in_list,l_start_pos);
       END If;
       RETURN p_parsed_table;
    END listToArray;  -- Procedure

END tools;



CREATE OR REPLACE PACKAGE inserts AS
    TYPE array_type is TABLE OF VARCHAR2(225) INDEX BY BINARY_INTEGER;

    PROCEDURE addProduct (inList         IN  VARCHAR2,
                          outList        OUT VARCHAR2
                         );

END inserts;  




CREATE OR REPLACE PACKAGE BODY inserts                      

    AS
    PROCEDURE addProduct (inList         IN  VARCHAR2,
                          outList        OUT VARCHAR2
                         )
    IS
    i NUMBER;
    localArray array_type := tools.listToArray(inList);
    BEGIN       
       outList := '';
       FOR i IN localArray.first .. localArray.last LOOP
          outList := outList || '*' ||localArray(i); -- return a string just to test this mess 
       END LOOP;

    END addProduct;

END inserts;

我当前在localArray上得到一个错误PLS-00382:expression is type type := tools.listToArray(inList);

I'm currently getting an error "PLS-00382: expression is of wrong type" on localArray array_type := tools.listToArray(inList);

- 创建sql类型集合

-- create sql type collection

CREATE OR REPLACE TYPE array_type is TABLE OF VARCHAR2(225);
/



CREATE OR REPLACE PACKAGE tools AS

  FUNCTION listToArray(in_list IN VARCHAR,
                     in_delim IN VARCHAR2 DEFAULT ',') 
  RETURN array_type;

END tools;   
/



CREATE OR REPLACE PACKAGE BODY tools
AS

    FUNCTION listToArray(in_list IN VARCHAR,
                         in_delim IN VARCHAR2 DEFAULT ',') 
    RETURN array_type

    IS
    l_token_count BINARY_INTEGER := 0;
    i pls_integer;
    l_start_pos INTEGER := 1;
    l_end_pos INTEGER :=1;
    p_parsed_table array_type := array_type();

    BEGIN
       WHILE l_end_pos <> 0 LOOP
          l_end_pos := instr(in_list,in_delim,l_start_pos);
          IF l_end_pos <> 0 THEN
             p_parsed_table.extend(1);
             l_token_count  := l_token_count  + 1;
             p_parsed_table(l_token_count ) :=
                      substr(in_list,l_start_pos,l_end_pos - l_start_pos);
             l_start_pos := l_end_pos + 1;
          END IF;

       END LOOP;
       p_parsed_table.extend(1);
       IF l_token_count = 0 THEN /* We haven't parsed anything so */ 
          l_token_count := 1;
          p_parsed_table(l_token_count) := in_list;
       ELSE  /* We need to get the last token */ 
          l_token_count := l_token_count + 1;
          p_parsed_table(l_token_count) := substr(in_list,l_start_pos);
       END If;
       RETURN p_parsed_table;
    END listToArray;  -- Procedure

END tools;
/



CREATE OR REPLACE PACKAGE inserts AS

    PROCEDURE addProduct (inList  IN  VARCHAR2,
                             outList OUT VARCHAR2
                         );

END inserts;
/




CREATE OR REPLACE PACKAGE BODY inserts
AS
    PROCEDURE addProduct (inList  IN  VARCHAR2,
                          outList OUT VARCHAR2
                         )
    IS
    i NUMBER;
    mylist VARCHAR(100);
    localArray array_type := array_type();

    BEGIN     
    localArray := tools.listToArray(inList);
       mylist := '';
       FOR i IN localArray.first .. localArray.last LOOP
          mylist := mylist || localArray(i) || '*';
       END LOOP;
       aList := mylist;
    END addProduct;

END inserts;  
/


推荐答案

自Oracle 8.0。它们曾经被称为PL / SQL表,它们混淆了每个人的想法,所以现在他们被称为集合。

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.

问题是,它们被实现为用户定义的类型(即对象)。我对 ColdFusion文档的阅读表明, cfprocparam 只支持原始数据类型(number,varchar2等)。因此不支持UDT。

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:


我会传递一个列表,但我不知道如何
使用列表,将它转换成一个
数组使用PL / SQL

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"

然后我有一个解决方法为你。 Oracle不提供内置的Tokenizer。但很久以前,约翰·斯潘塞发表了一个手动的解决方案,在Oracle 9i在OTN论坛上工作。 在此处查找

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.

编辑


但是... Oracle讨厌我

but... Oracle hates me

不要绝望。自从John发布以来,OTN论坛已经升级了好几次,并且格式化似乎已经破坏了某处的代码。有一些编译错误,它没有使用。

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.

我重写了John的代码,包括一个新的函数。主要的区别是嵌套表被声明为SQL类型,而不是PL / SQL类型。

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

正如你所看到的,函数只是一个包装器。 / p>

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

在SQL中声明类型的好处是我们可以在FROM子句,像这样:

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> 

这篇关于数组或列表导入Oracle中使用cfprocparam的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆