2012-05-13 44 views
1

我想遍历所有列来查找和替换特定字符。这是我的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,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_name的值,替换无效字符,然后更新t.table_name

回答

2

好吧,它几乎没问题(还有stevo的回答)。我让你用你的字符改变v_from和v_to。

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; 
+0

对不起,我想我无法解释清楚的问题。我不想在列名中搜索无效字符。我需要更换列数据。 – danrah

+0

Ok现在编辑... –

+0

我得到:ORA-01779:无法修改映射到非密钥保存表的列 – danrah

-1

类似于

EXECUTE IMMEDIATE'UPDATE'|| t.table_name ||' SET'|| t.column_name ||'= replace('|| t.column_name ||',''FROM'',''TO'')'

应该这样做,其中FROM是无效字符TO是你想要改变它的任何东西。 有关REPLACE如何工作的解释,请参阅链接中的oracle docs。

http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions134.htm

注意:我没有任何地方可以尝试此操作,因此语法可能不正确。