Oracle

序列化:觸發器中的新

  • February 1, 2016

我有一個需要創建 Oracle Advanced 隊列消息的觸發器。該消息的有效負載應包含已創建的新記錄,可通過 :new 訪問。

我正在尋找一種將 :new 對象轉換為原始或自定義數據類型的方法,該數據類型可以以通用方式設置為隊列消息的有效負載。

目前我正在嘗試將 :new 轉換為 anydata 並將其設置為有效負載數據類型。

我以這種方式實現了您嘗試執行的操作:到使用者定義對象的轉換發生在觸發器呼叫的打包過程中。

---all comments and debugging removed to keep it simple----    
CREATE OR REPLACE TRIGGER when_close_ini
  AFTER UPDATE OF end_date
  ON YOUR_TABLE
  REFERENCING NEW AS NEW OLD AS OLD
  FOR EACH ROW
DECLARE

BEGIN
  IF :NEW.end_date IS NULL AND :OLD.end_date IS NOT NULL
  THEN
     my_schema.queue_util.add_file_to_queue ('REOPEN', :NEW.ID, NULL);

  END IF;

END when_close_ini;

----------------an excerpt from the package with debugging removed----
PROCEDURE add_file_to_queue   (action_in      IN VARCHAR2,
                               d_case_id_in   IN NUMBER,
                               d_other_in     IN VARCHAR2 := NULL)
  IS

     queue_options        SYS.DBMS_AQ.ENQUEUE_OPTIONS_T;
     message_properties   SYS.DBMS_AQ.MESSAGE_PROPERTIES_T;
     message_id           RAW (16);
     my_message           MY_SCHEMA.file_action;
     err_text             VARCHAR2 (2000);
     PRAGMA AUTONOMOUS_TRANSACTION;
  BEGIN

     my_message := my_schema.file_action (action_in, d_case_id_in, d_other_in);
     DBMS_AQ.enqueue (queue_name           => 'MY_SCHEMA.MY_QUEUE',
                      enqueue_options      => queue_options,
                      message_properties   => message_properties,
                      payload              => my_message,
                      msgid                => message_id);
    COMMIT;
  END add_file_to_queue;

幾年前我與 PL/SQL 項目經理討論過這個問題,並被告知這是不可能的。您不能將 :NEW 或 :OLD 列作為記錄來處理並將它們轉換為任何內容。您可以創建一個與您正在為其編寫觸發器的表相同或通用的臨時表,即 table_name、column_name、column_type、clob。然後,您可以將 :NEW 或 :OLD 值插入到臨時表中,並且可以使用 after 語句觸發器訪問這些值。然後您可以在 after 語句觸發器中讀取數據。

引用自:https://dba.stackexchange.com/questions/127895