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
;
|