共用方式為


CREATE ASSEMBLY (Transact-SQL)

Applies to:SQL ServerAzure SQL Managed Instance

建立一個受控應用程式模組,其中所包含的類別中繼資料和受控碼是 SQL Server 執行個體中的一個物件。 您可以參考這個模組,在資料庫中建立 Common Language Runtime (CLR) 函數、預存程序、觸發程序、使用者定義彙總以及使用者定義型別。

Transact-SQL 語法慣例

Syntax

CREATE ASSEMBLY assembly_name
[ AUTHORIZATION owner_name ]
FROM { <client_assembly_specifier> | <assembly_bits> [ , ...n ] }
[ WITH PERMISSION_SET = { SAFE | EXTERNAL_ACCESS | UNSAFE } ]
[ ; ]
<client_assembly_specifier> ::=
    '[ \\computer_name\ ] share_name\ [ path\ ] manifest_file_name'
    | '[ local_path\ ] manifest_file_name'

<assembly_bits> ::=
{ varbinary_literal | varbinary_expression }

Arguments

assembly_name

組件的名稱。 The name must be unique within the database and a valid identifier.

AUTHORIZATION owner_name

指定身為組件擁有者的使用者或角色的名稱。 owner_name must either be the name of a role of which the current user is a member, or the current user must have IMPERSONATE permission on owner_name. 若未指定,擁有權便歸目前使用者。

<client_assembly_specifier>

指定正在上傳之組件所在的本機路徑或網路位置,以及對應於該組件的資訊清單檔案名稱。 <client_assembly_specifier> 可以使用變數,以固定字串或評估為固定字串的表達式來表示。 CREATE ASSEMBLY 不支援載入多模組元件。 SQL Server 也會在同一個位置尋找這個組件的任何相依組件,同時使用與根層級組件相同的擁有者來上傳這些組件。 如果找不到這些相依元件,而且它們尚未載入目前資料庫中,則 CREATE ASSEMBLY 失敗。 如果相依組件已經載入到目前資料庫中,則那些組件的擁有者,必須與剛建立組件的擁有者一樣。

Important

Azure SQL 資料庫 & Azure SQL 受控執行個體 不支援從檔案建立元件。

<client_assembly_specifier> 如果登入的使用者正在模擬,則無法指定 。

<assembly_bits>

組成元件及其相依元件的二進位值清單。 清單中的第一個值,被視為根層級組件。 對應於相依組件的值,可以採用任何順序提供。 忽略任何未對應至根元件相依性的值。

Note

自主資料庫中無法使用此選項。

varbinary_literal

A varbinary literal.

varbinary_expression

An expression of type varbinary.

PERMISSION_SET { SAFE |EXTERNAL_ACCESS |UNSAFE }

指定 SQL Server 存取時授與元件的一組程式代碼存取許可權。 如果未指定, SAFE 則會套用為預設值。

選項 PERMISSION_SET 會受到 伺服器組態的影響:clr strict 安全性 選項。 當 clr strict security 已啟用時,所有組件會被視為 UNSAFE

建議使用 SAFESAFE 是最嚴格的許可權集合。 具有 SAFE 許可權的元件所執行的程式代碼無法存取外部系統資源,例如檔案、網路、環境變數或登錄。

EXTERNAL_ACCESS 可讓元件存取特定外部系統資源,例如檔案、網路、環境變數和登錄。

UNSAFE 可讓元件不受限制地存取 SQL Server 實例內外的資源。 從元件內 UNSAFE 執行的程式代碼可以呼叫 Unmanaged 程式代碼。

SAFE 是元件的建議許可權設定,這些元件會執行計算和數據管理工作,而不需要存取 SQL Server 實例以外的資源。

Note

自主 EXTERNAL_ACCESS 資料庫中無法使用 和 UNSAFE 選項。

