4

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)

ありがとう!

4

2 に答える 2

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;
于 2010-05-14T17:09:05.487 に答える
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 フィールドは常に最大長まで埋められるため、うまくいきません。

于 2010-05-14T17:11:39.973 に答える