不要在使用 sys.sql_dependencies 來處理 !
臨時一個朋友傳來一個問題,說他的資料表增加一個欄位之後,結果造成一些程式都發生問題了,但如果把欄位給刪除,系統又恢復正常了。
連看查看一下,原來是它們系統中建立了很多的 View,而增加 Table 的欄位的時候,因為沒有更新到 View 的 Metadata ,因此造成會使用到該資料表的 View 取得的欄位會有偏移的狀況發生,因此當下想說是個簡單的問題,就請朋友看一下亂馬客所寫的「使用 sp_refreshview 更新 View 的 Metadata」,應該依樣畫葫蘆就好了。
但過了一天之後,又收到朋友傳來的訊息,他表示有按照文章中的處理去做,但問題還是依舊,因此又再度連線查看一下,才發現原來是因為微軟已經將原本的 sys.sql_dependencies 這個 DMV 已經給作廢了,雖然還可以使用,但裡面的資料是不正確的。目前需要使用 sys.sql_expression_dependencies 來取代,因此協助幫忙改一下指令,也做一下紀錄免得以後自己又踩到相同的地雷了。
SELECT 'EXEC sp_refreshview ''' + o.name + ''''
FROM sys.sql_expression_dependencies sed
JOIN sys.objects o ON sed.referencing_id=o.object_id and o.type = 'V'
WHERE sed.referenced_schema_name='dbo' AND sed.referenced_entity_name = '更新的 Table Name'
基本上雖然可以用上述方法,配合 sp_refreshview 去更新所有相依的 View,但我個人還是不建議那樣的作法,因為雖然可以在 View 裡面使用 select * 的方式,但這真的不是一個好習慣,因此我會建議改成以下幾種做法:
1. 利用 SSDT 建立資料庫專案,在專案內進行相關更改,這樣當有欄位異動或變更的時候,當佈署的時候它會自動去做相關處理。
2. 避開 select * 的寫法,在 Stored Procedure 或 View 裡面,最好明確的把欄位名稱給列出來