我們建議針對存取 SQL Server 實例外部資源的元件使用 EXTERNAL_ACCESSEXTERNAL_ACCESS 元件包括元件的可靠性與延展性保護 SAFE ,但從安全性觀點來看,與元件類似 UNSAFE 。 元件中的 EXTERNAL_ACCESS 程式代碼預設會在 SQL Server 服務帳戶下執行,並存取該帳戶下的外部資源,除非程式代碼明確模擬呼叫端。 因此,建立元件的許可權 EXTERNAL_ACCESS 應該只授與信任的登入,才能在 SQL Server 服務帳戶下執行程序代碼。 如需仿真的詳細資訊,請參閱 CLR 整合安全性

UNSAFE指定可讓元件中的程式代碼完全自由執行 SQL Server 進程空間中的作業,而這可能會危害 SQL Server 的健全性。 UNSAFE 元件也可能顛覆 SQL Server 或 Common Language Runtime 的安全性系統。 UNSAFE 許可權應該只授與高度信任的元件。 Only members of the sysadmin fixed server role can create and alter UNSAFE assemblies.

For more information about assembly permission sets, see Design assemblies.

不再支援程式碼存取安全性

CLR 使用 .NET Framework 中的程式碼存取安全性 (CAS),而這不再作為安全性界限受支援。 使用 PERMISSION_SET = SAFE 所建立的 CLR 組件可以存取外部系統資源、呼叫非受控程式碼,以及取得系統管理員權限。 在 SQL Server 2017 (14.x) 和更新版本中,sp_configure 安全性選項可增強 CLR 嚴格安全性clr strict security 會依預設啟用,且將 SAFEEXTERNAL_ACCESS 組件視作已標記為 UNSAFE 一樣。 可以基於回溯相容性而停用 clr strict security 選項,但不建議這麼做。

我們建議透過具有已獲授與資料庫中 UNSAFE ASSEMBLY權限master 之對應登入的憑證或非對稱金鑰簽署所有組件。 SQL Server 系統管理員也可以將組件新增至資料庫引擎應該信任的組件清單。 For more information, see sys.sp_add_trusted_assembly.

Remarks

CREATE ASSEMBLY 上傳先前從 Managed 程式代碼編譯為.dll檔案的元件,以在 SQL Server 實例內使用。

啟用時,會在執行階段忽略 PERMISSION_SETCREATE ASSEMBLY 陳述式中的 ALTER ASSEMBLY 選項,但在中繼資料中會保留 PERMISSION_SET 選項。 忽略 選項會將中斷現有的程式代碼語句最小化。

SQL Server 不允許使用相同名稱、文化特性和公鑰註冊不同版本的元件。

嘗試存取 中指定的 <client_assembly_specifier>元件時,SQL Server 會模擬目前 Windows 登入的安全性內容。 如果 <client_assembly_specifier> 指定網路位置 (UNC 路徑),則目前的登入模擬不會因為委派限制而轉送至網路位置。 此時就得利用 SQL Server 服務帳戶的資訊安全內容進行存取。 如需詳細資訊,請參閱認證 (資料引擎)

Besides the root assembly specified by assembly_name, SQL Server tries to upload any assemblies that are referenced by the root assembly being uploaded. 如果因為先前 CREATE ASSEMBLY 的語句而已將參考的元件上傳至資料庫,則不會上傳此元件,但可供根元件使用。 如果先前未上傳相依元件,但 SQL Server 在來源目錄中找不到其指令清單檔, CREATE ASSEMBLY 則傳回錯誤。

如果根元件所參考的任何相依元件尚未存在於資料庫中,而且會與根元件一起隱含載入,則它們具有與根層級元件相同的許可權集合。 如果相依組件必須以與根層級組件不同的權限集合加以建立,必須利用適當的權限集合,在根層級組件之前明確上傳。

Assembly Validation

