0

I'm trying to set a 4-digit password between 1234 and 9999 for those rows that don't already have a password.

My first attempt uses the following code.

begin tran

DECLARE @Lower   int
DECLARE @Upper   int
SET @Lower = 1234 -- Lowest password value
SET @Upper = 9999 -- Highest password value

update DestinationComparisons
set Password = ROUND(((@Upper - @Lower - 1) * RAND() + @Lower), 0)
where Password = '' or Password is null

commit tran
go

However, this seems to give me the same 4 digits for every row that is updated. Obviously, I'd like a different password for each row.

Can someone help me see what I'm missing?

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
  • 2
    rand() is evaluated only ONCE per query, e.g. `select rand(), somefield from sometable` will always return the same rand value for each row. You'd have to do something like `select rand(id + time())` or whatever to force a new seed for each row. – Marc B Apr 02 '13 at 21:53
  • Is there no way to do what I'm trying to do? – Jonathan Wood Apr 02 '13 at 21:54
  • I have a suggestion if you are able to accept letters and numbers. – Jack Pettinger Apr 02 '13 at 21:55

2 Answers2

2

Here is one possibility:

with toupdate as (
      select dc.*,
             (ROW_NUMBER() over (order by newid()) / cast(COUNT(*) over () as float)) as randnum
      from DestinationComparisons dc
     )
update toupdate
    set Password = ROUND(((@Upper - @Lower - 1) * randum + @Lower), 0)
    where Password = '' or Password is null

It uses newid() to generate a random row number, then divides that by teh count to get a value between 0 and 1. This can then be used for the password calculation.

Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
2
begin tran
update DestinationComparisons
set Password = cast(left(cast(ABS(checksum(newid())) as varchar),4) as int)
where Password = '' or Password is null
commit tran
ljh
  • 2,546
  • 1
  • 14
  • 20