主键字母自动生成函数

-- 动态生成字母方式主键,A-Z 大于Z自动进位【26进制数值表示】


-- 参数:动态查询表和主键列
create or replace function charkey (tabName char, pkName char) return char
as
  v_key varchar2(4);        -- 表中查询出当前主键列最大值
  v_char varchar2(4) := ''; -- 输出用变量
  v_len number(1);          -- 查询出最大值字符串长度
  v_i number(1);            -- 循环控制变量
  v_c char(1);              -- 提取单个字符变量
  v_flag number(1) := 1;    -- 是否'进位'变量
  v_count number;           -- 查询表中记录总数
begin
   -- 查询表中记录数
   execute immediate 'select count(1) from ' || tabName into v_count;
  
   -- 如果表中没有记录,则返回'A'
   if (v_count = 0) then 
      v_char := 'A';
      return v_char;
   end if;
   
   -- 获取指定表中主键列当前最大值
   execute immediate 'select ' || pkName || ' from ' ||
   '(select rownum r, t.' || pkName || ' from ' ||
   '(select ' || pkName || ' from ' || tabName || 
   ' order by length(' || pkName || ') desc, ' || pkName || ' desc) t) where r < 2'
   into v_key;
   
   -- 字符串长度
   v_len := length(v_key);
   -- 循环控制变量
   v_i := v_len;
   
   -- 从最后一个字符开始,向前循环遍历
   while v_i >= 1 loop
     v_c := substr(v_key, v_i, 1);
     -- 如果需要进位,当前字符+1
     if(v_flag = 1) then
       v_c := chr(ascii(v_c)+1);
       v_flag := 0;
     end if;
     -- 当前字符超出上限
     if( ascii(v_c) > ascii('Z')) then
       v_c := 'A';
       v_flag := 1;
     end if;
     
     v_char := v_c || v_char;
     v_i := v_i - 1;
   end loop;
   -- 如果遇到ZZ情况,需要补充一位'A'
   if(v_flag = 1) then
     v_char := 'A' || v_char;
   end if;  
   return v_char;
end;


-- 测试表
create table testtab
(
   id varchar2(4) primary key,
   val number(4)
);


-- 测试通过函数动态生成主键插入数据
declare
  v_count number(9) := 1;
begin
  while v_count <= 30 loop
    
    insert into testtab values(charkey('testtab','id'), 1);  
  
    v_count := v_count + 1;
  end loop;
end;




select * from testtab;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值