--- title: "Overview of CLR Integration Custom Attributes | Microsoft Docs" ms.custom: "" ms.date: "06/13/2017" ms.prod: "sql-server-2014" ms.reviewer: "" ms.technology: "database-engine" ms.topic: "reference" helpviewer_keywords: - "custom attributes [CLR integration]" - "attributes [CLR integration]" - "common language runtime [SQL Server], attributes" - "database objects [CLR integration], custom attributes" - "building database objects [CLR integration], custom attributes" ms.assetid: ecf5c097-0972-48e2-a9c0-b695b7dd2820 author: mashamsft ms.author: mathoma manager: craigg --- # Overview of CLR Integration Custom Attributes The common language runtime (CLR) of the [!INCLUDE[dnprdnshort](../../includes/dnprdnshort-md.md)] allows the use of descriptive keywords, called attributes. These attributes provide additional information for many elements, such as methods and classes. The attributes are saved in the assembly with the metadata of the object, and can be used to describe your code to other development tools or to affect runtime behavior inside [!INCLUDE[ssNoVersion](../../includes/ssnoversion-md.md)]. When you register a CLR routine with [!INCLUDE[ssNoVersion](../../includes/ssnoversion-md.md)], [!INCLUDE[ssNoVersion](../../includes/ssnoversion-md.md)] derives a set of properties about the routine. These routine properties determine the capabilities of the routine, including whether the routine can be indexed. For example, setting the `DataAccess` property to `DataAccessKind.Read` lets you access data from [!INCLUDE[ssNoVersion](../../includes/ssnoversion-md.md)] user tables inside a CLR function. The following example shows a simple case in which the `DataAccess` property is set to facilitate data access from a user table **table1**. ```csharp using System; using System.Data; using System.Data.Sql; using System.Data.SqlTypes; using Microsoft.SqlServer.Server; using System.Data.SqlClient; public partial class UserDefinedFunctions { [SqlFunction(DataAccess = DataAccessKind.Read)] public static string func1() { // Open a connection and create a command SqlConnection conn = new SqlConnection("context connection = true"); conn.Open(); SqlCommand cmd = conn.CreateCommand(); cmd.CommandText = "SELECT str_val FROM table1 WHERE int_val = 10"; // where table1 is a user table // Execute this command SqlDataReader rd = cmd.ExecuteReader(); // Set string ret_val to str_val returned from the query string ret_val = rd.GetValue(0).ToString(); rd.Close(); return ret_val; } } ``` ```vb Imports System Imports System.Data Imports System.Data.Sql Imports System.Data.SqlTypes Imports Microsoft.SqlServer.Server Imports System.Data.SqlClient Public partial Class UserDefinedFunctions _ Public Shared Function func1() As String ' Open a connection and create a command Dim conn As SqlConnection = New SqlConnection("context connection = true") conn.Open() Dim cmd As SqlCommand = conn.CreateCommand() cmd.CommandText = "SELECT str_val FROM table1 WHERE int_val = 10" ' where table1 is a user table ' Execute this command Dim rd As SqlDataReader = cmd.ExecuteReader() ' Set string ret_val to str_val returned from the query Dim ret_val As String = rd.GetValue(0).ToString() rd.Close() Return ret_val End Function End Class ``` For [!INCLUDE[tsql](../../includes/tsql-md.md)] routines, [!INCLUDE[ssNoVersion](../../includes/ssnoversion-md.md)] derives routine properties directly from the routine definition. For CLR routines, the server does not analyze the body of the routine to derive these properties. Instead, you can use custom attributes for classes and class members implemented in a [!INCLUDE[dnprdnshort](../../includes/dnprdnshort-md.md)] language. The custom attributes needed for CLR routines, user-defined types, and aggregates are defined in the `Microsoft.SqlServer.Server` namespace. ## See Also [Custom Attributes for CLR Routines](../../relational-databases/clr-integration/database-objects/clr-integration-custom-attributes-for-clr-routines.md)