私は次のコードを持っています:
CREATE OR REPLACE FUNCTION repeatable_rand_text(ftype IN VARCHAR2
, in_val IN VARCHAR2)
RETURN VARCHAR2 IS
workval VARCHAR2(64);
insert_needed BOOLEAN := FALSE;
BEGIN
BEGIN
SELECT new_name
INTO workval
FROM ps_dt_mixnames_preserve
WHERE name_type = ftype AND old_name = in_val;
EXCEPTION
WHEN NO_DATA_FOUND THEN
workval := rand_text(ftype);
insert_needed := TRUE;
END;
IF insert_needed THEN
INSERT INTO ps_dt_mixnames_preserve(name_type, old_name, new_name)
VALUES (ftype, in_val, workval);
END IF;
RETURN workval;
END repeatable_rand_text;
このルーチンの目的は、本番環境から開発データベースを作成する準備の一環として、データベース内の名前をマスクすることです。
名前をマスクしたいのですが、結果が次のようになるように、名前を繰り返し可能にする必要があります:(左側に入力;右側に出力)
JOHN JONES -> STEEL POTATO
SAM JONES -> LARGE POTATO
MARY JONES -> WHITE POTATO
SUE SMITH -> LARGE CARROT
FRED JONES -> RED POTATO
JOHN SMITH -> GREEN CARROT
おそらくあなたは考えを理解するでしょう:家族の名前はランダムな値に変更されますが、それが再び遭遇すると繰り返されます。名は単にランダムです。ここで気になるのは家系の名前です。
配列やその他の非永続的なソリューションは、実際にはすべて同じセッション内で実行される一連の大規模なUPDATEステートメントとして実行されるため、うまく機能しません。GTTはこの種のものにぴったりのようでした。
最終的には、次のような更新を実行する必要があります。
UPDATE MY_TABLE
SET ORIG_NAME = repeatable_rand_text('last', ORIG_NAME)
ただし、「このルーチンの結果を証明するために、次のSQLを実行します。
SELECT ORIG_NAME, repeatable_rand_text('last',ORIG_NAME)
FROM MY_TABLE
さて、明らかにその関数のINSERTはSELECTの結果として実行され、それはノーノーです。(そして、それができなければ、自然に続くUPDATEを試すのは嫌です。私たちが知っている限り、同様のメッセージで失敗する可能性があります。)問題は、このシナリオを回避する合理的な方法があるかどうかです。