Database 查找和替换,循环遍历oracle DB中的所有表

Database 查找和替换,循环遍历oracle DB中的所有表,database,oracle,loops,replace,Database,Oracle,Loops,Replace,我试图循环遍历oracle数据库中的每个表,并查找和替换字符串值。我想为整个数据库中的所有条目查找字符串值的所有实例,用另一个字符串值替换它。我很接近,但由于某种原因,我的代码没有正确响应 DECLARE CURSER all_tables IS SELECT table_name FROM all_tables; v_count NUMBER; BEGIN FOR host IN all_tables LOOP SELECT REPLACE('jack

我试图循环遍历oracle数据库中的每个表,并查找和替换字符串值。我想为整个数据库中的所有条目查找字符串值的所有实例,用另一个字符串值替换它。我很接近,但由于某种原因,我的代码没有正确响应

DECLARE
   CURSER all_tables IS
      SELECT table_name FROM all_tables;
   v_count NUMBER;
BEGIN
   FOR host IN all_tables LOOP
      SELECT REPLACE('jack','j','b') "Changes"
         FROM host
   END LOOP;
END;

警告一句

DECLARE
    schemaName VARCHAR2(30) := 'HR';
    stmt VARCHAR2(32767); -- on 11g, use CLOB
BEGIN
    FOR tr IN (
        SELECT t.OWNER, t.TABLE_NAME
        FROM ALL_TABLES t
        WHERE t.OWNER = schemaName
        ORDER BY 1, 2
    )
    LOOP
        FOR cr IN (
            SELECT c.COLUMN_NAME
            FROM ALL_TAB_COLUMNS c
            WHERE c.OWNER = tr.OWNER AND c.TABLE_NAME = tr.TABLE_NAME
              AND c.DATA_TYPE = 'VARCHAR2'
            ORDER BY 1
        )
        LOOP
            stmt := 'UPDATE '||tr.OWNER||'.'||tr.TABLE_NAME
                ||' SET '||cr.COLUMN_NAME||' = REPLACE('||cr.COLUMN_NAME||', ''j'', ''b'')';
            DBMS_OUTPUT.PUT_LINE(stmt||';'); -- useful for debugging
            EXECUTE IMMEDIATE stmt;
        END LOOP;
    END LOOP;
END;
/
如果您实际上试图为模式中每个表中的每一列替换字符串值,请注意这至少需要几个小时

撇开免责声明不谈,类似的脚本在很多情况下都很有用(可能是更改列名,可能是执行海量数据清理,或者是从元数据表创建表)

一般方法

基本上,您需要:

  • 循环遍历目标架构中的每个表
  • 对于每个表,循环遍历每个
    VARCHAR2
  • 对于每个列,生成一个
    UPDATE
    语句并执行它
  • 更智能的解决方案只为每个表生成一条
    UPDATE
    语句。然后,您的解决方案将:

  • 循环遍历目标架构中的每个表
  • 对于每个表,生成
    UPDATE
    语句的第一部分,直到
    SET
    子句
  • 对于每一列,将
    SET
    子句的一部分附加到语句中
  • 执行你的陈述
  • Oracle 10g/11g的示例代码,使用众所周知的HR模式:

    每列一条更新语句

    DECLARE
        schemaName VARCHAR2(30) := 'HR';
        stmt VARCHAR2(32767); -- on 11g, use CLOB
    BEGIN
        FOR tr IN (
            SELECT t.OWNER, t.TABLE_NAME
            FROM ALL_TABLES t
            WHERE t.OWNER = schemaName
            ORDER BY 1, 2
        )
        LOOP
            FOR cr IN (
                SELECT c.COLUMN_NAME
                FROM ALL_TAB_COLUMNS c
                WHERE c.OWNER = tr.OWNER AND c.TABLE_NAME = tr.TABLE_NAME
                  AND c.DATA_TYPE = 'VARCHAR2'
                ORDER BY 1
            )
            LOOP
                stmt := 'UPDATE '||tr.OWNER||'.'||tr.TABLE_NAME
                    ||' SET '||cr.COLUMN_NAME||' = REPLACE('||cr.COLUMN_NAME||', ''j'', ''b'')';
                DBMS_OUTPUT.PUT_LINE(stmt||';'); -- useful for debugging
                EXECUTE IMMEDIATE stmt;
            END LOOP;
        END LOOP;
    END;
    /
    
    每个表一条更新语句

    您可以尝试变得更聪明,对表中的所有列只使用一条
    UPDATE
    语句。小心不要使
    stmt
    变量溢出

    DECLARE
        schemaName VARCHAR2(30) := 'HR';
        stmt VARCHAR2(32767); -- on 11g, use CLOB
        do_update BOOLEAN;
    BEGIN
        FOR tr IN (
            SELECT t.OWNER, t.TABLE_NAME
            FROM ALL_TABLES t
            WHERE t.OWNER = schemaName
            ORDER BY 1, 2
        )
        LOOP
            do_update := FALSE;
            stmt := 'UPDATE '||tr.OWNER||'.'||tr.TABLE_NAME||' SET ';
            FOR cr IN (
                SELECT c.COLUMN_NAME
                FROM ALL_TAB_COLUMNS c
                WHERE c.OWNER = tr.OWNER AND c.TABLE_NAME = tr.TABLE_NAME
                  AND c.DATA_TYPE = 'VARCHAR2'
                ORDER BY 1
            )
            LOOP
                do_update := TRUE;
                stmt := stmt||cr.COLUMN_NAME||' = REPLACE('||cr.COLUMN_NAME||', ''j'', ''b''), ';
            END LOOP;
            IF do_update THEN
                stmt := SUBSTR(stmt, 1, LENGTH(stmt) - 2); -- remove trailing ', '
                DBMS_OUTPUT.PUT_LINE(stmt||';'); -- useful for debugging
                EXECUTE IMMEDIATE stmt;
            END IF;
        END LOOP;
    END;
    /
    

    请展示你迄今为止所做的工作。这是可能的,但这是一件非常不寻常的事情。本质上与相同,只是使用了update…
    CURSER
    是一个不正确的关键字,您必须指定一个列名而不是Jack。我不明白你为什么写这段代码。在所有表中的所有列中循环是一种有用的技术。选择的例子是不寻常的,一般的方法是值得学习的。