ORCLE 中15位身份证号转18为存储过程

procedure :

create or replace procedure PROC_PID15TO18(pid in varchar2, tabName in varchar2) is
  v_sqlerrm varchar2(500);
  v_sql varchar2(200);
BEGIN 
  v_sql:='UPDATE ' || tabName || ' SET ' || pid || '=' ||
         ' CASE WHEN LENGTH(' || pid || ')=15 THEN ' ||
              'FUN_PID15TO18(' || pid || ')' ||
           ' WHEN LENGTH(' || pid || ')=18 THEN ' ||
               pid ||
           ' ELSE ' ||
              '''000000000000000000''' ||
         ' END ';
  EXECUTE IMMEDIATE v_sql;
  COMMIT;
EXCEPTION
  when others then
    v_sqlerrm := substr(SQLERRM, 1, 300);
    dbms_output.put_line('ERR=' || v_sqlerrm);
    rollback;
end PROC_PID15TO18;


function :

create or replace function FUN_PID15TO18(pid15 in char) return char is
  TYPE array_17_number IS VARRAY(17) OF NUMBER;
  TYPE array_11_char IS VARRAY(11) OF char;
  Result         varchar2(18);
  v_check_number integer := 0;
  v_check_char   char(1);
  v_factor       array_17_number := array_17_number(7,
                                                    9,
                                                    10,
                                                    5,
                                                    8,
                                                    4,
                                                    2,
                                                    1,
                                                    6,
                                                    3,
                                                    7,
                                                    9,
                                                    10,
                                                    5,
                                                    8,
                                                    4,
                                                    2);

  v_mod array_11_char := array_11_char('1',
                                       '0',
                                       'X',
                                       '9',
                                       '8',
                                       '7',
                                       '6',
                                       '5',
                                       '4',
                                       '3',
                                       '2');
begin
  if (length(pid15) = 18) then
    return pid15;
  elsif (length(pid15) = 15) then
    result := substr(pid15, 1, 6) || '19' || substr(pid15, 7, 9);
    FOR i IN 1 .. 17 LOOP
      v_check_number := to_number(substr(result, i, 1)) * v_factor(i) +
                        v_check_number;
    END LOOP;
 
    v_check_number := mod(v_check_number, 11);
    v_check_char   := v_mod(v_check_number + 1);
    result         := result || v_check_char;
    return result;
  else
    raise_application_error(-20001, 'Length of pid should be 15 or 18!');
  end if;
end FUN_PID15TO18;

猜你喜欢

转载自blog.csdn.net/lanbery/article/details/3491540