Trigger
如何在不使用觸發器的情況下觸發操作
我只是想問問。我們有一個日曆表,我們在一個數據庫中將其稱為 CAL1,我們將其稱為 DB1。CAL1 是手動填充的。現在在另一個數據庫 DB2 中,有另一個日曆表 CAL2。我需要做的是根據 CAL1 中的值填充 CAL2。我不知道何時會填充 CAL1。其他數據庫中還有一些其他日曆表/表將引用 CAL1,因此我需要創建一個 API,以便在將新數據載入到 CAL1 時填充或至少執行來自其他數據庫(例如 DB2)的過程。我最初考慮使用觸發器,但讀到最好不要使用它。那麼有沒有其他方法可以在不使用觸發器的情況下做到這一點?非常感謝。
這取決於您希望 CAL2 的最新程度。
如果它應該立即反映 CAL1 中的值,那麼觸發器就是要走的路。
如果它可能有幾個 mnutes 不同步,那麼您可以有一個每 5 分鐘執行一次的作業並呼叫一個同步表的儲存過程。
另一個解決方案是創建一個在 CAL1 上執行 CRUD 操作的包。更改、插入或刪除值時,呼叫的過程可以創建一個作業來更新 CAL2,或者將值插入到要傳播到訂閱者數據庫的高級隊列中。
Arwen 詢問更多細節:
有很多方法可以實現這一點,最好的方法必須考慮到您的數據庫和網路。
- 如果 DB2 在全國范圍內,則可能會因延遲或停機而超時。如果 DB2 位於伺服器機架的另一側,那麼假設 DB1 已啟動,那麼 DB2 也將啟動,您可能會感覺更舒服。
- 您還應該考慮 DB2 不更新的後果是什麼?這個任務是關鍵任務還是應該在 24 小時內引起注意和修復。任務關鍵型應用程序需要更堅固的解決方案。
- 有多少交易?每天幾萬,幾千,幾百萬?硬體、網路選擇和編碼解決方案都受此影響。
讓我們從 DB1 上的範例插入開始。這應該是包的一部分
FUNCTION CREATE_CASE (case_type_id_in IN NUMBER, created_by_in IN NUMBER, file_ref_in IN VARCHAR2:= NULL, file_title_in IN VARCHAR2:= NULL) RETURN NUMBER IS /****************************************************************************** PURPOSE: create a case of any type ******************************************************************************/ c_log_case_created CONSTANT VARCHAR2 (10) := 'LOG_1009'; v_case_id NUMBER (10); v_file_ref VARCHAR2 (200); v_log_message VARCHAR2 (200); v_contact_date TIMESTAMP (6) := CURRENT_TIMESTAMP; BEGIN SELECT CASE_ID_SEQ.NEXTVAL INTO v_case_id FROM DUAL; INSERT INTO APPBASE.CASE (ID, CASE_TYPE_ID, TITLE, CREATED_BY_USER_ID, LAST_MODIFIED_BY_USER_ID, REFERENCE_NUMBER) VALUES (v_case_id, case_type_id_in, file_title_in, created_by_in, created_by_in, v_file_ref); v_log_message := v_file_ref || ',' || v_case_id || ','; APP_UTIL.APP_LOG (created_by_in, v_case_id, c_log_case_created, v_log_message); --notice: no commit, this is done outside the package and no error handling -- we want errors to bubble up to the calling application -- but we do want a log of what was successful --here is where we add the same information to an oracle advanced queue --the most bulletproof solution, allows the main transaction to complete --and the secondary insert becomes a second transaction QUEUE_UTIL.ADD_FILE_TO_QUEUE(case_type_id_in,v_case_id,null); RETURN v_case_id; END CREATE_CASE; --then in another package QUEUE_UTIL dealing with the queue PROCEDURE add_file_to_queue (case_type_in IN NUMBER, d_case_id_in IN NUMBER, d_other_in IN VARCHAR2:= NULL) IS /****************************************************************************** PURPOSE: when there is a change to a file (create, closed or reopen) add the change to queue of changes ******************************************************************************/ queue_options SYS.DBMS_AQ.enqueue_options_t; message_properties SYS.DBMS_AQ.message_properties_t; message_id RAW (16); my_message file_action; err_text VARCHAR2 (2000); PRAGMA AUTONOMOUS_TRANSACTION; BEGIN my_message := chrcbase.file_action (case_type_in, d_case_id_in, d_other_in); DBMS_AQ.enqueue (queue_name => 'CASE_QUEUE', enqueue_options => queue_options, message_properties => message_properties, payload => my_message, msgid => message_id); IF g_debugging THEN q$error_manager.TRACE ( q$error_manager.MAKE_AN_INFO_MSG ('Inserted case ID'), 'QUEUE_UTIL.ADD_FILE_TO_QUEUE ' || ' Case ' || d_case_id_in || ' action ' || action_in || ' Other ' || d_other_in, TRUE ); END IF; COMMIT; EXCEPTION WHEN NO_DATA_FOUND THEN err_text := SQLERRM; INSERT INTO application_error_logging ( ID, request_uri, ERROR_CODE, user_id, stack_trace, information, TIMESTAMP ) VALUES ( application_error_logging_seq.NEXTVAL, 'QUEUE_UTIL.add_file_to_queue', NULL, g_admin_id, 'Failed to insert case ID ' || d_case_id_in || ' file ' || ' ' || TO_CHAR (SYSDATE, 'DD-MON-YYYY HH12:MI'), 'Failure:no Data ' || err_text, SYSDATE ); COMMIT; WHEN OTHERS THEN err_text := SQLERRM; INSERT INTO application_error_logging ( ID, request_uri, ERROR_CODE, user_id, stack_trace, information, TIMESTAMP ) VALUES ( application_error_logging_seq.NEXTVAL, 'QUEUE_UTIL.add_file_to_queue', NULL, g_admin_id, 'Failed to insert case ID ' || d_case_id_in || ' ' || TO_CHAR (SYSDATE, 'DD-MON-YYYY HH12:MI'), 'Failure:when Others ' || err_text, SYSDATE ); COMMIT; END add_file_to_queue;
這不是一個完整的解決方案,因為您需要為消息和隊列創建類型,並授予管理隊列的權限。解決方案的最後一部分是將消息從隊列中彈出並將更改插入 DB2。