Sql-Server

根據插入的單元格值觸發 xp_LogEvent

  • December 14, 2017

我需要在表上創建一個觸發器(插入後),它只檢查單元格中的字元串。如果字元串存在,我需要在 Windows 事件記錄器中記錄一個事件。我不確定我是否能夠以這種方式使用插入的表,但我想我會嘗試。這是我到目前為止所擁有的:

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO

CREATE TRIGGER bcpCatchTrigger
  ON  dbo.TABLE_NAME
  AFTER INSERT
AS 
BEGIN
   SET NOCOUNT ON;
   DECLARE @@Message varchar(255), @@go int;
   SET @@go = 0

   CASE
       WHEN inserted.STAT_MESSAGE LIKE '%bcp.exe%' THEN @@go = 1
   END

   IF @@go == 1 {
       @@Message = inserted.STAT_MESSAGE
       EXEC xp_logevent 60000, @@Message, ERROR;
   }

END
GO

我在 CASE 語句中得到不正確的語法,但我不太明白為什麼。也許問題實際上是我如何訪問插入的表。我在哪裡錯了?

謝謝你。

編輯程式碼:

SET QUOTED_IDENTIFIER ON
GO

ALTER TRIGGER bcpCatchTrigger
  ON  dbo.TABLE_NAME
  AFTER INSERT
AS 
BEGIN
   SET NOCOUNT ON;
   DECLARE @@Message varchar(255), @@go int;
   SET @@go = CASE
       WHEN (SELECT STAT_MESSAGE FROM INSERTED) LIKE '%bcp.exe%' THEN 1
       ELSE 0
   END

   IF (@@go = 1) BEGIN
       SET @@Message = (SELECT STAT_MESSAGE FROM INSERTED)
       EXEC xp_logevent 60000, @@Message, ERROR;
   END

END
GO

讓我們從這個觸發器的主要問題開始:

SET @@Message = (SELECT STAT_MESSAGE FROM dbo.TABLE_NAME)

這將產生以下錯誤

子查詢返回超過 1 個值。當子查詢跟隨 =、!=、<、<=、>、>= 或子查詢用作表達式時,這是不允許的。

只要您的INSERT聲明將超過一行。

其他的建議多於更正。

  • insert檢查是否確實插入了任何行,如果不只是退出觸發器(if @@rowcount = 0 return;)是一個好習慣
  • 您也不應該執行從inserted 兩次讀取的程式碼。
  • 最後,我將其更改為僅讀取 (select top 1) 的第一次, STAT_MESSAGE LIKE '%bcp.exe%'但您應該考慮LIKE '%bcp.exe%'插入多行的情況:如果要記錄所有行,則應使用循環。

這是您修改的觸發器:

alter TRIGGER bcpCatchTrigger
  ON  dbo.TABLE_NAME
  AFTER INSERT
AS 
BEGIN
if @@rowcount = 0 return; 

SET NOCOUNT ON;

DECLARE @@Message varchar(255);

SELECT @@Message = (select top 1 STAT_MESSAGE
                   FROM INSERTED
                   where STAT_MESSAGE LIKE '%bcp.exe%')  
if @@Message is NULL return;

EXEC xp_logevent 60000, @@Message, ERROR;
END;
SET QUOTED_IDENTIFIER ON
GO

ALTER TRIGGER bcpCatchTrigger
  ON  dbo.TABLE_NAME
  AFTER INSERT
AS 
BEGIN
   SET NOCOUNT ON;
   DECLARE @@Message varchar(255), @@go int;
   SET @@go = CASE
       WHEN (SELECT STAT_MESSAGE FROM INSERTED) LIKE '%bcp.exe%' THEN 1
       ELSE 0
   END

   IF (@@go = 1) BEGIN
       SET @@Message = (SELECT STAT_MESSAGE FROM INSERTED)
       EXEC xp_logevent 60000, @@Message, ERROR;
   END

END
GO

以上工作完美。現在錯誤會在我的事件日誌中添加一個條目,我可以從中觸發計劃的任務事件。

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