如何在Oracle DB中将3.5k int插入数组

时间:2018-07-18 12:20:42

标签: sql oracle

我有自定义类型:

create or replace type integer_varray as varray (4000) of int;

然后使用该数组的表:

create table plan_capacities
(
  id       int generated by default as identity not null constraint plan_capacities_pkey primary key,
  line_id  int references lines (id) on delete cascade,
  model_id int references models (id) on delete cascade,
  plan_id  int references plans (id) on delete cascade,
  capacity integer_varray
);

然后要插入一些数据。问题是在Oracle中,我不能在数组“ constructor”这样简单的语句中使用超过1000个项目(我有3 500个项目)

INSERT INTO plan_capacities ("model_id", "line_id", "plan_id", "capacity") VALUES (1,1,1,integer_varray(1,2,3.....35000))

无法使用。 (数据是一些容量,必须按特定顺序排列。)

应该插入数组的数据是我必须输入脚本的字符串。 -> {1,10,11,10,20,0,0,0,1,10 ....}

如何插入大量数据?

我试图将它们插入到临时表中,然后用它们填充数组-这行得通,但该sql脚本有3500行(仅向plan_capacities创建一条记录),这是可怕的而且很大。

2 个答案:

答案 0 :(得分:3)

您可以将数组用作表,使用单个SQL语句将其值插入表中;例如:

declare
    vArray integer_varray;
begin
    -- some code to populate vArray

    insert into someTable(col)
    select column_value from table(vArray);
end;  

如果可以用查询填充数组,则不需要该数组,只需将查询用作插入语句的数据源即可;例如:

insert into someTable(col)
select something
from someOtherTable

如果您需要一种创建一组数字的方法,例如1,2,... 3500,这是一种常用的方法:

select level 
from dual 
connect by level <= 3500 

关于一种根据字符串构建一组数字的方法,这是一种非常常见的方法:

SQL> create or replace type integer_varray as varray (4000) of int
  2  /

Type created.

SQL> create table someTable(n number);

Table created.

SQL> declare
  2      vString     varchar2(32000) := '1,10,11,10,20,0,0,0,1,10';
  3      vArray      integer_varray;
  4  begin
  5      insert into someTable(n)
  6      select to_number(regexp_substr(vString, '[^,]+', 1, level))
  7      from dual
  8      connect by instr(vString, ',', 1, level - 1) > 0;
  9  end;
 10  /

PL/SQL procedure successfully completed.

SQL> select * from someTable;

         N
----------
         1
        10
        11
        10
        20
         0
         0
         0
         1
        10

10 rows selected.

SQL>

答案 1 :(得分:0)

所以我的最终解决方案是:

create or replace type integer_varray as varray (4000) of int;
/

create or replace type varchar_varray as varray (10) of varchar(32767);
/

declare
  data_to_be_stored varchar_varray := varchar_varray(
    '0,0,0,0,.....',
    '0,0,0,0,0,0....',
    '0,0,0,0,0,0....'
  );
  array_to_store    integer_varray := integer_varray();
begin
  for i in 1 .. data_to_be_stored.COUNT loop
    for j in (select to_number(trim(regexp_substr(data_to_be_stored(i), '[^,]+', 1, LEVEL))) value
              from dual
              connect by LEVEL <= regexp_count(data_to_be_stored(i), ',') + 1
    ) loop
      array_to_store.extend;
      array_to_store(array_to_store.count) := j.value;
    end loop;
  end loop;
  insert into table_with_that_array (array) values (array_to_store);
end;
\

我不得不使用varchar_varray,因为我的数据/字符串大于varchar2的最大容量,所以我将其拆分为数组中的多个字符串。