sql 生成唯一随机数字字符串

时间:2022-11-04 22:11:43

 

 

oracle 实现快速批量生成随机数字字符串:

--
create table RANDOM_NUMBER_TEMP
(
  ROW_NUM    NUMBER default 0 not null,
  RANDOM_NUM VARCHAR2(30) not null
 
)
--type
type number_array_t is table of number index by binary_integer;
--实现生成唯一随机数
PROCEDURE INIT_RANDOM_NUMBRE(P_QUANTITY  IN NUMBER,   --生成数量
                             P_LEN       IN NUMBER, --随机数长度                            
                             STATUS      OUT VARCHAR2,
                             REEOR_MES   OUT VARCHAR2         
   )IS   
    number_array       number_array_t;
    v_number_array_len number ;
    v_random_index     number;
    new_number_array   number_array_t;
    new_num_arr_index  integer :=1;
    
    V_ROW_NUM          integer  := 0;
    V_MAX_INDEX        NUMBER;
    V_EMPTY_COUNT      NUMBER := 0 ;  --检测到空值的次数
    --n                  integer  :=1 ; --测试用的,统计重至number_array数组次数
    tag_number         NUMBER := 0.25; --允许检测到空值的比例
    V_MAC_EMPTY_COUNT  number := 100; --允许检测到空值的次数的最大值
    
   BEGIN   
        STATUS := CONST_TRUE;
         v_number_array_len := POWER(10,P_LEN);
        --生成条数大于随机数数量最大值。
        if P_QUANTITY>v_number_array_len then
            v_number_array_len := P_QUANTITY;
          -- return 'N';
        end if;
        for k in 0..v_number_array_len-1 loop
           number_array(k+1) := k;
        end loop;
        
        V_MAX_INDEX := number_array.count;
        V_MAC_EMPTY_COUNT :=CEIL(V_MAX_INDEX * tag_number);                                
        loop 
            exit when V_ROW_NUM = P_QUANTITY or number_array.count = 0;--V_ROW_NUM 从0开始
            v_random_index := round(dbms_random.value(0.5,V_MAX_INDEX));         
            
             IF number_array.EXISTS( v_random_index) THEN   
                   V_ROW_NUM := V_ROW_NUM + 1;    
                   INSERT INTO sfc.random_number_temp(ROW_NUM, random_num) VALUES(V_ROW_NUM,LPAD(to_char(number_array(v_random_index)),P_LEN,'0'));                    
                   number_array.DELETE( v_random_index); 
            ELSE
                V_EMPTY_COUNT := V_EMPTY_COUNT +1;
                IF V_EMPTY_COUNT > V_MAC_EMPTY_COUNT THEN
                   if number_array.count <=V_MAX_INDEX then
                     new_num_arr_index :=1;
                     for t in 1..V_MAX_INDEX loop
                           if number_array.EXISTS(t) then
                              new_number_array(new_num_arr_index) := number_array(t);
                              new_num_arr_index := new_num_arr_index + 1;
                           end if;  
                      end loop;      
                    end if;
                  number_array := new_number_array;    
                  new_number_array.delete(); --清空数组              
                  V_MAX_INDEX := number_array.count;
                  V_MAC_EMPTY_COUNT :=CEIL(V_MAX_INDEX * tag_number);--重至取空次数
                  --n := n+1;  
                  V_EMPTY_COUNT := 0;                      
                 END IF; 
            END IF;
        end loop;  
       COMMIT;
    EXCEPTION
      WHEN OTHERS THEN
        STATUS := CONST_FALSE;
        REEOR_MES := SQLCODE || '::' || SUBSTR(SQLERRM, 1, 500);  
   END;

代码实现:

1.把最小值到最大值依次存入一个临时数组中。

2.从数组中随机取出一个值放入表中,并删除该值。

3.重复步骤2,直到取出空值的次数达到指定的次数,重新生成临时数组,把临时数组中的空值去掉,然后再重复步骤2。