if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sp_CreateNewPassword]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[sp_CreateNewPassword]
GO

Create Proc sp_CreateNewPassword
 @Money varchar(10),  --定义卡密的面额,做为前缀,如100元,输入100
 @Lenght int,         --定义卡密的长度,如20个长度
 @Qty int,             --定义生成卡密的数量,如100张,
 @CarNOPrefix varchar(20) = '',     --定义卡号前缀,如ABCDE
 @StartNO varchar(10) = ''                   --定义卡号开始号码,如001,那么生成的卡号为ABCD001开始
as
begin

-- Declare @Money varchar(10),
--  @Lenght int,
--  @Qty int
--
-- select @Money = '500', @Lenght = 50, @Qty = 10

Declare @tblReturn table(CardNO varchar(200), Password varchar(200))

Declare @Temp varchar(200),
 @i int,
 @j int,     --临时表卡密的数量
 @CardNO varchar(200)    --卡号

--避免出错处理, 避免出现这样的情况,@Qty = 1000, @StartNO = ‘001’
set @i = Len((Cast(@StartNo as Int) + @Qty))
set @j = Len(@StartNo)
if  @i > @j
begin
 while @i > @j
 begin
  set @StartNo = '0' + @StartNo
  set @j = @j + 1     
 End
End

set @Temp = ''
set @j = 0
set @CardNO = ''

while Len(@Temp) < @Lenght   --判断字符串@Temp 的长度是否大于 @Lenght 卡密的长度
begin
 --自动生成一个随机数
 set @i = Cast(FLOOR(Rand() * 74) as Int) + 48   
 
 --判断这个随数数的数字范围,0~9, A~Z, a~z 才是有效范围,其他不进行操作
 if (@i >= 48 and @i <= 57) or (@i > 65 and @i < 90) or (@i >= 97 and @i <= 122)
 begin
  set @Temp = @Temp + Char(@i)

 End

 --如果 @Temp 的长度已经等于 @Lenght的长度,并且临时表的卡密数量 @j 小于 需要生成的数量 @Qty
 if (Len(@Temp) = @Lenght) and (@Qty > @j)
 begin
  set @Temp = @Money + @Temp 
  
  if Not Exists(select * from @tblReturn where Password = @Temp)
  begin
   --生成卡号
   if @CarNOPrefix <> ''
   begin
    --如果卡号开始号码没有输入,则弹出提示
    if @StartNo = ''
    begin
     Raiserror('请输入卡号开始号码再运行', 16, 1)
     Return
    End
 
   
    --如果临时表没有记录,则卡号直接相加即可
    if not Exists(select * from @tblReturn)  
    begin
     set @CardNO = @CarNOPrefix + @StartNO
    End
    else
    begin
     --如果临时表存在记录,则进行获取卡号操作  
     Declare @StartNoLen int
     set @StartNoLen = Len((Cast(@StartNo as Int) + @Qty))
     
     Select @i= Max(Right(CardNO, @StartNoLen)) + 1  From @tblReturn
 
     Declare @ID varchar(200)
     set @ID = Cast(@i as Varchar(200))
     
     while Len(@ID) < @StartNoLen
     begin
      set @ID = '0' + @ID
     End
 
     set @CardNO = @CarNOPrefix + @ID
    End
   End

   Insert Into @tblReturn(CardNO, Password)
   select @CardNO, @Temp
 
   set @Temp = ''
 
   set @j = @j + 1
  End
 End
End

--如果没有卡号,则直接查询密码
if @CarNOPrefix <> ''
 select CardNO, Upper(Password) as Password from @tblReturn
else
 select Upper(Password) From @tblReturn

End
Go

exec sp_CreateNewPassword '100', '20', 100, 'abcd', '501'
Go

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sp_CreateNewPassword]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[sp_CreateNewPassword]
GO