Database 查找和替换,循环遍历oracle DB中的所有表
我试图循环遍历oracle数据库中的每个表,并查找和替换字符串值。我想为整个数据库中的所有条目查找字符串值的所有实例,用另一个字符串值替换它。我很接近,但由于某种原因,我的代码没有正确响应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
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
子句的一部分附加到语句中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。我不明白你为什么写这段代码。在所有表中的所有列中循环是一种有用的技术。选择的例子是不寻常的,一般的方法是值得学习的。