我们需要在某些表上加扰某些字段值,但某些字段之间存在逻辑链接。
例如,如果表是:table t(name varchar2(30),email varchar2(60)), 电子邮件值必须以名称的完整值开头:
Name Email
---- ----
Smith Smitha@any.com
所以在争夺之后,它可以是
Name Email
---- ----
xubal xubaly@any.com
我们使用dbms_random.string函数,因此对于每次调用,它都会返回一个不同的值。
可以在一次独特的运行中进行更新并保持字段之间的逻辑链接吗? (我不能使用db触发器)
在我尝试的下两个选项中,Oracle返回name字段的旧值,而不是新值。
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 :(得分: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, '@'))
答案 1 :(得分: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';