有没有办法根据每个单独字段(DB2 或其他)的内容逐行修改 table 中的字段?

Is there a way to modify a field in a table line by line based upon the contents of each individual field (DB2 or other)?

我有一个 DB2 table,它有一个包含特定值(社会安全号码)的字段。我需要根据字段的内容修改每一行的字段值。我获取原始字段的值并基于它创建一个新值。基本上我使用原始值作为种子来创建一个新值,所以我需要知道每个值并根据它更新字段......我很抱歉这么含糊,我还在努力明白这一切。

这 SQL 将所有值更改为一个错误的值 更新 Table 设置 SSN = '123-45-6789'

我需要:

  1. 获取字段的值
  2. 使用当前值作为种子,使用简单的公式对其进行屏蔽

619-46-0988--->427-95-1143
424-09-8912--->699-01-4628
619-46-0988--->427-95-1143

请注意 619-46-0988 会随着原始值的变化而不断变化

非常感谢,

芭芭拉

我的意思是,您可以使用 SSN 作为 System.Random 的种子,这将始终 return 谓词 table 下一个值。只要 RNG 函数不改变它就是一致的。

你可以这样做:

PS C:\> $rng = [System.Random]::new([int]'619-46-0988'.Replace('-',''))
PS C:\> $rng.Next(1e9).ToString('000-00-0000')
010-05-3964

或者这样:

PS C:\> (Get-Random -Maximum 1e9 -SetSeed ([int]'619-46-0988'.Replace('-',''))).ToString('000-00-0000')
660-94-7295

你应该这样做吗? 绝对不是。 生成整个使用过的密钥 space 并创建彩虹 table 并不安全,而且很简单。此外,它不会生成适合 the SSN allowed ranges 的值(例如不以 000 开头),因此它们可能不合适,具体取决于您的应用程序。

A more 正确的方法是将 SSN 视为密码,可能使用 bcrypt/scrypt 或 PBKDF2 或其他一些加密哈希函数,然后使用哈希更直接地生成“成为”新 SSN 的 9 位数字(例如,消耗最低有效字节以创建 9 位整数)。

但是,在我能想到的任何情况下,“我需要混淆 SSN”的问题我首选的解决方案是“向 table 添加一个新列或创建一个新的 table ,然后创建与 person table 密钥相关联的代理密钥,然后将 SSN 清除为空值,并在需要时使用代理”。哎呀,你的代理键可能只是 (Get-Random -Maximum 1e9).ToString('000-00-0000') 的输出,据我所知(但你自己研究),它使用 System.Security.Cryptography.RandomNumberGenerator。即使那样,我也不会热衷于将代理键保留很长时间。

可以使用UPDATE语句。您尚未指定如何计算新值,但引用现有值是一种常见的情况:每个 INDIVIDUAL 员工的新薪水应基于当前现有薪水。

计算新值的表达式可以是任何expression。因此,您可以在另一个 table 中查找它或在函数中计算它。

UPDATE myTable SET column = computedValue(column) WHERE howToIdentifyThoseToChange

可能是最简单的掩码函数示例。
具有恒定第二参数的唯一 SSN 集的唯一且一致的结果。

CREATE OR REPLACE FUNCTION SSN_MASK(P_SSN VARCHAR(11), P_MASK VARCHAR(9)) 
RETURNS VARCHAR(11)
CONTAINS SQL
DETERMINISTIC 
NO EXTERNAL ACTION
RETURN
CASE
   WHEN 
         REGEXP_LIKE(P_SSN,  '^[\d]{3}-[\d]{2}-[\d]{4}$')
     AND REGEXP_LIKE(P_MASK, '^[\d]{9}$')
   THEN
        MOD(INT(SUBSTR(P_SSN,  1, 1)) + INT(SUBSTR(P_MASK, 1, 1)), 10)
     || MOD(INT(SUBSTR(P_SSN,  2, 1)) + INT(SUBSTR(P_MASK, 2, 1)), 10)
     || MOD(INT(SUBSTR(P_SSN,  3, 1)) + INT(SUBSTR(P_MASK, 3, 1)), 10)
     || '-'
     || MOD(INT(SUBSTR(P_SSN,  5, 1)) + INT(SUBSTR(P_MASK, 4, 1)), 10)
     || MOD(INT(SUBSTR(P_SSN,  6, 1)) + INT(SUBSTR(P_MASK, 5, 1)), 10)
     || '-'
     || MOD(INT(SUBSTR(P_SSN,  8, 1)) + INT(SUBSTR(P_MASK, 6, 1)), 10)
     || MOD(INT(SUBSTR(P_SSN,  9, 1)) + INT(SUBSTR(P_MASK, 7, 1)), 10)
     || MOD(INT(SUBSTR(P_SSN, 10, 1)) + INT(SUBSTR(P_MASK, 8, 1)), 10)
     || MOD(INT(SUBSTR(P_SSN, 11, 1)) + INT(SUBSTR(P_MASK, 9, 1)), 10)
END
;
    
SELECT V, SSN_MASK(V, '123456789') V_MASKED 
FROM 
(
VALUES 
  '619-46-0988'
, '424-09-8912'
, '619-46-0988'
, 'ABC'
) T(V);
    
The result is: 
        
|V          |V_MASKED   |
|-----------|-----------|
|619-46-0988|732-81-6667|
|424-09-8912|547-44-4691|
|619-46-0988|732-81-6667|
|ABC        |NULL       |