[SQL][問題處理]無法刪除 SQL Agent 內的作業, 出現 作業卸除失敗的錯誤訊息 ?

[SQL][問題處理]無法刪除 SQL Agent 內的作業, 出現 作業卸除失敗的錯誤訊息 ?

收到一個朋友傳來的問題,他原先有設定一個維護計畫,但後來因為那個維護計畫有些設定錯了,因此再使用一陣子之後,將該執行計畫給刪除,再重新建立一組新的。正常狀況下要是你刪除執行計畫,則會自動將執行計畫所建立的 SQL Agent Job ( 作業 ) 也會一併刪除。但就是那麼剛好他的環境中雖然已經把執行計畫給刪除,但就是沒有辦法刪除作業,但如果想要手動透過 SSMS 來做刪除。

clip_image001

 

從錯誤訊息中我們稍微可以看出一些端倪,看起來 SSMS 刪除時是呼叫 sp_delete_job 的預存程序去刪除時,因為 sysmainplan_subplans 裡面會去關連到這個這個 job_id 的欄位,導致沒有辦法刪除。既然如此,那我們先看一下 msdb.dbo.sysjobs 這個 table 會有那些 Table 跟他建立關聯

SELECT
  OBJECT_NAME(f.parent_object_id) AS TableName, COL_NAME(f.parent_object_id, fc.parent_column_id) AS ColumnName   
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc ON f.OBJECT_ID = fc.constraint_object_id
WHERE 
  OBJECT_NAME (fc.referenced_object_id) = 'sysjobs' AND
  COL_NAME(fc.referenced_object_id,fc.referenced_column_id) = 'job_id'

image

 

配合上述關聯出來的 Table 和錯誤訊息,看起來在刪除作業的時後,可能有先去判斷執行計畫是否有存在,但因為該執行計畫已經刪除掉了,所以沒有去判斷到還有子計畫沒有刪除,因此

透過以下的指令,我們可以查到需要手動處理的部分

image

image

 

但如果要手動刪除 sysmaintplan_subplans 這個 Table 的資料的時候,我們也先來檢查一下是否有人關連到該 Table,因此比照上述檢查的語法,調整一下 Table 和欄位名稱

SELECT
  OBJECT_NAME(f.parent_object_id) AS TableName, COL_NAME(f.parent_object_id, fc.parent_column_id) AS ColumnName   
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc ON f.OBJECT_ID = fc.constraint_object_id
WHERE 
  OBJECT_NAME (fc.referenced_object_id) = 'sysmaintplan_subplans' AND
  COL_NAME(fc.referenced_object_id,fc.referenced_column_id) = 'subplan_id'

image

 

既然知道這些關聯之後,那就反過來先手動把 sysmaintplan_log 內的 log 紀錄刪除,接著刪除 sysmaintplan_subplans 內的紀錄,最後再透過 sp_delete_job 的預存程序去刪除,就可以順利的清除資料。

image

 

後記 : 在絕大部分狀況下 SSMS 是都可以正常運作的,但有時還是會有些突發狀況,因此要能當一個 DBA,不能只靠 SSMS 來處理,遇到一些如上述的例外狀況時,或許善用一些簡單的語法和觀念,就能輕鬆的解決問題了。