So you want to dynamically update tables containing varchar2, clob, etc.?
If so, you can query user_tab_cols to find these tables and columns. And build up your SQL statement using listagg. For example:
create table t (
x varchar2(10), y int, z varchar2(10)
);
select table_name,
'update ' || table_name || ' set ' ||
listagg(column_name, ' = ''NEW VALS'',') within group (order by column_name) ||
' = ''NEW VALS'' returning rowid into :rids' update_stmt
from user_tab_cols
where data_type in ('VARCHAR2', 'XMLTYPE', 'CLOB')
and table_name = 'T'
group by table_name ;
TABLE_NAME UPDATE_STMT
T update T set X = 'NEW VALS',Z = 'NEW VALS' returning rowid into :rids
The returning clause enables you to capture which rows your update changed. So when you run the update, you bulk collect these into an array. You can then save these into another table (or whatever):
insert into t values ('this', 0, 'that');
insert into t values ('this', 1, 'that');
insert into t values ('this', 2, 'that');
insert into t values ('this', 3, 'that');
insert into t values ('this', 4, 'that');
commit;
declare
type rowids_tab is table of rowid index by pls_integer;
rowids rowids_tab;
begin
for updates in (
select table_name,
'update ' || table_name || ' set ' ||
listagg(column_name, ' = ''NEW VALS'',') within group (order by column_name) ||
' = ''NEW VALS'' returning rowid into :rids' update_stmt
from user_tab_cols
where data_type in ('VARCHAR2', 'XMLTYPE', 'CLOB')
and table_name = 'T'
group by table_name
) loop
execute immediate updates.update_stmt
returning bulk collect into rowids;
for i in 1 .. rowids.count loop
dbms_output.put_line(updates.table_name || ' ' || rowids(i));
end loop;
end loop;
end;
/
T AAAcyCAABAAARn/AAA
T AAAcyCAABAAARn/AAB
T AAAcyCAABAAARn/AAC
T AAAcyCAABAAARn/AAD
T AAAcyCAABAAARn/AAE
select * from t;
X Y Z
NEW VALS 0 NEW VALS
NEW VALS 1 NEW VALS
NEW VALS 2 NEW VALS
NEW VALS 3 NEW VALS
NEW VALS 4 NEW VALS