系统城装机大师 - 固镇县祥瑞电脑科技销售部宣传站!

当前位置:首页 > 数据库 > oracle > 详细页面

oracle 身份证校验函数的实例代码

时间:2020-01-02来源:系统城作者:电脑系统城

1、正则表达式写法:


 
  1. CREATE OR REPLACE FUNCTION Func_checkidcard (p_idcard IN VARCHAR2) RETURN INT
  2. IS
  3. v_regstr VARCHAR2 (2000);
  4. v_sum NUMBER;
  5. v_mod NUMBER;
  6. v_checkcode CHAR (11) := '10X98765432';
  7. v_checkbit CHAR (1);
  8. v_areacode VARCHAR2 (2000) :='11,12,13,14,15,21,22,23,31,32,33,34,35,36,37,41,42,43,44,45,46,50,51,52,53,54,61,62,63,64,65,71,81,82,91,';
  9. BEGIN
  10. CASE LENGTHB (p_idcard)
  11. WHEN 15
  12. THEN -- 15位
  13. IF INSTRB (v_areacode, SUBSTR (p_idcard, 1, 2) || ',') = 0 THEN
  14. RETURN 0;
  15. END IF;
  16.  
  17. IF MOD (TO_NUMBER (SUBSTRB (p_idcard, 7, 2)) + 1900, 400) = 0
  18. OR
  19. (
  20. MOD (TO_NUMBER (SUBSTRB (p_idcard, 7, 2)) + 1900, 100) <> 0
  21. AND
  22. MOD (TO_NUMBER (SUBSTRB (p_idcard, 7, 2)) + 1900, 4) = 0
  23. )
  24. THEN -- 闰年
  25. v_regstr :=
  26. '^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}$';
  27. ELSE
  28. v_regstr :=
  29. '^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}$';
  30. END IF;
  31.  
  32. IF REGEXP_LIKE (p_idcard, v_regstr) THEN
  33. RETURN 1;
  34. ELSE
  35. RETURN 0;
  36. END IF;
  37. WHEN 18
  38. THEN -- 18位
  39. IF INSTRB (v_areacode, SUBSTRB (p_idcard, 1, 2) || ',') = 0 THEN
  40. RETURN 0;
  41. END IF;
  42.  
  43. IF MOD (TO_NUMBER (SUBSTRB (p_idcard, 7, 4)), 400) = 0
  44. OR
  45. (
  46. MOD (TO_NUMBER (SUBSTRB (p_idcard, 7, 4)), 100) <> 0
  47. AND
  48. MOD (TO_NUMBER (SUBSTRB (p_idcard, 7, 4)), 4) = 0
  49. )
  50. THEN -- 闰年
  51. v_regstr :=
  52. '^[1-9][0-9]{5}(19|20)[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}[0-9Xx]$';
  53. ELSE
  54. v_regstr :=
  55. '^[1-9][0-9]{5}(19|20)[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}[0-9Xx]$';
  56. END IF;
  57.  
  58. IF REGEXP_LIKE (p_idcard, v_regstr) THEN
  59. v_sum :=
  60. ( TO_NUMBER (SUBSTRB (p_idcard, 1, 1))
  61. + TO_NUMBER (SUBSTRB (p_idcard, 11, 1))
  62. )
  63. * 7
  64. + ( TO_NUMBER (SUBSTRB (p_idcard, 2, 1))
  65. + TO_NUMBER (SUBSTRB (p_idcard, 12, 1))
  66. )
  67. * 9
  68. + ( TO_NUMBER (SUBSTRB (p_idcard, 3, 1))
  69. + TO_NUMBER (SUBSTRB (p_idcard, 13, 1))
  70. )
  71. * 10
  72. + ( TO_NUMBER (SUBSTRB (p_idcard, 4, 1))
  73. + TO_NUMBER (SUBSTRB (p_idcard, 14, 1))
  74. )
  75. * 5
  76. + ( TO_NUMBER (SUBSTRB (p_idcard, 5, 1))
  77. + TO_NUMBER (SUBSTRB (p_idcard, 15, 1))
  78. )
  79. * 8
  80. + ( TO_NUMBER (SUBSTRB (p_idcard, 6, 1))
  81. + TO_NUMBER (SUBSTRB (p_idcard, 16, 1))
  82. )
  83. * 4
  84. + ( TO_NUMBER (SUBSTRB (p_idcard, 7, 1))
  85. + TO_NUMBER (SUBSTRB (p_idcard, 17, 1))
  86. )
  87. * 2
  88. + TO_NUMBER (SUBSTRB (p_idcard, 8, 1)) * 1
  89. + TO_NUMBER (SUBSTRB (p_idcard, 9, 1)) * 6
  90. + TO_NUMBER (SUBSTRB (p_idcard, 10, 1)) * 3;
  91. v_mod := MOD (v_sum, 11);
  92. v_checkbit := SUBSTRB (v_checkcode, v_mod + 1, 1);
  93.  
  94. IF v_checkbit = upper(substrb(p_idcard,18,1)) THEN
  95. RETURN 1;
  96. ELSE
  97. RETURN 0;
  98. END IF;
  99. ELSE
  100. RETURN 0;
  101. END IF;
  102. ELSE
  103. RETURN 0; -- 身份证号码位数不对
  104. END CASE;
  105. EXCEPTION
  106. WHEN OTHERS
  107. THEN
  108. RETURN 0;
  109. END fn_checkidcard;
  110. /
  111. Show Err;

