Designing assemblies

Applies to: SQL Server

This article describes the following factors you should consider when you design assemblies:

  • Packaging assemblies
  • Managing assembly security
  • Restrictions on assemblies

Package assemblies

An assembly can contain functionality for more than one SQL Server routine or type in its classes and methods. Most of the time, it makes sense to package the functionality of routines that perform related functions within the same assembly, especially if these routines share classes whose methods call one another. For example, classes that perform data entry management tasks for common language runtime (CLR) triggers and CLR stored procedures can be packaged in the same assembly. This is because the methods for these classes are more likely to call each other than methods of less related tasks.

When you're packaging code into assembly, consider:

  • CLR user-defined types and indexes that depend on CLR user-defined functions can cause persisted data to be in the database that depends on the assembly. Modifying the code of an assembly is frequently more complex when there's persisted data that depends on the assembly in the database. Therefore, it's better to separate code on which persisted data dependencies rely (such as user-defined types and indexes using user-defined functions) from code that doesn't have these persisted data dependencies. For more information, see Implementing assemblies and ALTER ASSEMBLY (Transact-SQL).

  • If a piece of managed code requires higher permission, it's better to separate that code into a separate assembly from code that doesn't require higher permission.

Manage assembly security

You can control how much an assembly can access resources protected by .NET Code Access Security when it runs managed code. You do this by specifying one of three permission sets when you create or modify an assembly: SAFE, EXTERNAL_ACCESS, or UNSAFE.

SAFE permission

SAFE is the default permission set and it's the most restrictive. Code run by an assembly with SAFE permissions can't access external system resources such as files, the network, environment variables, or the registry. SAFE code can access data from the local SQL Server databases or perform computations and business logic that don't involve accessing resources outside the local databases.

Most assemblies perform computation and data management tasks without having to access resources outside SQL Server. Therefore, we recommend SAFE as the assembly permission set.

EXTERNAL_ACCESS permission

EXTERNAL_ACCESS allows for assemblies to access certain external system resources such as files, networks, Web services, environmental variables, and the registry. Only SQL Server logins with EXTERNAL ACCESS permissions can create EXTERNAL_ACCESS assemblies.

SAFE and EXTERNAL_ACCESS assemblies can contain only code that is verifiably type-safe. This means that these assemblies can only access classes through well-defined entry points that are valid for the type definition. Therefore, they can't arbitrarily access memory buffers not owned by the code. Additionally, they can't perform operations that might have an adverse effect on the robustness of the SQL Server process.

UNSAFE permission

UNSAFE gives assemblies unrestricted access to resources, both within and outside SQL Server. Code that is running from within an UNSAFE assembly can call unmanaged code.

Also, specifying UNSAFE allows for the code in the assembly to perform operations that are considered type-unsafe by the CLR verifier. These operations can potentially access memory buffers in the SQL Server process space in an uncontrolled manner. UNSAFE assemblies can also potentially subvert the security system of either SQL Server or the common language runtime. UNSAFE permissions should be granted only to highly trusted assemblies by experienced developers or administrators. Only members of the sysadmin fixed server role can create UNSAFE assemblies.

Restrictions on assemblies

SQL Server puts certain restrictions on managed code in assemblies to make sure that they can run in a reliable and scalable manner. This means that certain operations that can compromise the robustness of the server aren't permitted in SAFE and EXTERNAL_ACCESS assemblies.

Disallowed custom attributes

Assemblies can't be annotated with the following custom attributes:

System.ContextStaticAttribute
System.MTAThreadAttribute
System.Runtime.CompilerServices.MethodImplAttribute
System.Runtime.CompilerServices.CompilationRelaxationsAttribute
System.Runtime.Remoting.Contexts.ContextAttribute
System.Runtime.Remoting.Contexts.SynchronizationAttribute
System.Runtime.InteropServices.DllImportAttribute
System.Security.Permissions.CodeAccessSecurityAttribute
System.STAThreadAttribute
System.ThreadStaticAttribute

Additionally, SAFE and EXTERNAL_ACCESS assemblies can't be annotated with the following custom attributes:

System.Security.SuppressUnmanagedCodeSecurityAttribute
System.Security.UnverifiableCodeAttribute

Disallowed .NET Framework APIs

Any Microsoft .NET Framework API that is annotated with one of the disallowed HostProtectionAttributes can't be called from SAFE and EXTERNAL_ACCESS assemblies.

eSelfAffectingProcessMgmt
eSelfAffectingThreading
eSynchronization
eSharedState
eExternalProcessMgmt
eExternalThreading
eSecurityInfrastructure
eMayLeakOnAbort
eUI

Supported .NET Framework assemblies

Any assembly that is referenced by your custom assembly must be loaded into SQL Server by using CREATE ASSEMBLY. The following .NET Framework assemblies are already loaded into SQL Server and, therefore, can be referenced by custom assemblies without having to use CREATE ASSEMBLY.

  • CustomMarshalers.dll
  • Microsoft.VisualBasic.dll
  • Microsoft.VisualC.dll
  • mscorlib.dll
  • System.dll
  • System.Configuration.dll
  • System.Core.dll
  • System.Data.dll
  • System.Data.OracleClient.dll
  • System.Data.SqlXml.dll
  • System.Deployment.dll
  • System.Security.dll
  • System.Transactions.dll
  • System.Web.Services.dll
  • system.Xml.dll
  • System.Xml.Linq.dll