我正在尝试为一群新员工生成非连续的唯一PIN码。 这是它应该如何工作: 1.游标应该从表B中获取所有新员工 2.为每位新员工生成新的独特引脚 3.检查表A中是否已存在新生成的PIN 4.如果是,请重复步骤2,直到我们为所有新员工获取唯一的PIN 5.将新员工编号和PIN插入表A
在表A上,字段为PIN,Employee_Number,日期
我尝试使用游标逐个插入每个新的emp和他的PIN,以便检查每个插入的唯一性:
这只循环一次并停止,有人能告诉我我缺少的东西
DECLARE
@EmpNo VARCHAR(50),
@Pin INT,
@today DATETIME,
@Upper INT,
@Lower INT,
SET @Lower = 100000 ---- The lowest random number allowed
SET @Upper = 999999 ---- The highest random number allowed
DECLARE cur CURSOR FOR
SELECT
Employee_Number,
(ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0))as PIN,
GETDATE()
FROM TableB
WHERE Employee_Number NOT IN (SELECT Employee_Number FROM TableA)
OPEN cur
FETCH NEXT FROM cur INTO @EmpNo, @Pin, @Today
WHILE @@FETCH_STATUS=0
BEGIN
INSERT INTO TableA (PIN, Employee_Number, Date)
SELECT @Pin, @EmpNo, @Today
FETCH NEXT FROM cur INTO @Pin, @EmpNo, @Today
END
CLOSE cur
DEALLOCATE cur
答案 0 :(得分:0)
INSERT INTO TableA (PIN, Employee_Number, Date)
SELECT pin = @Lower
+ ( abs(convert(bigint,convert(varbinary(20),newid())))
% (@Upper - @Lower + 1)
),
Employee_Number,
GETDATE()
FROM TableB
WHERE Employee_Number NOT IN (SELECT Employee_Number FROM TableA)
编辑:
处理独特的引脚,不使用光标的解决方案是保留所有可能引脚的表。
create table pin
(
pin int primary key,
is_used bit default 0
)
使用recursive cte
生成引脚; with num as
(
-- anchor member
select pin = @Lower
union all
-- recursive member
select pin = pin + 1
from num
where pin < @Upper
)
insert into pin (pin)
select pin
from num
然后当您需要将销分配给员工时
; with emp as
(
select Employee_Number, rn = row_number() over (order by Employee_Number)
from TableA a
where not exists
(
select *
from TableB b
where b.Employee_Number = a.Employee_Number
)
),
pin as
(
-- get unused pin, order it randomly using newid()
select pin, rn = row_number() over (order by newid())
from pin
where is_used = 0
)
insert into #TableB (Employee_Number, pin)
select e.Employee_Number, p.pin
from emp e
inner join pin p on e.rn = p.rn
之后更新了针脚表中的is_used列
update p
set is_used = 1
from TableB b
inner join #pin p on b.pin = p.pin
where p.is_used = 0
答案 1 :(得分:0)
另一种方法可能如下。
注意@EmpTable是一个演示版EmpTable(为您的环境删除@)
1)cte0生成一个10行的基本计数表
2)cteR将cte0扩展为1,000行并添加随机字符串(NewID())
3)cteI将cteR转换为INT(不超过6位)
4)更新适用于所有NULL PINS
Declare @EmpTable table (Employee_Number int,PIN int)
Insert Into @EmpTable values
(1,100288),(2,651701),(3,823700),
(4,NULL),(5,NULL)
Declare @Lower int=100000,@Upper int = 999999
;with cte0(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N))
, cteR(R) As (Select Distinct R=cast(NewID() as varchar(50)) From cte0 N1, cte0 N2, cte0 N3, cte0 N4)
, cteI(R,N) As (Select Distinct R,cast(Left(cast(abs(cast(Hashbytes('MD5',R) as int)) as varchar(25)),6) as int) From cteR R)
Update @EmpTable Set PIN = B.N
From @EmpTable A
Join (
Select RowNr=(Select min(Employee_Number)-1 From @EmpTable Where PIN is NULL)+Row_Number() over (Order By R)
,N
From cteI
Where N Between @Lower and @Upper
and N not in (Select Distinct PIN From @EmpTable Where PIN is not NULL)
) B on A.Employee_Number=B.RowNr and PIN is null
Select * from @EmpTable
更新了EmpTable
Employee_Number PIN
1 100288 -- Same as Original
2 651701 -- Same as Original
3 823700 -- Same as Original
4 118844 -- New Random PIN
5 677855 -- New Random PIN