Есть ли способ изменять поле в таблице построчно на основе содержимого каждого отдельного поля (DB2 или другого)?

#sql #database #powershell #db2

#sql #База данных #powershell #db2

Вопрос:

У меня есть таблица DB2, в которой есть поле, содержащее определенное значение (номера СОЦИАЛЬНОГО СТРАХОВАНИЯ). Мне нужно изменить значение поля каждой строки в зависимости от содержимого поля. Я беру исходное значение поля и на его основе создаю новое значение. В основном я использую исходное значение в качестве начального для создания нового значения, поэтому мне нужно знать каждое значение и обновлять поле на его основе… Прошу прощения за то, что выражаюсь так расплывчато, я все еще пытаюсь понять все это.

Этот SQL изменил все значения на одно неверное значение Update Table set 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 изменяется последовательно, поскольку исходное значение было одинаковым

Большое спасибо,

Барбара

Комментарии:

1. Пожалуйста, отредактируйте вопрос и объясните, что и почему вы хотели бы это сделать. Могут быть лучшие варианты, такие как использование маски данных DB2, но это зависит от того, что вам действительно нужно.

2. Вы можете реализовать свой собственный алгоритм, который должен последовательно преобразовывать данные и сохранять уникальность. Это может быть какой-то отдельный алгоритм перетасовки для каждой цифры, например, добавление константы и возврат напоминания о делении на 10 или постоянное сопоставление цифр один к одному без повторения. Реализовать такую скалярную функцию SQL относительно легко.

3. Что update устанавливает значения в одно и то же значение? Я не вижу ни одного update .

Ответ №1:

Вероятно, самый простой пример функции маскировки.
Уникальный и согласованный результат для уникального набора SSN с постоянным 2-м параметром.

 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       |
  

Ответ №2:

Я имею в виду, вы могли бы использовать SSN в качестве начального для System.Случайное, и это всегда будет возвращать предсказуемое следующее значение. Пока функция 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
  

Следует ли вам делать это таким образом? Абсолютно нет. Это небезопасно, и тривиально генерировать все используемое пространство ключей и создавать таблицу rainbow. Кроме того, он не генерирует значения, которые соответствуют разрешенным диапазонам SSN (например, не начинающиеся с 000), поэтому они могут не подходить в зависимости от вашего приложения.

Более правильным способом сделать это было бы обработать SSN как пароль, возможно, с помощью чего-то вроде bcrypt / scrypt или PBKDF2 или какой-либо другой криптографической функции хэширования, а затем использовать хэш для более прямой генерации 9-значного числа, которое «становится» новым SSN (например, использовать наименее значимые байты для создания 9-значного целого числа).

Однако при любых обстоятельствах, которые я мог себе представить, проблема «Мне нужно запутать SSN», мое предпочтительное решение было бы «добавить новый столбец в таблицу или создать новую таблицу, затем создать суррогатные ключи, связанные с ключом таблицы person, а затем очистить SSN до нулей и использовать суррогаты, когда мне нужно это сделать». Черт возьми, ваши суррогатные ключи могут быть просто выводом, (Get-Random -Maximum 1e9).ToString('000-00-0000') который, насколько я знаю (но проведите собственное исследование), использует System.Security.Cryptography.RandomNumberGenerator . Даже тогда я бы не стремился хранить суррогатные ключи очень долго.

Ответ №3:

Вы можете использовать инструкцию UPDATE. Вы не указали, как вычисляется новое значение, но это обычный сценарий для ссылки на существующее значение: новая зарплата каждого ОТДЕЛЬНОГО сотрудника должна основываться на текущей существующей зарплате.

Выражение для вычисления нового значения может быть любым выражением. Таким образом, вы можете посмотреть его в другой таблице или вычислить в функции.

 UPDATE myTable SET column = computedValue(column) WHERE howToIdentifyThoseToChange