如何在PLSQL ORACLE中用10 M ~ 30 M的数字填充类型或集合

camsedfj  于 2023-02-07  发布在  Oracle
关注(0)|答案(1)|浏览(141)

你好stackoverflow朋友!
请帮助,我必须在游标或类型或表中分配一个值,因为100到300(我不知道哪一个更适合这个项目)。首先,我想用这些值填充类型或光标(10 M到30 M),然后随机选择其中一个,但只能选一次,我的意思是,它不能选102两次,例如,有数百万个条目,我不想影响数据库的性能。我试着用一个游标和n+1来做,但是太慢了...
感谢我的先知朋友们的帮助和建议。

yjghlzjz

yjghlzjz1#

我相信n + 1很慢;如果你这样做,那么一个接一个地插入2000万行肯定要花时间。2另一个选择是使用行生成器。
笔记本电脑上有21XE(没什么特别的;Intel i5,8GB RAM),内存不足,无法一次性完成:

SQL> create table test (id number);

Table created.

SQL> insert into test
  2  select 10e6 + level - 1
  3  from dual
  4  connect by level <= 20e6;
insert into test_20mil
            *
ERROR at line 1:
ORA-30009: Not enough memory for CONNECT BY operation

SQL>

如果你问 * 它是否真的有效?*,答案是 * 是 *-请参阅一个小样本:

SQL> select level
  2  from dual
  3  connect by level <= 5;

     LEVEL
----------
         1
         2
         3
         4
         5

SQL>

因此,我用一个循环做了20次,每次插入100万行一次到一个表中(不是逐行)。

SQL> create table test (id number primary key, cb_picked number(1));

Table created.

SQL> set serveroutput on
SQL> set timing on
SQL> declare
  2    l_mil number := 10e6;
  3  begin
  4    for i in 1 .. 20 loop
  5      insert into test (id)
  6        select l_mil + level - 1
  7        from dual
  8        connect by level <= 1e6;
  9      dbms_output.put_Line('inserted ' || sql%rowcount);
 10      l_mil := l_mil + 1e6;
 11    end loop;
 12  end;
 13  /
inserted 1000000
inserted 1000000
inserted 1000000
inserted 1000000
inserted 1000000
inserted 1000000
inserted 1000000
inserted 1000000
inserted 1000000
inserted 1000000
inserted 1000000
inserted 1000000
inserted 1000000
inserted 1000000
inserted 1000000
inserted 1000000
inserted 1000000
inserted 1000000
inserted 1000000
inserted 1000000

PL/SQL procedure successfully completed.

Elapsed: 00:01:25.77

正如你所看到的,这花了不到一分半钟。

SQL> set timing off
SQL> select count(*) from test;

        COUNT(*)
----------------
      20,000,000

SQL> select min(id), max(id) from test;

         MIN(ID)          MAX(ID)
---------------- ----------------
      10,000,000       29,999,999

SQL>

这是插入;如何获取随机选取的行?使用dbms_random.value函数。为了避免两次选择已经选取的值,请更新表的cb_picked列。为此,请创建一个自治事务函数(为什么?这样您就可以执行DML-update-并返回值)。

SQL> create or replace function f_rnd
  2    return number
  3  is
  4    pragma autonomous_transaction;
  5    retval number;
  6  begin
  7    select id
  8      into retval
  9      from test
 10      where cb_picked is null
 11        and id = round(dbms_random.value(10e6, 20e6));
 12    update test set cb_picked = 1
 13      where id = retval;
 14    commit;
 15    return retval;
 16  end;
 17  /

Function created.

我们试试看:

SQL> select f_rnd from dual;

     F_RND
----------
  19191411

SQL> select f_rnd from dual;

     F_RND
----------
  16411522

SQL> select * from test where cb_picked = 1;

        ID  CB_PICKED
---------- ----------
  16411522          1
  19191411          1

SQL>

就这样吧,我想。

相关问题