在 SQL Server 中啟用 CLR 整合雖能以 .NET 語言撰寫預存程序/函數,但 DBA 常因記憶體洩漏風險、除錯困難、部署遷移複雜、首次載入效能差而持保留態度。本文彙整實務經驗:CLR Bug 可能導致整個 SQL 服務掛點、記憶體壓力下組件反覆載入/卸載拖垮效能、複寫錯誤排查時 CLR 預存程序頻現記憶體錯誤。並詳解 .NET 記憶體回收機制、IDisposable/using 模式正確釋放非受控資源,附完整 C# 範例與實際 SQL Server CLR 部署腳本。
Dispose 將洩漏;~Class() 中的 I/O 操作會延遲記憶體釋放;StreamWriter 在終結子寫入日誌,導致檔案關閉延遲。public class MyResource : IDisposable
{
private StreamWriter _writer;
public MyResource(string path) { _writer = new StreamWriter(path); _writer.WriteLine("Init"); }
public void Dispose() { _writer?.Close(); _writer = null; GC.SuppressFinalize(this); }
}
// 使用
using (var r = new MyResource("test.txt"))
{
r._writer.WriteLine("Working");
} // 離開 using 即呼叫 Dispose,檔案立即關閉
using 確保區塊結束時釋放資源,即使發生例外;GC.SuppressFinalize 避免雙重清理;IDisposable。包含純量函數(正則比對、位元運算、權限運算、變體格式化)、表值函數(結果集串聯、倉庫調撥查詢)等 7 個 CLR 函數的 CREATE FUNCTION ... AS EXTERNAL NAME 完整 T-SQL,展示組件註冊命名慣例 Assemblies.[Namespace.Class].Method。
| 場景 | 建議 |
|---|---|
| 複雜字串/正則/加密運算 | ✅ CLR 優於 T-SQL |
| 大量集合運算/資料存取 | ❌ T-SQL 集合導向更高效 |
| 需外部資源(Web Service、檔案) | ⚠️ EXTERNAL_ACCESS 需嚴格審核 |
| 核心業務邏輯/高併發熱點 | ❌ 留在應用層,避免資料庫成為單點 |
結論:CLR 整合是利器,但**僅限於純運算、無外部依賴、效能經驗證**的場景。嚴守 IDisposable 模式、最小權限原則、完整測試與監控,方能安全落地。