2010-05-14 73 views
4

在Oracle 10g中,有没有办法在PL/SQL中执行以下操作?如何修剪所有类型为string的表中所有行的所有列?

for each table in database 
    for each row in table 
    for each column in row 
     if column is of type 'varchar2' 
     column = trim(column) 

谢谢!

+2

看一看在USER_TABLES http://download.oracle.com/docs/cd/B28359_01/server.111/b28320/statviews_5443.htm 和USER_TAB_COLUMNS http://download.oracle的.com /文档/ CD/B28359_01/server.111/b28320/statviews_5429.htm#REFRN26277 系统表。我认为你应该能够制定一个动态的查询使用这些来做你想做的。 – 2010-05-14 17:04:06

+0

有用的问题! ;-) – UltraCommit 2010-05-14 17:18:36

+0

@ pm_2非常感谢您的建议,看起来像下面的家伙做的。 – daveslab 2010-05-14 17:45:31

回答

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; 
+2

USER_TAB_COLUMNS包含在表和视图中找到的列。要做到这一点,你需要过滤掉视图。 – Allan 2010-05-14 17:14:42

+1

如果您的数据库包含VARCHAR2类型的列很多,很多表,DBMS_OUTPUT.PUT_LINE的缓冲区可能不足以容纳所有的UPDATE语句,所以它可以方便的更新语句存放在Oracle表,使用INSERT语句而不是DBMS_OUTPUT.PUT_LINE语句。 – UltraCommit 2010-05-14 17:20:22

+1

同意,鸡,但是然后再次为我的表,这只是少数,我只是增加了输出缓冲区,并且它工作正常。 – daveslab 2010-05-14 17:55:10

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字段总是填充到其最大长度。

相关问题