2011-04-19 30 views
1

我想在所有使用它的數據庫對象中搜索並替換DZONE爲SZONE。我有一個查詢使用下面的查詢搜索DZONE,但不知道如何在代碼中進行替換。搜索並替換所有數據庫對象中的字符串oracle數據庫中的源代碼

select name,text from user_source where text like '%DZONE'; 
+0

這個問題意味着你沒有使用源代碼管理。這是一個非常嚴重的攻擊。 :)請參閱http://www.joelonsoftware.com/articles/fog0000000043.html – 2011-04-21 03:11:46

回答

-4

使用更新與查詢的WHERE子句

Update user_source 
Set text = 'SZONE' 
Where text like '%DZONE'; 

希望幫助

+1

不確定嘗試更新內部Oracle視圖是一個好主意,或者對於普通用戶來說是允許的。然而,如果需要「替換」的話,這在正常表格上並不正確,這會在DZONE之前丟失任何文本。 – 2011-04-19 10:20:05

+2

反思一下,我會重申那個;試圖直接更新'USER_SOURCE'確實是一個壞主意。 – 2011-04-19 10:24:03

+0

-1;這是一個非常糟糕的主意;我們無法以這種方式執行更新。非常不受支持。更好的辦法是生成DDL並重新發布修改後的DDL。 – 2011-04-19 10:41:11

3

您不能直接更新對象的來源。您需要識別所有對象,並使用修改後的文本重新創建它們 - 無論是首先使用任何DDL創建它們的更新版本,還是通過提取全文,更新它,然後執行它。你可以用動態SQL做,但這似乎有點危險 - 我個人可能想要檢查和驗證我正在更新的所有內容。

4

先拿到DDL和其後臺到一個文本文件供您查看:源

select regexp_replace (dbms_metadata.get_ddl (object_type, object_name, USER),'DZONE','SZONE') 
from (
select distinct object_name, object_type 
from user_procedures where object_name in (select name from user_source where text like '%DZONE%') 
) 

不是適用於您的數據庫。 爲你想要修改的對象類型做這件事,在這個例子中,我只挑選了存儲過程,包和函數。 我希望它有幫助。

0

我最近需要創建這樣的腳本。這是所有數據庫替換錯誤的Unicode字符,所以我開始各地尋找一個:

 
--text with encoding problems 

SET SERVEROUTPUT ON SIZE 100000 

DECLARE 
CURSOR c1 IS 
SELECT owner, table_name, column_name 
       FROM all_tab_columns 
       WHERE owner = 'your-owner-name' and data_type LIKE '%CHAR%'; 
-- 
c1rec c1%ROWTYPE; 
-- 
l_sql VARCHAR2(1000); 
BEGIN 
FOR r1 IN c1 LOOP 
    l_sql := 'DECLARE '|| 
      ' CURSOR c1 IS '|| 
      ' SELECT '||r1.column_name|| 
      ' FROM '||r1.table_name||' WHERE '||r1.column_name||' like ''%Ã%''; '|| 
      ' c1rec c1%ROWTYPE; '|| 
      'BEGIN '|| 
      ' FOR r1 IN c1 LOOP '|| 
      '  dbms_output.put_line('''||r1.table_name||'.'||r1.column_name||': ''|| r1.'||r1.column_name||'); '|| 
      ' END LOOP; '|| 
      'END; '; 

    EXECUTE IMMEDIATE l_sql; 
END LOOP; 
END; 
/

,將打印所有文字問題(如你需要修改所有者或數據類型)

好,但之後,您需要修復數據庫(替換)。好吧,這只是與Oracle PL/SQL

 
--generating updates with encoding problems 

SET SERVEROUTPUT ON SIZE 100000 

DECLARE 
CURSOR c1 IS 
SELECT owner, table_name, column_name 
       FROM all_tab_columns 
       WHERE owner = 'your-owner-name' and data_type LIKE '%CHAR%'; 
-- 
c1rec c1%ROWTYPE; 
-- 
l_sql VARCHAR2(1000); 
BEGIN 
FOR r1 IN c1 LOOP 
    l_sql := 'DECLARE '|| 
      ' CURSOR c1 IS '|| 
      ' SELECT '||r1.column_name|| 
      ' FROM '||r1.table_name||' WHERE '||r1.column_name||' like ''%Ã%''; '|| 
      ' c1rec c1%ROWTYPE; '|| 
      'BEGIN '|| 
      ' FOR r1 IN c1 LOOP '|| 
      '  dbms_output.put_line(''UPDATE '||r1.table_name||' SET '||r1.column_name||' = ''''''|| r1.'||r1.column_name||'||'''''' WHERE '||r1.column_name||' = ''''''|| r1.'||r1.column_name||'||'''''';''); '|| 
      ' END LOOP; '|| 
      'END; '; 

    --dbms_output.put_line(l_sql); 

    EXECUTE IMMEDIATE l_sql; 
END LOOP; 
END; 
/

,將輸出一系列更新的命令,你應該用你的修改調整更多的樂趣。

 
UPDATE PERSON SET NAME = 'ÿângela' WHERE NAME = 'ÿângela'; 
UPDATE ROOM SET DESCRIPCION = 'Sala de reparacÿn' WHERE DESCRIPCION = 'Sala de reparacÿn'; 
... 

是這樣的:根據問題

 
UPDATE PERSON SET NAME = 'Ángela' WHERE NAME = 'ÿângela'; 
UPDATE ROOM SET DESCRIPCION = 'Sala de reparación' WHERE DESCRIPCION = 'Sala de reparacÿn'; 
... 

(如果你設法對付報價地獄)

提示,你可以自動完成這個部分:這是一個替代

更新
 
SET SERVEROUTPUT ON SIZE 100000 

DECLARE 
CURSOR c1 IS 
SELECT owner, table_name, column_name 
       FROM all_tab_columns 
       WHERE owner = 'your-owner-name' and data_type LIKE '%CHAR%'; 
       --uncomment to shorten the search and debug 
       --AND table_name = 'some-table' 
-- 
c1rec c1%ROWTYPE; 
-- 
l_sql VARCHAR2(1000); 
BEGIN 
FOR r1 IN c1 LOOP 
    l_sql := 'DECLARE '|| 
      ' CURSOR c1 IS '|| 
      ' SELECT '||r1.column_name|| 
      ' FROM '||r1.table_name||' WHERE '||r1.column_name||' like ''%ÿ%''; '|| 
      ' c1rec c1%ROWTYPE; '|| 
      'BEGIN '|| 
      ' FOR r1 IN c1 LOOP '|| 
      '  dbms_output.put_line(''UPDATE '||r1.table_name||' SET '||r1.column_name||' = REPLACE('||r1.column_name||',''''%ÿ%'''',''''ó'''')''||'' WHERE '||r1.column_name||' = ''''''|| r1.'||r1.column_name||'||'''''';''); '|| 
      ' END LOOP; '|| 
      'END; '; 

    --uncomment to debug   
    --dbms_output.put_line(l_sql); 

    EXECUTE IMMEDIATE l_sql; 
END LOOP; 
END; 
/

其中輸出類似於:

 
UPDATE VEHICLE SET NAME = REPLACE(NAME,'%ÿ%','ó') WHERE NAME = 'Camiÿn'; 
相關問題