declare
type v_re is record
( name  varchar2(20),
  age   number
);
v_st    v_re;type aa is table of v_re index by binary_integer;
a    aa;
begin
     for i in 1..5000000 loop  ---这里的循环数量很大
        v_st.name:=''||ROUND(DBMS_RANDOM.VALUE(1,5000);--具体业务需要随机生成
        v_st.age :=ROUND(DBMS_RANDOM.VALUE(1,5000);
        
        --这里才是问题关键,向索引表里加入这个数据之前,我需要判断 索引表里 加入的record 是否
        --已经存在,就是 name 也相同,age也相同,这里的循环 灰常大,也就是索引表的数据非常多,怎么才能高效解决
        
        加入之前需要先判断是不是已经加入了,必须保持数据唯一性
        a(a.count):=v_st;
     end loop;
     
end;

解决方案 »

  1.   


    可以用oracle异常处理来实现
    create or replace procedure sp_test
    as
    ...
    begin
      --for loop 放这里执行
      
    exception
      when DUP_VAL_ON_INDEX then
        --主键重复执行此处
         --多个主键时,增加对sqlerrm里的主键名称判断
         null;
      

  2.   

    你还没有明白我的意思,因为数据量大,我要把生成的数据insert 到表里,我想进一步提高效率,所以想用
    forall 插入 ,这才把数据放入 索引表里的
      

  3.   

    要用forall的话,这批随机数事先并不存在,还是得要一个一个的生成,所以forall我觉得行不通其实你是怕主键重复的问题,可以用name与age的随机数加上一个递增或递减的数字,这样就可以保证生成name与age不会有重复
      

  4.   

    随机数我可以生成,也可以放入index 嵌套表内,但是怎么判断生成的新数据在嵌套表中是否存在,这个麻烦啊,大批量的话,嵌套表很大,怎么高效判断嵌套表有没有指定的数据,这个才是关键
      

  5.   

    forall可以使用 save EXCEPTIONSSQL> select * from t1;A                    B                             C
    -------------------- -------------------- ----------
    192                  1                             1
    193                  1                             2
    194                  1                             3
    -- 其中A是主键DECLARE
        TYPE LIST_TYPE IS TABLE OF VARCHAR2(20) INDEX BY PLS_INTEGER;
        mylist LIST_TYPE;
        err_cnt NUMBER;
        for_all_errors EXCEPTION;
        PRAGMA EXCEPTION_INIT(for_all_errors, -24381);
    BEGIN
        mylist(1) := '201';
        mylist(2) := '192';
        mylist(3) := '202';
        mylist(4) := '193';
        FORALL i IN mylist.FIRST .. mylist.LAST save EXCEPTIONS
            INSERT INTO t1(A) VALUES (mylist(i));
    EXCEPTION
        WHEN for_all_errors THEN
            err_cnt := SQL%BULK_EXCEPTIONS.COUNT;
            FOR i IN 1 .. err_cnt LOOP
                dbms_output.put_line('index:' || SQL%BULK_EXCEPTIONS(i).ERROR_INDEX || '  code:' || SQL%BULK_EXCEPTIONS(i).ERROR_CODE);
            END LOOP;
            COMMIT;
        WHEN OTHERS THEN
            NULL;       
    END;-- 结果:
    index:2  code:1
    index:4  code:1SQL> select * from t1;A                    B                             C
    -------------------- -------------------- ----------
    201                                       
    202                                       
    192                  1                             1
    193                  1                             2
    194                  1                             3