Sql-Server

.NET SQLCLR 程序集在 SQL Server 2016 中不起作用(錯誤消息 10314)

  • September 9, 2019

我正在將一個數據庫應用程序從 Windows 2008 R2/SQL Server 2008 R2 遷移到使用第三方 .NET CLR 程序集來解析字元串的 Windows 2012 R2/SQL Server 2016。

我得到的錯誤是:

嘗試載入程序集 id 65540 時,Microsoft .NET Framework 發生錯誤。伺服器可能資源不足,或者程序集可能不受 PERMISSION_SET = EXTERNAL_ACCESS 或 UNSAFE 的信任。再次執行查詢,或查看文件以了解如何解決程序集信任問題。有關此錯誤的更多資訊:

System.IO.FileLoadException:無法載入文件或程序集“clrsplit,版本=0.0.0.0,文化=中性,PublicKeyToken=null”或其依賴項之一。發生與安全有關的錯誤。(來自 HRESULT 的異常:0x8013150A)

System.IO.FileLoadException:在 System.Reflection.RuntimeAssembly._nLoad(AssemblyName 文件名、字元串程式碼庫、證據 assemblySecurity、RuntimeAssembly locationHint、StackCrawlMark 和 stackMark、IntPtr pPrivHostBinder、布爾 throwOnFileNotFound、布爾 forIntrospection、布爾suppressSecurityChecks)在 System.Reflection.RuntimeAssembly.InternalLoadAssemblyName (AssemblyName assemblyRef,證據 assemblySecurity,RuntimeAssembly reqAssembly,StackCrawlMark 和 stackMark,IntPtr pPrivHostBinder,布爾 throwOnFileNotFound,Boolean forIntrospection,Boolean suppressSecurityChecks)在 System.Reflection.RuntimeAssembly.InternalLoad(字元串 assemblyString,證據 assemblySecurity,StackCrawlMark 和 stackMark,IntPtr pPrivHostBinder,布爾 forIntrospection) System.Reflection.RuntimeAssembly。System.Reflection.Assembly.Load(String assemblyString) 處的 InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark & stackMark, Boolean forIntrospection)

$$ SQLSTATE 42000 $$(錯誤 10314)。

錯誤:10314,嚴重性:16,狀態:11。

設置了數據庫 TRUSTWORTHY 位:

name             is_trustworthy_on
msdb             1
SimplusStaging   1

PERMISSION_SET設置為UNSAFE。裝配標記為不安全,因為這些是供應商安裝說明。已嘗試刪除程序集和相關的 T-SQL 對象並重新創建它們。不用找了。DBO 使用者是 SA 登錄名。而且,這是我們用於此數據庫/伺服器的唯一 CLR 程序集。

這是使用分離/附加的新安裝。是否安裝了KB2919355,否則 SQL Server 2016 將無法安裝。

我很想STRING_SPLIT在 2016 年使用新功能,只是該應用程序由第三方支持,並且他們為 2008 R2 建構了所有內容。想要利用 2016 年的一些新功能,“它執行得更快”。

原始安裝和新安裝的數據庫所有者的 SID 相同。0x01在問題數據庫的上下文中執行時,以下兩個查詢都會返回:

SELECT [sid] FROM sys.database_principals WHERE [name] = N'dbo';
SELECT [owner_sid] FROM sys.databases WHERE [database_id] = DB_ID();

我是否需要為新的 .Net Framework 重新編譯 CLR 程序集,還是應該正常工作?

在 Windows 2008 R2 上執行相同的遷移到 SQL 2012 和 2014 沒有問題。

以下形式的錯誤:

消息 10314,級別 16,狀態 11,第 1 行

嘗試載入程序集 ID ##### 時,Microsoft .NET Framework 中發生錯誤。伺服器可能資源不足,或者程序集可能不受 PERMISSION_SET = EXTERNAL_ACCESS 或 UNSAFE 的信任。再次執行查詢,或查看文件以了解如何解決程序集信任問題。有關此錯誤的詳細資訊:

System.IO.FileLoadException: 無法載入文件或程序集“{assembly_name}, Version=#.#.#.#, Culture=neutral, PublicKeyToken=xxxxxxxxxxxxxxxx”或其依賴項之一。發生與安全有關的錯誤。(來自 HRESULT 的異常:0x8013150A)

表示程序集,目前標記為 aPERMISSION_SET或不允許使用該權限級別,直到 SQLCLR 權限設置的第二部分得到處理。第二部分是執行以下操作之一EXTERNAL_ACCESS``UNSAFE

  • 非常首選的方法

    1. 編譯時對程序集簽名(並給它一個密碼!)。這有時被稱為給它一個強名稱。

    如果程序集沒有簽名,並且您沒有重新編譯它的原始碼,並且沒有任何其他程序集引用它,那麼您仍然可以按照前半部分的說明對其進行簽名博文:http: //ianpicknell.blogspot.com/2009/12/adding-strong-name-to-third-party.html 2. [master]從該程序集的 DLL創建一個非對稱密鑰 3. 從該非對稱密鑰創建登錄 4. 授予該登錄這兩個權限之一:EXTERNAL ACCESS ASSEMBLYUNSAFE ASSEMBLY(該UNSAFE ASSEMBLY權限還允許將程序集標記為EXTERNAL_ACCESS,因此您不需要這兩個權限) 5. 在它應該存在的任何數據庫中創建程序集 6. 不要將TRUSTWORTHY包含此程序集的數據庫的屬性設置為ON. TRUSTWORTHY可以保持為OFF

  • 非首選方法

    1. 將程序集應該存在的數據庫更改為TRUSTWORTHY ON
    2. 確保包含此程序集的數據庫所有者的登錄具有以下兩種權限之一:EXTERNAL ACCESS ASSEMBLYUNSAFE ASSEMBLY

    如果 Database(s) 的所有者是sa或任何其他位於sysadmin固定伺服器角色中的登錄名,那麼您無需擔心顯式設置這兩個權限之一,因為它們是sysadmin角色所暗示的。 3. 如果可能的話,盡量避免這種方法:-)

由問題作者的評論生成的社區 Wiki 答案

找到了答案。事實證明,CLR 程序集被用於 2 個不同的數據庫中。需要確保兩者都打開了可信賴的位。此外,它顯然在做字元串拆分以外的事情,因為我需要創建程序集,UNSAFE因為它說它不能使用部分受信任的呼叫者。

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