更新Oracle中所有表中的所有行

时间:2015-07-07 01:00:12

标签: oracle oracle11g sql-update

我有一个字段(clientID)在大多数我的表中重复(大约100左右),我正在尝试使用oracle 11g一次更新它。我能够得到表的名称,但我无法使用它。从下面的代码:

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;

1 个答案:

答案 0 :(得分:3)

您可以尝试使用EXECUTE IMMEDIATE

来使用动态SQL

这样的事情:

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绑定参数。我只是不记得如何做到这一点。但如果您需要,请在评论中提问,我会寻找它。

修改

我认为如果要绑定值,它看起来像这样:

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

编辑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数据库。我可能拼错了一些东西。