在Oracle 10g中,有没有办法在PL / SQL中执行以下操作?
for each table in database
for each row in table
for each column in row
if column is of type 'varchar2'
column = trim(column)
谢谢!
答案 0 :(得分:6)
当然,进行大规模动态更新可能会带来危险和耗时。但是这里是你如何生成你想要的命令。这是针对单个模式的,只是构建命令并输出它们。您可以将它们复制到脚本中并在运行之前查看它们。或者,您可以将dbms_output.put_line( ... )
更改为EXECUTE IMMEDIATE ...
,以使此脚本在生成时执行所有语句。
SET SERVEROUTPUT ON
BEGIN
FOR c IN
(SELECT t.table_name, c.column_name
FROM user_tables t, user_tab_columns c
WHERE c.table_name = t.table_name
AND data_type='VARCHAR2')
LOOP
dbms_output.put_line(
'UPDATE '||c.table_name||
' SET '||c.column_name||' = TRIM('||c.column_name||') WHERE '||
c.column_name||' <> TRIM('||c.column_name||') OR ('||
c.column_name||' IS NOT NULL AND TRIM('||c.column_name||') IS NULL)'
);
END LOOP;
END;
答案 1 :(得分:3)
据推测,您希望对模式中的每个列执行此操作,而不是在数据库中执行此操作。尝试对字典表执行此操作将是一个坏主意......
declare
v_schema varchar2(30) := 'YOUR_SCHEMA_NAME';
cursor cur_tables (p_schema_name varchar2) is
select owner, table_name, column_name
from all_tables at,
inner join all_tab_columns atc
on at.owner = atc.owner
and at.table_name = atc.table_name
where atc.data_type = 'VARCHAR2'
and at.owner = p_schema;
begin
for r_table in cur_tables loop
execute immediate 'update ' || r.owner || '.' || r.table_name
|| ' set ' || r.column_name || ' = trim(' || r.column_name ||');';
end loop;
end;
这仅适用于首先是VARCHAR2的字段。如果您的数据库包含CHAR字段,那么您运气不佳,因为CHAR字段始终填充到其最大长度。