create procedure p_sfzto18 @sfz_input varchar(18),@sfz_output varchar(18) output as declare @sfz_doing varchar(18), @count integer,@valid integer
select @sfz_doing = rtrim(ltrim(@sfz_input)) //将输入身份证赋给中间处理变量 if (char_length(@sfz_doing) < > 15) and (char_length(@sfz_doing) < > 17) and (char_length(@sfz_doing) < > 18) //身份证长度合法性校验 begin select @sfz_output = @sfz_input return end select @sfz_doing = case char_length(@sfz_doing) //转化为十七位身份证(没有校验位)when 15 then substring(@sfz_doing,1,6)+'19'+substring(@sfz_doing,7,9) when 18 then substring ( @sfz_doing ,1,17) else @sfz_doing end select @count = 17,@valid = 0 while @count > 0 begin //非数字字符的合法性校验 if ascii(substring(@sfz_doing,@count,1))< 48 or ascii(substring(@sfz_doing,@count,1)) >57 begin select @sfz_output = @sfz_input return end select @valid = @valid + convert(integer, substring(@sfz_doing,@count,1)) * (case (19 - @count) when 1 then 1 when 2 then 2 when 3 then 4 when 4 then 8 when 5 then 5 when 6 then 10 when 7 then 9 when 8 then 7 when 9 then 3 when 10 then 6 when 11 then 1 when 12 then 2 when 13 then 4 when 14 then 8 when 15 then 5 when 16 then 10 when 17 then 9 when 18 then 7 end) select @count = @count - 1 end
select @sfz_output = @sfz_doing + case @valid%11 when 0 then '1' when 1 then '0' when 2 then 'X' when 3 then '9' when 4 then '8' when 5 then '7' when 6 then '6' when 7 then '5' when 8 then '4' when 9 then '3' when 10 then '2' end //对出生日期的合法性校验 if convert(integer, substring(@sfz_doing, 13, 2)) > 31 or convert(integer, substring(@sfz_doing, 11, 2)) > 12 begin select @sfz_output = @sfz_input return end else begin if substring(@sfz_doing,11,2) = '02' begin if convert(integer, substring(@sfz_doing,13,2)) > 29 begin select @sfz_output = @sfz_input return end if convert(integer,substring(@sfz_doing, 13, 2)) = 29 and not ( (convert(integer, substring(@sfz_doing, 7, 4)) % 4 = 0 And convert(integer,substring(@sfz_doing,7,4))%100 < > 0) Or (convert(integer,substring(@sfz_doing,7,4)) % 400 = 0) ) begin select @sfz_output = @sfz_input return end end if convert(integer,substring(@sfz_doing,13,2)) = 31 and substring(@sfz_doing,11,2) not in ('01','03','05','07','08','10','12') begin select @sfz_output = @sfz_input return end end ;
|