2013-04-14 1 views
0

Нам нужно скремблировать некоторые значения полей в некоторой таблице, но между некоторыми полями существует логическая связь.Обмен значения столбцов в одном обновлении (Oracle)

Например, если таблица: таблица т (имя varchar2 (30), по электронной почте varchar2 (60)), значения электронной почты должна начинаться с полного значения имени:

Name  Email 
----  ---- 
Smith  [email protected] 

Так после схватки, он может быть

Name  Email 
----  ---- 
xubal  [email protected] 

Мы используем функцию dbms_random.string, поэтому для каждого называют его вернуть определенное значение.

Возможно ли выполнить один уникальный запуск для обновления и сохранить логическую связь между полями? (Я не могу использовать триггеры db)

В следующих двух вариантах, которые я пытался, Oracle возвращает старое значение поля имени, а не новое значение.

update t 
set name=dbms_random.string('l',length(name)), 
    email=name || dbms_random.string('l',2) || '@any.com'; 

update t t1 
set name=dbms_random.string('l',length(name)), 
    email=(select t1.name || dbms_random.string('l',2) || '@any.com' 
      from t t2 
      where t2.rowid = t1.rowid) 

ответ

0

Вы можете создать пакет и использовать переменную в пакете.
Что-то вроде этого:

create package pck as 

v t.name%TYPE; 
function rnd_next(in_name t.name%TYPE) return t.name%TYPE; 
function rnd_cur return t.name%TYPE; 
end; 
/

create package body pck as 

function rnd_next(in_name t.name%TYPE) return t.name%TYPE is 

begin 
v := dbms_random.string('l',length(in_name)); 
return v; 
end; 

function rnd_cur return t.name%TYPE is 

begin 
return v; 
end; 
end; 
/

Затем вы можете обновить так:

update t 
set name = pck.rnd_next(name), 
email = pck.rnd_cur || '@aaa.com'; 

Here is a sqlfiddle demo

2

С MERGE вы можете сделать это с помощью запроса, а не процедуры.

Получить список таблицы t идентификаторов строк (с использованием Oracle ROWID псевдостолбец) и случайные имена, а затем сопоставить их обратно к столу t и использовать их, чтобы обновить как имя и электронную почту. Запрос (который я протестировал) выглядит следующим образом:

MERGE INTO t 
USING (
    SELECT ROWID AS ID, DBMS_Random.String('l', LENGTH(name)) AS RandName 
    FROM t) newNames 
ON (t.ROWID = newNames.ID) 
WHEN MATCHED THEN 
    UPDATE SET 
    name = newNames.RandName, 
    email = newNames.RandName || SUBSTR(email, INSTR(email, '@')) 
+0

+1 Отличная идея для проживания в sql без plsql! –

Смежные вопросы