Stored-Procedures

如何在插入時觸發此儲存過程?

  • June 25, 2012

我有一個錯誤消息表,其中將插入錯誤。我還有一個表定義錯誤之間的互動。例如,當發生“Power Restored”錯誤時,它會清除任何先前的“Power Lost”錯誤。(“錯誤”被鬆散地用於描述任何可列舉的診斷消息。)

為此,我定義了以下儲存過程:

BEGIN
  -- Declare local variables
  DECLARE done BIT DEFAULT 0;
  DECLARE target SMALLINT(5) UNSIGNED DEFAULT '0';
  DECLARE `action` ENUM('Clear','Raise','SetSeverity');
  DECLARE severity TINYINT(3) UNSIGNED DEFAULT NULL;
  DECLARE timespan INT(11) DEFAULT NULL;
  DECLARE cutoff TIMESTAMP;
  -- Declare the cursor
  DECLARE interactions CURSOR FOR
  SELECT TargetErrNo, errorinteraction.`Action`, errorinteraction.Severity, errorinteraction.TimeSpan
     FROM errorinteraction WHERE ActorErrNo=NEW.Number ORDER BY Priority DESC;
  -- Declare continue handler
  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
  CREATE TABLE IF NOT EXISTS interactionrecord
     (`datediff` INT);
  TRUNCATE TABLE interactionrecord;
  -- Open the cursor
  OPEN interactions;
  -- Loop through all rows
  REPEAT
     -- Get
     FETCH interactions INTO target, `action`, severity, timespan;
     IF NOT done THEN
        -- Process
        IF timespan IS NULL THEN
           IF `action`='Clear' THEN
              UPDATE error SET Cleared=NOW(), UpdatedBy=NEW.Id WHERE Number=target AND Cleared IS NULL;
           ELSEIF `action`='Raise' THEN
              UPDATE error SET Cleared=NULL, UpdatedBy=NEW.Id WHERE Number=target AND Cleared IS NOT NULL;
           ELSEIF `action`='SetSeverity' AND severity IS NOT NULL THEN
              UPDATE error SET error.Severity=severity, UpdatedBy=NEW.Id WHERE Number=target AND error.Severity!=severity;
           END IF;
        ELSE
           SET cutoff=DATE_SUB(NEW.Reported, INTERVAL timespan SECOND);
           IF `action`='Clear' THEN
              UPDATE error SET Cleared=NOW(), UpdatedBy=NEW.Id WHERE Number=target AND Cleared IS NULL AND error.Reported>=cutoff;
           ELSEIF `action`='Raise' THEN
              UPDATE error SET Cleared=NULL, UpdatedBy=NEW.Id WHERE Number=target AND Cleared IS NOT NULL AND error.Reported>=cutoff;
           ELSEIF `action`='SetSeverity' AND severity IS NOT NULL THEN
              UPDATE error SET error.Severity=severity, UpdatedBy=NEW.Id WHERE Number=target AND error.Severity!=severity AND error.Reported>=cutoff;
           END IF;
        END IF;
     END IF;
  -- End of loop
  UNTIL done END REPEAT;
  -- Close the cursor
  CLOSE interactions;
END

當我手動插入一個新錯誤,然後呼叫這個函式傳遞新錯誤的Id.

但是當我嘗試插入一個觸發器來自動呼叫它時,MySQL 開始向我拋出錯誤 1422。我已經嘗試了這兩種FOR EACH ROW CALL updateerror(NEW.Id); 方法並將儲存過程程式碼直接複製到觸發器中,用它們各自的NEW列替換了一些變數。我是否應該簡單地將其保留為儲存過程並假設使用者有責任呼叫它?有一個更好的方法嗎?

我的確切 MySQL 版本是 5.5.25。

我發現以下程式碼行不允許在觸發器中執行:

CREATE TABLE IF NOT EXISTS interactionrecord
     (`datediff` INT);
  TRUNCATE TABLE interactionrecord;

我把它們放在那裡是出於調試目的,卻忘了刪除它們。

刪除它們後,我可以將程式碼作為觸發器執行,直到我嘗試更新錯誤表,因為顯然也不允許更新觸發器所在的表。

我現在正在做的是一個觸發器,它只是將新錯誤Id插入到一個小表中,然後每分鐘左右執行一個事件,在所有新插入的錯誤上呼叫我的儲存過程。

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