Хорошо, снимок с бедра, успокойся в моем синтаксисе: -)
Подойдет ли такой подход:
DECLARE
v_sql1 VARCHAR2(1000);
v_sql2 VARCHAR2(2000);
TYPE T_Rules IS RECORD (srch VARCHAR2(100), repl(VARCHAR2(100));
TYPE T_RuleTab IS TABLE OF T_Rules INDEX BY BINARY_INTEGER;
v_rules T_RuleTab;
FUNCTION get_subquery RETURN VARCHAR2 IS
BEGIN
RETURN '(SELECT id FROM category WHERE code = ''ABC'')';
END;
BEGIN
v_sql1 := 'UPDATE customer SET status = REPLACE('':1'','':2'') WHERE status LIKE ''%:1%'' AND category_id IN ';
v_rules(1).srch := ('X_Y'); v_rules(1).repl := 'yx';
v_rules(2).srch := ('X_Z'); v_rules(2).repl := 'xz';
FOR i IN 1..v_rules.COUNT LOOP
v_sql2 := v_sql1||get_subquery();
EXECUTE IMMEDIATE v_sql2 USING v_rules(i).srch, v_rules(i).repl;
END LOOP;
END;
Вы можете заменить таблицу PL / SQL реальной таблицей и навести на нее курсор, но это отвечает вашему второму требованию.
Очевидно, что в get_subquery, вашем первом требовании, осталось немного работы; -)
EDIT
Dang! забыл упомянуть, что вы должны быть осторожны с этой строкой замены в предложении WHERE - подчеркивания - это подстановочный знак, соответствующий одиночному символу в Oracle ...