为了满足安全性要求,在向开发人员提供所述数据库之前,我需要找到一种用唯一的随机9位数替换SSN的方法。 SSN位于数据库表的列中。所述表中可能有数十万行。这个数字不需要连字符。我是SQL和编程的初学者。
我无法找到满足我特定需求的解决方案。似乎没什么。但如果你知道我错过了一个帖子,请告诉我。
感谢您的帮助!
答案 0 :(得分:4)
这是一种方式。
我假设您已经拥有真实数据的备份,因为此更新不可逆。
以下我假设您的表名为人,其中您的ssn列名为 SSN 。
UPDATE Person SET
SSN = CAST(LEFT(CAST(ABS(CAST(CAST(NEWID() as BINARY(10)) as int)) as varchar(max)) + '00000000',9) as int)
答案 1 :(得分:2)
如果它们不必是随机的,您可以用升序数值替换它们。如果做不到这一点,你必须生成一个随机数。您可能已经发现,RAND函数只会为每个查询语句生成一个值(选择,更新等);解决方法是newid()函数,它将为查询生成的每一行生成GUID(运行SELECT newid() from MyTable
以查看其工作原理)。将它包装在校验和()中以生成整数;模数乘以1,000,00,000得到一个SSN范围内的值(0到999,999,999);并且,假设您将其存储为char(9)前缀,并带有前导零。
下一个技巧是确保它对表中的所有值都是唯一的。这很棘手,我会通过设置一个带有值的临时表,填充它,然后将它们复制过来来实现。承租人现在......
DECLARE @DummySSN as table
(
PrimaryKey int not null
,NewSSN char(9) not null
)
-- Load initial values
INSERT @DummySSN
select
UserId
,right('000000000' + cast(abs(checksum(newid()))%1000000000 as varchar(9)), 9)
from Users
-- Check for dups
select NewSSN from @DummySSN group by NewSSN having count(*) > 1
-- Loop until values are unique
IF exists (SELECT 1 from @DummySSN group by NewSSN having count(*) > 1)
UPDATE @DummySSN
set NewSSN = right('000000000' + cast(abs(checksum(newid()))%1000000000 as varchar(9)), 9)
where NewSSN in (select NewSSN from @DummySSN group by NewSSN having count(*) > 1)
-- Check for dups
select NewSSN from @DummySSN group by NewSSN having count(*) > 1
这适用于我拥有的小桌子,它适用于大型桌子。我没有看到这变成一个无限循环,但即便如此,你可能想要在10次迭代后添加一个检查以退出循环,
答案 2 :(得分:0)
我在这里运行了几百万个测试,它似乎生成随机(URN)9位数字(没有前导零)。 我想不出更有效的方法来做到这一点。
SELECT CAST(FLOOR(RAND(CHECKSUM(NEWID())) * 900000000 ) + 100000000 AS BIGINT)
使用的测试;
;WITH Fn(N) AS
(
SELECT CAST(FLOOR(RAND(CHECKSUM(NEWID())) * 900000000 ) + 100000000 AS BIGINT)
UNION ALL
SELECT CAST(FLOOR(RAND(CHECKSUM(NEWID())) * 900000000 ) + 100000000 AS BIGINT)
FROM Fn
)
,Tester AS
(
SELECT TOP 5000000 *
FROM Fn
)
SELECT LEN(MIN(N))
,LEN(MAX(N))
,MIN(N)
,MAX(N)
FROM Tester
OPTION (MAXRECURSION 0)
答案 3 :(得分:0)
不是那么快,但最简单......我添加了一些点......
DECLARE @tr NVARCHAR(40)
SET @tr = CAST(ROUND((888*RAND()+111),0) AS CHAR(3)) + '.' +
CAST(ROUND((8888*RAND()+1111),0) AS CHAR(4)) + '.' + CAST(ROUND((8888*RAND()+1111),0) AS
CHAR(4)) + '.' + CAST(ROUND((88*RAND()+11),0) AS CHAR(2))
PRINT @tr
答案 4 :(得分:0)
如果要求对数据库进行模糊处理,那么这将为任何表中的每个不同SSN返回相同的唯一值,从而保留输出中的引用完整性,而无需进行查找和转换。
SELECT CAST(RAND(SSN)*999999999 AS INT)