I have the following code:
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;
The purpose of this routine, is to mask names in a database as part of the preparation to create a development database from Production.
We want to mask the names, but we want them to be repeatable so that our result is something like: (input on the left; output on the right)
JOHN JONES -> STEEL POTATO
SAM JONES -> LARGE POTATO
MARY JONES -> WHITE POTATO
SUE SMITH -> LARGE CARROT
FRED JONES -> RED POTATO
JOHN SMITH -> GREEN CARROT
You probably get the idea: family name is changed to a random value, but repeats when it is again encountered. Given name is simply random. It is the family name that’s a concern here.
Arrays and other non-permanent solutions won’t work well for us, because this will actually be executed as a large series of UPDATE statements all executed within the same session. GTT seemed a perfect fit for this type of thing.
Ultimately, we’ll want to execute an Update similar to:
UPDATE MY_TABLE
SET ORIG_NAME = repeatable_rand_text('last', ORIG_NAME)
But in an effort to “prove the results of this routine, we execute the following SQL:
SELECT ORIG_NAME, repeatable_rand_text('last',ORIG_NAME)
FROM MY_TABLE
Now, obviously the INSERT in that function will execute as a result of the SELECT, and that’s a no-no. (And without being able to do that, we’re loathe to try the UPDATE that naturally follows. For all we know, it may fail with a similar message.) The question is, is there a reasonable way around this scenario?
I finally used an autonomous block. Those are rarely a good idea, but in this case I think it’s just the ticket. here’s how it looks: