Как обрезать все столбцы во всех строках во всех таблицах типа строка? - PullRequest
4 голосов
/ 14 мая 2010

В 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)

Спасибо! * * 1004

Ответы [ 2 ]

6 голосов
/ 14 мая 2010

Конечно, выполнение масштабных динамических обновлений потенциально опасно и отнимает много времени. Но вот как вы можете генерировать команды, которые вы хотите. Это для одной схемы, и она будет просто создавать команды и выводить их. Вы можете скопировать их в скрипт и просмотреть их перед запуском. Или вы можете изменить 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;
3 голосов
/ 14 мая 2010

Предположительно, вы хотите сделать это для каждого столбца в схеме, а не в базе данных. Попытка сделать это со словарными таблицами была бы плохой идеей ...

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 всегда дополняются до максимальной длины.

...