2015-07-07 2 views
1

У меня есть поле (clientID), которое повторяется в большинстве моих таблиц (около 100 или около того), и я пытаюсь обновить его все сразу, используя oracle 11g. Мне удалось получить имя таблиц, но я не могу его использовать. Из кода ниже:Обновить все строки во всех таблицах в Oracle

BEGIN 
    FOR Name IN (SELECT TABLE_NAME FROM SYS.all_tables where TABLESPACE_NAME='MyTableSpace') LOOP 
     DBMS_OUTPUT.PUT_LINE(Name.TABLE_NAME); --I can't see any logs on DBMS Output for some reason 
     -- Update Name.TABLE_NAME set ClientID = 1 Where ClientID = 2; --This line does not work message "Table or view does not exist" 
    END LOOP; 
END; 

ответ

2

Вы можете попробовать использовать динамический SQL, используя EXECUTE IMMEDIATE.

Что-то вроде этого:

BEGIN 
    FOR Name IN (SELECT TABLE_NAME FROM SYS.all_tables where TABLESPACE_NAME='MyTableSpace') LOOP 
     DBMS_OUTPUT.PUT_LINE(Name.TABLE_NAME); --I can't see any logs on DBMS Output for some reason 
     EXECUTE IMMEDIATE 'Update ' || Name.TABLE_NAME || ' set ClientID = 1 Where ClientID = 2'; 
    END LOOP; 
END; 

Если вам необходимо установить значение, которые будут обновляться динамически, есть способы связывания параметров с динамическим SQL. Я просто не помню, как это сделать. Но если вам это нужно, просто спросите в комментариях, и я буду искать его.

EDIT

Я думаю, что если вы должны были связать значения, это будет выглядеть примерно так:

BEGIN 
    FOR Name IN (SELECT TABLE_NAME FROM SYS.all_tables where TABLESPACE_NAME='MyTableSpace') LOOP 
     DBMS_OUTPUT.PUT_LINE(Name.TABLE_NAME); --I can't see any logs on DBMS Output for some reason 
     EXECUTE IMMEDIATE 'Update ' || Name.TABLE_NAME || ' set ClientID = :1 Where ClientID = :2' 
          USING 1, 2; 
    END LOOP; 
END; 

... где вместо USING 1, 2, вы можете использовать переменные вместо жесткого кодирования постоянные значения.

Для получения дополнительной информации: EXECUTE IMMEDIATE.

EDIT 2

Если необходимо пропустить таблицы, которые не имеют столбец в вопросе, здесь скорректированный запрос, который должен сделать эту работу:

BEGIN 
    FOR Name IN (
    SELECT t.TABLE_NAME 
    FROM all_tables t 
    where t.TABLESPACE_NAME='MyTableSpace' 
    and exists (
     select null 
     from all_tab_columns c 
     where c.table_name = t.table_name 
     and c.column_name = 'CLIENTID' -- put the right column name here 
    ) 
    ) LOOP 
     DBMS_OUTPUT.PUT_LINE(Name.TABLE_NAME); --I can't see any logs on DBMS Output for some reason 
     EXECUTE IMMEDIATE 'Update ' || Name.TABLE_NAME || ' set ClientID = 1 Where ClientID = 2'; 
    END LOOP; 
END; 

Вы, возможно, придется немного измените его, поскольку у меня нет базы данных Oracle передо мной. Возможно, я ошибался.

+0

Привет @sstan он почти работает, у меня очень мало таблиц, у которых нет поля, и он разбивает процесс, мне может понадобиться найти способ проверить, существует ли это поле в таблице, прежде чем выполнить sql – Icaro

+0

, он сделал не работает, выражение возвращает nil, и это очень странно, даже если пробег выбирает * из all_tab_columns c где c.column_name = 'ClientID' Я получаю пустой результат – Icaro

+0

Вы пытались 'CLIENTID' весь верхний регистр? По умолчанию Oracle хранит все имена столбцов в верхнем регистре. Кроме того, просто сделайте 'SELECT column_name FROM all_tab_columns WHERE table_name = 'выберите имя таблицы здесь'' и проверьте, что Oracle считает именем столбца. Похоже, вы действительно близки, вам просто нужно выяснить, как запросить метаданные столбца. – sstan

Смежные вопросы