SQL Server 會掃描 語句上傳的 CREATE ASSEMBLY 元件二進位檔,以確保下列檢查:

  • 組件二進位具有有效的中繼資料和程式碼區段,格式良好,而且程式碼區段也具有有效的 Microsoft 中繼語言 (MSIL) 指示。

  • 它參考的系統元件集合是 SQL Server 中下列其中一個支援的元件:、、、Microsoft.VisualBasic.dllmscorlib.dllSystem.Data.dllSystem.dllSystem.Xml.dllMicrosoft.VisualC.dllCustomMarshallers.dllSystem.Security.dllSystem.Web.Services.dll和 。System.Data.SqlXml.dllSystem.Core.dllSystem.Xml.Linq.dll 也可以參考其他系統組件,但是它們必須在資料庫中明確註冊。

  • 針對使用 SAFEEXTERNAL ACCESS 權限集合所建立的元件:

    • 組件程式碼應該是類型安全的程式碼。 類型安全性是藉由對組件執行 Common Language Runtime 驗證器而完成的。

    • 除非元件標示為唯讀,否則元件不應該在其類別中包含任何靜態數據成員。

    • 元件中的類別不能包含完成項方法。

    • 組件的類別或方法只能以允許的程式碼屬性加以註解。 如需詳細資訊,請參閱 CLR整合:CLR 例程的自訂屬性。

除了先前在執行時 CREATE ASSEMBLY 執行的檢查之外,在元件中的程式代碼運行時間執行額外的檢查:

  • 如果元件的許可權集不包含該許可權,呼叫需要特定程式代碼訪問許可權的特定 .NET Framework API 可能會失敗。

  • 針對 SAFEEXTERNAL_ACCESS 元件,任何呼叫以特定 HostProtectionAttributes 標註的 .NET Framework API 嘗試都失敗。

For more information, see Design assemblies.

Permissions

需要 CREATE ASSEMBLY 權限。

如果 PERMISSION_SET = EXTERNAL_ACCESS 指定 ,則需要 EXTERNAL ACCESS ASSEMBLY 伺服器上的許可權。 如果 PERMISSION_SET = UNSAFE 指定 ,則需要 UNSAFE ASSEMBLY 伺服器上的許可權。

如果任何由即將上傳之組件所參考的組件已經在資料庫中,則使用者必須是這些組件的擁有者才行。 To upload an assembly by using a file path, the current user must be a Windows authenticated login or a member of the sysadmin fixed server role. 執行 CREATE ASSEMBLY 之使用者的 Windows 登入必須具有共用的讀取許可權,以及正在語句中載入的檔案。

使用 CLR 嚴格安全性的權限

啟用 CLR strict security 時,需要有下列權限才能建立 CLR 組件:

  • 使用者必須具有 CREATE ASSEMBLY 權限
  • 而且,下列其中一個條件也必須成立:
    • 組件是使用憑證或非對稱金鑰進行簽署,該金鑰有具有伺服器 UNSAFE ASSEMBLY 權限的對應登入。 建議簽署組件。
    • 資料庫的 TRUSTWORTHY 屬性設定為 ON,而且具有伺服器之 UNSAFE ASSEMBLY 權限的登入擁有資料庫。 不建議使用此選項。

For more information about assembly permission sets, see Design assemblies.

Examples

A. 從 DLL 建立元件

下列範例假設 SQL Server 資料庫引擎 範例會安裝在本機計算機的預設位置,並HelloWorld.csproj編譯範例應用程式。 如需詳細資訊,請參閱 Hello World 範例

CREATE ASSEMBLY HelloWorld
FROM '<system_drive>:\Program Files\Microsoft SQL Server\100\Samples\HelloWorld\CS\HelloWorld\bin\debug\HelloWorld.dll'
WITH PERMISSION_SET = SAFE;

Important

Azure SQL 資料庫 不支援從檔案建立元件。

B. 從元件位建立元件

將範例位(未完成或有效)取代為您的元件位。

CREATE ASSEMBLY HelloWorld
    FROM 0x4D5A900000000000
WITH PERMISSION_SET = SAFE;