Oracle 迭代所有列以查找和替换字符
我希望遍历所有列以查找和替换特定字符。下面是我的pl/sql块:Oracle 迭代所有列以查找和替换字符,oracle,plsql,Oracle,Plsql,我希望遍历所有列以查找和替换特定字符。下面是我的pl/sql块: Declare match_count Number:=0; v_search_string VARCHAR2(4000) := '%ي%'; BEGIN FOR t IN (SELECT owner, table_name, column_name FROM all_tab_columns WHERE (SUBSTR(table_name,1,2)='PN' OR (SUBSTR(table_name
Declare
match_count Number:=0;
v_search_string VARCHAR2(4000) := '%ي%';
BEGIN
FOR t IN
(SELECT owner,
table_name,
column_name
FROM all_tab_columns
WHERE (SUBSTR(table_name,1,2)='PN'
OR (SUBSTR(table_name,1,2) ='CD'
AND owner ='PNET_USER' ))
AND (data_type ='VARCHAR2'
OR data_type ='CLOB')
)
LOOP
BEGIN
EXECUTE IMMEDIATE 'SELECT count(*) FROM '||t.owner || '.' || t.table_name|| ' WHERE '||t.column_name||' LIKE :1' INTO match_count USING v_search_string;
IF match_count > 0 THEN
dbms_output.put_line( t.owner || '.' || t.table_name ||' '||t.column_name||' '||match_count );
--EXECUTE IMMEDIATE 'UPDATE '||t.table_name||' SET '||t.column_name||'=replace()'
END IF;
END;
END LOOP;
它工作正常,并打印包含无效字符的列的名称。但我不知道如何替换这些字符。如何获取t.column\u name
的值,替换无效字符,然后更新t.table\u name
立即执行“更新”| | t.table| | |“设置”| t.column| | | |”=替换(“| | t.column| u name |”、“从”、“到”)
应该这样做,其中FROM是无效字符,TO是要将其更改为的任何字符。
有关替换工作原理的说明,请参见链接中的oracle文档
注意:我没有地方尝试这个,所以语法可能不正确
立即执行“更新”| | t.table| | |“设置”| t.column| | | |”=替换(“| | t.column| u name |”、“从”、“到”)
应该这样做,其中FROM是无效字符,TO是要将其更改为的任何字符。
有关替换工作原理的说明,请参见链接中的oracle文档
注意:我没有任何地方可以尝试这个,所以语法可能不正确。嗯,这几乎没问题(stevo的答案也是如此)。我让你用你的手铐把v_从和v_换成
Declare
match_count Number :=0;
v_from varchar2(5) := 'a';
v_like varchar2(5) := '%'||v_from||'%';
v_to varchar2(5) := 'b';
v_sql varchar2(1000);
v_emesg varchar2(1000);
CURSOR s is
(SELECT owner, table_name, column_name
FROM all_tab_columns
where SUBSTR(table_name,1,2) IN ('PN', 'CD')
AND owner ='PNET_USER'
AND data_type IN('VARCHAR2', 'CLOB'););
begin
for t in s LOOP
begin
EXECUTE IMMEDIATE 'SELECT count(*) FROM '||t.owner || '.' || t.table_name|| ' WHERE '||t.column_name||' LIKE :1' INTO match_count USING v_like;
IF match_count > 0 THEN
begin
dbms_output.put_line( t.owner || '.' || t.table_name ||' '||t.column_name||' '||match_count );
v_sql := 'UPDATE '||t.owner||'.'||t.table_name||' SET '||t.column_name||'= REPLACE('||t.column_name||', '''||v_from||''', '''||v_to||''') WHERE '||t.column_name||' LIKE '''|| v_like||'''';
dbms_output.put_line(v_sql);
EXECUTE IMMEDIATE v_sql;
EXCEPTION WHEN OTHERS THEN
v_emesg := SQLERRM;
dbms_output.put_line(v_emesg);
dbms_output.put_line('Errow while trying to update '||t.owner||'.'||.t.table_name||' : column '||t.column_name||'.';
END;
END IF;
end;
END LOOP;
end;
嗯,这几乎是好的(斯特沃的回答也是)。我让你用你的手铐把v_从和v_换成
Declare
match_count Number :=0;
v_from varchar2(5) := 'a';
v_like varchar2(5) := '%'||v_from||'%';
v_to varchar2(5) := 'b';
v_sql varchar2(1000);
v_emesg varchar2(1000);
CURSOR s is
(SELECT owner, table_name, column_name
FROM all_tab_columns
where SUBSTR(table_name,1,2) IN ('PN', 'CD')
AND owner ='PNET_USER'
AND data_type IN('VARCHAR2', 'CLOB'););
begin
for t in s LOOP
begin
EXECUTE IMMEDIATE 'SELECT count(*) FROM '||t.owner || '.' || t.table_name|| ' WHERE '||t.column_name||' LIKE :1' INTO match_count USING v_like;
IF match_count > 0 THEN
begin
dbms_output.put_line( t.owner || '.' || t.table_name ||' '||t.column_name||' '||match_count );
v_sql := 'UPDATE '||t.owner||'.'||t.table_name||' SET '||t.column_name||'= REPLACE('||t.column_name||', '''||v_from||''', '''||v_to||''') WHERE '||t.column_name||' LIKE '''|| v_like||'''';
dbms_output.put_line(v_sql);
EXECUTE IMMEDIATE v_sql;
EXCEPTION WHEN OTHERS THEN
v_emesg := SQLERRM;
dbms_output.put_line(v_emesg);
dbms_output.put_line('Errow while trying to update '||t.owner||'.'||.t.table_name||' : column '||t.column_name||'.';
END;
END IF;
end;
END LOOP;
end;
对不起,我想我解释不清楚这个问题。我不想在列名中搜索无效字符。我需要替换列数据。我得到:ORA-01779:无法修改映射到非键保留表的列认为视图或没有主键的复制表有问题。。。我使用异常捕获进行编辑,您将看到哪些表或视图有问题。顺便说一下,引发异常的列不会更改。。。所以你应该通过“程序”,纠正发现的问题并重新通过程序!对不起,我想我解释不清楚这个问题。我不想在列名中搜索无效字符。我需要替换列数据。我得到:ORA-01779:无法修改映射到非键保留表的列认为视图或没有主键的复制表有问题。。。我使用异常捕获进行编辑,您将看到哪些表或视图有问题。顺便说一下,引发异常的列不会更改。。。所以你应该通过“程序”,纠正发现的问题并重新通过程序!