2011-11-30 24 views
4

在我們的應用程序中,只有約25%的數據庫觸發器顯示在DBA_SOURCE中。我知道如果我進行實際的修改(如添加和刪除空間)然後重新編譯觸發器,我可以強制其他人出現,但我有大約400個觸發器進行修改(這是一個很大的應用程序)。只需重新編譯觸發器alter trigger <triggername> compile;沒有完成任何事情。Oracle觸發器在DBA_SOURCE中未顯示

沒有觸發器在DBA_SOURCE中,我們不能在觸發器代碼上進行文本搜索。

有沒有一些簡單的方法來完成這個?有什麼方法可以防止未來的問題?

我們在Oracle 10.2.0.5.0上。

+0

也許我應該補充說這是在我們的開發環境中,所以不管我做什麼都不會搞亂生產。 – AndyDan

+1

源代碼管理中的觸發器,還是僅僅在數據庫中?如果在源代碼控制中(它們應該在那裏),那麼你應該能夠對存儲觸發器的文件進行文本搜索。我承認搜索數據庫通常更容易,但關鍵是數據庫不應該成爲代碼的「主副本」,即使是開發者 - 我也從多年前的錯誤教訓中學到了錯誤的開發數據庫時的難題! –

+0

不幸的是,它們不在任何源代碼控制中,只是在數據庫中。希望我能說服團隊其他人,否則就是這樣(我在這裏已經有7年了,我仍然是這裏的新手)。也許我可以用它來推動這一點! – AndyDan

回答

2

我們有同樣的問題。這是來自舊版本Oracle的遷移問題。

觸發器在早期版本(8?,9i?)中未包含在DBA_SOURCE中,並且在遷移到較新版本時沒有被添加到DBA_SOURCE。重新編譯沒有將它們放入DBA_SOURCE中。但是,如果您刪除並重新創建觸發器,它們將包含在DBA_SOURCE中。

所以我的猜測是你有一些舊的觸發器,並已將數據庫遷移到較新的版本。

+0

我想你可能會用這個釘在頭上,吉姆。這個數據庫已經存在了10多年,自從我來到這裏以來,它已經從9i升級到了。我不知道它原來是什麼版本。你知道升級到11g是否解決了這個問題?我們計劃在明年某個時候進行升級(我認爲明年初)。 – AndyDan

+0

我們在移動到11g後從未檢查過,主要是因爲我認爲我們已經重新加載了所有觸發器。我沒有權利做類似「select * from dba_triggers t where where not exists(從dba_source s中選擇1,其中S.TYPE ='TRIGGER'和s.name = t.trigger_name);」抱歉。 –

+0

謝謝,吉姆。我接受了你的答案,不是因爲你直接回答了我的問題,而是因爲你解釋了這個問題。無人也回答了這個問題。 – AndyDan

0

誰擁有觸發器?

,當然,你試過

選擇所有者,從ALL_OBJECTS 其中OBJECT_TYPE =在( 'schema1', 'SCHEMA2')

+0

觸發器都在同一個模式中,它也包含所有表,存儲過程/函數/包等。我可以直接登錄到該模式,所以這不是問題。如果解決方案需要DBA權限,我們的DBA位於下一排隔間。 – AndyDan

3

'TRIGGER' 和老闆,我相信你能OBJECT_NAME 在all_triggers中找到源代碼。不幸的是,這些數據是LONG變量(Oracle的例子,就像我說的那樣,而不是我)。所以,最簡單的事情是創建一個臨時表來使用,以轉換爲CLOB數據填充它,然後搜索:

CREATE TABLE tr (trigger_name VARCHAR2(32), trigger_body CLOB); 

INSERT INTO tr 
(SELECT trigger_name, TO_LOB(trigger_body) 
    FROM all_triggers 
    WHERE owner = 'xxx'); 

SELECT trigger_name 
    FROM tr 
WHERE trigger_body LIKE '%something%'; 

我不知道爲什麼dba_source視圖只人煙稀少的觸發器。我的10.2.0.4數據庫也是這樣。

編輯:

這裏是一個簡短的腳本,你可以用它來重建所有觸發器,他們都應該是dba_source在這一點:

CREATE TABLE temp_sql (sql1 CLOB, sql2 CLOB); 

INSERT INTO temp_sql (sql1, sql2) (
SELECT 'CREATE OR REPLACE TRIGGER '|| 
     DESCRIPTION||' '||CASE WHEN when_clause IS NULL THEN NULL ELSE 'WHEN('||when_clause||')' END sql1, 
     to_lob(trigger_body) sql2 
    FROM all_triggers 
WHERE table_owner = 'theowner'); 

DECLARE 
    v_sql VARCHAR2(32760); 

BEGIN 
    FOR R IN (SELECT sql1||' '||sql2 S FROM temp_sql) LOOP 
    v_sql := R.s; 
    EXECUTE IMMEDIATE v_sql; 
    END LOOP; 
END; 
/
+0

這可以作爲一種解決方法,但是隨後整個開發團隊中的每個人都必須記住,無論何時他們使用新的或修改的觸發器,都可以在該表中添加新的或修改的觸發器。 – AndyDan

+0

或者您可以在需要搜索時簡單地重新創建數據。在事物的計劃中400觸發器並不是那麼多的數據。實際上,使其成爲全球臨時表,並在您每次需要搜索時進行構建。 – DCookie

+0

您還可以查詢dba_objects以確定何時在觸發器上執行最後一個DDL,以確定是否需要更新它。 – DCookie