Sql-Server

使用 Visual Studio 2017 發布 SQLCLR C# 函式時出錯

  • January 21, 2019

我正在嘗試(學習)使用 Visual Studio 2017 發布 SQLCLR 函式。(這是一個發送電子郵件的簡單函式。)

作為參考,我在CodeProjectMSSQLTips上使用了這篇文章:

使用 Visual Studio 2013 數據庫項目創建、執行、調試和部署 SQL CLR 函式

使用 CLR 儲存過程從 SQL Server Express 發送電子郵件

在項目屬性-> SQLCLR 我已經設置:

Permission level : UNSAFE

根據文章,我更新了目標數據庫:

sp_configure 'clr enabled', 1;  
GO  
RECONFIGURE;  
GO  

在我得到錯誤之後,我在 MSSQLTips 文章中遵循了這個建議:

如果您在嘗試編譯程式碼時收到錯誤消息,您可能需要使用以下命令更改數據庫,然後再次嘗試創建程序集和儲存過程。

ALTER DATABASE msdb SET trustworthy ON

我嘗試過使用兩個不同的目標數據庫:

  • SQL-Server 2017 本地數據庫
  • SQL-Server 2017 速成版

我可以毫無錯誤地建構項目,但是當我發布項目時,我在執行下一個命令時收到一個錯誤:

CREATE ASSEMBLY [dbSysmac]
   AUTHORIZATION [dbo]
   FROM 0x5F8A900003000000...
   WITH PERMISSION_SET = UNSAFE;

(47,1):SQL72014:.Net SqlClient 數據提供程序:消息 10327,級別 14,狀態 1,第 1 行為程序集“dbSysmac”創建程序集失敗,因為程序集“dbSysmac”不受信任。當以下任一情況為真時,程序集是受信任的:程序集使用證書或非對稱密鑰簽名,該密鑰具有相應的登錄名並具有 UNSAFE ASSEMBLY 權限,或者程序集使用 sp_add_trusted_assembly 受信任。

我做錯了什麼?

我已經更新了目標數據庫:

 sp_configure 'clr enabled', 1;

需要明確的是,“啟用 clr”sp_configure通常是實例級別的,而不是數據庫級別的配置。

我在 MSSQLTips 文章上遵循了這個建議

哎呀。好吧,關於 MSSQLTips 的那篇文章比您遇到的錯誤更成問題。如果您忘記在那篇文章中看到的所有內容並且再也沒有看過它,那將是最好的。它充滿了不好的建議:

  1. 在 SQL Server Express 中發送電子郵件不需要 SQLCLR (我已經對此進行了測試,它確實有效)。但是,它在 SQL Server Express LocalDB 中不起作用*:-(*

  2. 您應該使用SqlString而不是String輸入參數類型(和返回類型)

  3. 部署到msdb? 也許只有我一個人,但我永遠不會將程式碼部署到msdb(而且我只會在master物理需要時添加程式碼,例如將 proc 標記為啟動 proc 或系統 proc 時)。

  4. UNSAFE權限集?為什麼?對於電子郵件?大會應該是EXTERNAL_ACCESS. 程式碼(程序集、登錄名、使用者或其他任何內容)不應被授予超出必要的權限。

  5. 設置TRUSTWORTHY ONmsdb兩個問題之一:

  6. 設置TRUSTWORTHY ON是懶惰的。當然,可以進行概念驗證/快速測試,但這不是一個好的長期/生產級選項。這是一個巨大的安全風險。相反,應該使用模組簽名。這是我為如何完成此操作編寫的指南,並在 Visual Studio 中執行此操作:

SQLCLR 與 SQL Server 2017,第 2 部分:“CLR 嚴格安全”-解決方案 1 2. TRUSTWORTHY已經ONmsdb。至少它是ON預設的。 6. 輸入@body參數應該是NVARCHAR(MAX),不是NVARCHAR(4000)。畢竟,這是 HTML 電子郵件(即myMessage.IsBodyHtml = True) 7. 不,絕對不要您的純文字電子郵件密碼儲存在 .NET 程式碼中。DLL / 程序集未加密。所有字元串都按原樣儲存在 EXE / DLL / 程序集的末尾。顯示程序集的內容幾乎不費吹灰之力,如果您遵循此建議,您的 SMTP 伺服器、登錄名和密碼將被儲存以供任何人查看。要麼從變數中傳遞它們,要麼執行簡單的查詢以從表中進行選擇。您甚至可以從 Windows 系統資料庫中獲取它們。

您實際發佈到哪個數據庫?假設您要發佈到另一個不是 的數據庫msdb,那麼您至少簡單地說,在這一刻要繼續前進,需要為TRUSTWORTHY ON您要發佈到的數據庫進行設置。但同樣,啟用TRUSTWORTHY只是為了測試(請參閱:請、請、請停止使用模擬、可信和跨數據庫所有權連結)。

現在,如果您ALTER DATABASE...手動執行,然後在發佈時仍然出現錯誤,那麼很可能您選擇了“部署數據庫屬性”選項(在 Visual Studio 中:轉到“項目屬性”|“調試”選項卡 |“部署選項" 底部的區域)。TRUSTWORTHY是這些數據庫屬性之一。因此,當選中“部署數據庫屬性”時,每個部署都會設置選項以匹配項目中定義的內容。並且預設情況下Trustworthy是不啟用的。

您的選擇是:

  1. 如果要部署數據庫屬性:

要在 Visual Studio 中啟用Trustworthy(用於部署):轉到“項目屬性”| “項目設置”選項卡 | “數據庫設置…”按鈕 | “其他”選項卡。選中“可信賴”複選框,然後點擊“確定”按鈕。 2. 如果您不部署數據庫屬性:

TRUSTWORTHY在部署程序集的數據庫中啟用可信賴(啟用msdb不會有幫助) 3. 一旦你在開發中正常工作,在推送到生產之前正確處理安全性:

SQLCLR 與 SQL Server 2017,第 2 部分:“CLR 嚴格安全性” - 解決方案 1

要了解更多關於 SQLCLR 的一般資訊,請訪問:SQLCLR 資訊。請務必查看“Stairway to SQLCLR”連結,這​​是我在 SQL Server Central 上就該主題撰寫的系列文章。

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