2、非正则表达式写法


 
  1. Create Or Replace Function Func_checkIdcard (p_idcard in varchar2) Return Number
  2. Is
  3. v_sum Number;
  4. v_mod Number;
  5. v_length Number;
  6. v_date Varchar2(10);
  7. v_isDate Boolean;
  8. v_isNumber Boolean;
  9. v_isNumber_17 Boolean;
  10. v_checkbit CHAR (1);
  11. v_checkcode CHAR (11) := '10X98765432';
  12. v_areacode VARCHAR2 (2000) :='11,12,13,14,15,21,22,23,31,32,33,34,35,36,37,41,42,43,44,45,46,50,51,52,53,54,61,62,63,64,65,71,81,82,91,';
  13.  
  14. --[isNumber]--
  15. Function isNumber (p_string in varchar2) Return Boolean
  16. Is
  17. i number;
  18. k number;
  19. flag boolean;
  20. v_length number;
  21. Begin
  22. /*
  23. 算法:
  24. 通过ASCII码判断是否数字,介于[48, 57]之间。
  25. select ascii('0'),ascii('1'),ascii('2'),ascii('3'),ascii('4'),ascii('5'),ascii('6'),ascii('7'),ascii('8'),ascii('9') from dual;
  26. */
  27.  
  28. flag := True;
  29. select length(p_string) into v_length from dual;
  30.  
  31. for i in 1..v_length loop
  32. k := ascii(substr(p_string,i,1));
  33. if k < 48 or k > 57 then
  34. flag := False;
  35. Exit;
  36. end if;
  37. end loop;
  38.  
  39. Return flag;
  40. End isNumber;
  41.  
  42. --[isDate]--
  43. Function isDate (p_date in varchar2) Return Boolean
  44. Is
  45. v_flag boolean;
  46. v_year number;
  47. v_month number;
  48. v_day number;
  49. v_isLeapYear boolean;
  50. Begin
  51. --[初始化]--
  52. v_flag := True;
  53.  
  54. --[获取信息]--
  55. v_year := to_number(substr(p_date,1,4));
  56. v_month := to_number(substr(p_date,5,2));
  57. v_day := to_number(substr(p_date,7,2));
  58.  
  59. --[判断是否为闰年]--
  60. if (mod(v_year,400) = 0) Or (mod(v_year,100) <> 0 And mod(v_year,4) = 0) then
  61. v_isLeapYear := True;
  62. else
  63. v_isLeapYear := False;
  64. end if;
  65.  
  66. --[判断月份]--
  67. if v_month < 1 Or v_month > 12 then
  68. v_flag := False;
  69. Return v_flag;
  70. end if;
  71.  
  72. --[判断日期]--
  73. if v_month in (1,3,5,7,8,10,12) and (v_day < 1 or v_day > 31) then
  74. v_flag := False;
  75. end if;
  76. if v_month in (4,6,9,11) and (v_day < 1 or v_day > 30) then
  77. v_flag := False;
  78. end if;
  79. if v_month in (2) then
  80. if (v_isLeapYear) then
  81. --[闰年]--
  82. if (v_day < 1 or v_day > 29) then
  83. v_flag := False;
  84. end if;
  85. else
  86. --[非闰年]--
  87. if (v_day < 1 or v_day > 28) then
  88. v_flag := False;
  89. end if;
  90. end if;
  91. end if;
  92.  
  93. --[返回结果]--
  94. Return v_flag;
  95. End isDate;
  96. Begin
  97. /*
  98. 返回值说明:
  99. -1 身份证号码位数不对
  100. -2 身份证号码出生日期超出范围
  101. -3 身份证号码含有非法字符
  102. -4 身份证号码校验码错误
  103. -5 身份证号码地区码非法
  104. 身份证号码通过校验
  105. */
  106. --[长度校验]--
  107. if p_idcard is null then
  108. return -1;
  109. end if ;
  110. select lengthb(p_idcard) into v_length from dual;
  111. if v_length not in (15,18) then
  112. return -1;
  113. end if;
  114.  
  115. --[区位码校验]--
  116. if instrb(v_areacode, substr(p_idcard, 1, 2)||',') = 0 then
  117. return -5;
  118. end if;
  119.  
  120. --[格式化校验]--
  121. if v_length = 15 then
  122. v_isNumber := isNumber (p_idcard);
  123. if not (v_isNumber) then
  124. return -3;
  125. end if;
  126. elsif v_length = 18 then
  127. v_isNumber := isNumber (p_idcard);
  128. v_isNumber_17 := isNumber (substr(p_idcard,1,17));
  129. if not ((v_isNumber) or (v_isNumber_17 and upper(substr(p_idcard,18,1)) = 'X')) then
  130. return -3;
  131. end if;
  132. end if;
  133.  
  134. --[出生日期校验]--
  135. if v_length = 15 then
  136. select '19'||substr(p_idcard,7,6) into v_date from dual;
  137. elsif v_length = 18 then
  138. select substr(p_idcard,7,8) into v_date from dual;
  139. end if;
  140. v_isDate := isDate (v_date);
  141. if not (v_isDate) then
  142. return -2;
  143. end if;
  144.  
  145. --[校验码校验]--
  146. if v_length = 18 then
  147. v_sum :=
  148. ( TO_NUMBER (SUBSTRB (p_idcard, 1, 1))
  149. + TO_NUMBER (SUBSTRB (p_idcard, 11, 1))
  150. )
  151. * 7
  152. + ( TO_NUMBER (SUBSTRB (p_idcard, 2, 1))
  153. + TO_NUMBER (SUBSTRB (p_idcard, 12, 1))
  154. )
  155. * 9
  156. + ( TO_NUMBER (SUBSTRB (p_idcard, 3, 1))
  157. + TO_NUMBER (SUBSTRB (p_idcard, 13, 1))
  158. )
  159. * 10
  160. + ( TO_NUMBER (SUBSTRB (p_idcard, 4, 1))
  161. + TO_NUMBER (SUBSTRB (p_idcard, 14, 1))
  162. )
  163. * 5
  164. + ( TO_NUMBER (SUBSTRB (p_idcard, 5, 1))
  165. + TO_NUMBER (SUBSTRB (p_idcard, 15, 1))
  166. )
  167. * 8
  168. + ( TO_NUMBER (SUBSTRB (p_idcard, 6, 1))
  169. + TO_NUMBER (SUBSTRB (p_idcard, 16, 1))
  170. )
  171. * 4
  172. + ( TO_NUMBER (SUBSTRB (p_idcard, 7, 1))
  173. + TO_NUMBER (SUBSTRB (p_idcard, 17, 1))
  174. )
  175. * 2
  176. + TO_NUMBER (SUBSTRB (p_idcard, 8, 1)) * 1
  177. + TO_NUMBER (SUBSTRB (p_idcard, 9, 1)) * 6
  178. + TO_NUMBER (SUBSTRB (p_idcard, 10, 1)) * 3;
  179. v_mod := MOD (v_sum, 11);
  180. v_checkbit := SUBSTRB (v_checkcode, v_mod + 1, 1);
  181.  
  182. if v_checkbit = upper(substrb(p_idcard,18,1)) then
  183. return 1;
  184. else
  185. return -4;
  186. end if;
  187. else
  188. return 1;
  189. end if;
  190. End Func_checkIdcard;
  191. /
  192. Show Err;

总结

以上所述是小编给大家介绍的oracle 身份证校验函数,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

分享到:

相关信息

  • sql in查询元素超过1000条的解决方案

    1、方案一:核心思路是,将集合拆分,使用or 连接。 2、方案二:用子查询(临时表)+关联查询...

    2023-03-06

  • Navicat设置Oracle数据库主键自增的方法步骤

    天工作的时候,用到了oracle数据库建表,发现navicat中对于oracle的支持没有那个主键自增的按钮,下面这篇文章主要给大家介绍了关于Navicat设置Oracle数据库主键自增的方法步骤,需要的朋友可以参考下...

    2023-03-06

系统教程栏目

栏目热门教程

人气教程排行

站长推荐

热门系统下载