【问题标题】:Update all rows in all tables in Oracle更新Oracle中所有表中的所有行
【发布时间】:2015-07-07 01:00:12
【问题描述】:

我有一个字段 (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;

【问题讨论】:

    标签: oracle oracle11g sql-update


    【解决方案1】:

    您可以尝试使用 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绑定参数的方式。我只是不记得该怎么做。不过如果你需要的话,在 cmets 里问,我会找的。​​p>

    编辑

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

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

    【讨论】:

    • 嗨@sstan它几乎可以工作,我有很少的表没有该字段并且它使进程崩溃,我可能需要找到一种方法来检查它在执行之前表中是否存在该字段sql
    • 不行,表达式返回nil,很奇怪,即使一个运行 select * from all_tab_columns c where c.column_name = 'ClientID' 我得到一个空结果
    • 你试过CLIENTID全部大写吗?默认情况下,Oracle 以大写形式存储所有列名。或者,只需执行SELECT column_name FROM all_tab_columns WHERE table_name = 'pick a table name here',然后检查 Oracle 认为列名是什么。听起来你真的很接近,你只需要弄清楚如何查询列元数据。
    • 是的,谢谢,这是我应该使用所有大写字母的问题,现在它正在工作,变量在 EXECUTE IMMEDIATE 中不起作用,但我对其进行了硬编码,然后它工作正常(也许你想编辑答案。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2013-04-10
    • 2023-04-01
    • 2020-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-06
    • 1970-01-01
    相关资源
    最近更新 更多