oracle 使用触发器创建复杂ID

7xzttuei  于 2022-12-22  发布在  Oracle
关注(0)|答案(1)|浏览(170)

在我们的许多应用程序中,我们使用标识列来生成唯一的编号,例如customer_id。
我们的内部审计员认为这可能是对安全性的破坏,未来我们希望使用更复杂一点的东西。
我发现了一个base34以下的函数,我想给它传递SYS_Guid、TIMESTAMP的一部分和序列号的串联,以创建一个更复杂的ID。
下面是我的测试用例。有没有一种方法可以在一个before INSERT触发器中使用base34函数,并使用上面的连接,而不改变base34函数来完成这个任务?
例如,假设我有下面的表。

CREATE TABLE CUSTOMERS (
 customer_id VARCHAR2 (20),
 first_name VARCHAR2 (20),
 last_name VARCHAR2 (20));

我希望触发器填充customer_id
提前感谢您的时间和专业知识。

create table t ( pk number);

 create sequence seq start with 1000000 minvalue 1000000 maxvalue 9999999 cycle;

 begin
      for i in 1 .. 10 loop
        insert into t values (            to_number(trunc(dbms_random.value(1000,9999))||                      to_char(systimestamp,'FFSS')||
                       seq.nextval));
      end loop;
    end;
/

create or replace function base34(p_num number) return varchar2 is
      l_dig varchar2(34) := 'AB0CD1EF2GH3JK4LM5NP6QR7ST8UV9WXYZ';
      l_num number := p_num;
      l_str varchar2(38);
    begin
     loop
        l_str := substr(l_dig,mod(l_num,34)+1,1) || l_str ;
        l_num := trunc(l_num/34);
       exit when l_num = 0;
     end loop;
    return l_str;
   end;
 /
 
create or replace function dec34(p_str varchar2) return number is
     l_dig varchar2(34) := 'AB0CD1EF2GH3JK4LM5NP6QR7ST8UV9WXYZ';
      l_num number := 0;
    begin
     for i in 1 .. length(p_str) loop
        l_num := l_num * 34 + instr(l_dig,upper(substr(p_str,i,1)))-1;
      end loop;
     return l_num;
   end;
 /

select base34(pk) from t where rownum <= 10;

 select to_char(pk) from t where rownum = 1
    union all
    select base34(pk) from t where rownum = 1
    union all
    select to_char(dec34(base34(pk))) from t where rownum = 1;
nlejzf6q

nlejzf6q1#

CREATE TABLE CUSTOMERS (
 customer_id VARCHAR2 (20),
 first_name VARCHAR2 (20),
 last_name VARCHAR2 (20));

create sequence seq start with 1000000 minvalue 1000000 maxvalue 9999999 cycle;

create or replace function base34(p_num number) return varchar2 is
      l_dig varchar2(34) := 'AB0CD1EF2GH3JK4LM5NP6QR7ST8UV9WXYZ';
      l_num number := p_num;
      l_str varchar2(38);
    begin
     loop
        l_str := substr(l_dig,mod(l_num,34)+1,1) || l_str ;
        l_num := trunc(l_num/34);
       exit when l_num = 0;
     end loop;
    return l_str;
   end;
 

CREATE OR REPLACE TRIGGER customer_trg
BEFORE    INSERT 
ON    customers 
FOR EACH ROW
BEGIN
    :NEW.customer_id := base34(to_number(trunc(dbms_random.value(1000,9999))||                      to_char(systimestamp,'FFSS')||
                       seq.nextval));
END;

begin
      for i in 1 .. 100 loop
         INSERT into customers (first_name, last_name) VALUES ('John', 'Doe');
              end loop;
    end;
/

相关问题