An Overview Of CLR Database Procedures In C#

Introduction

In this article, we will learn about CLR database procedures in C#. Let’s discuss CLR database stored procedure.

Description

Why use CLR procedures instead of T-SQL procedures & functions.

  • If you'd prefer to write the code in (VB.Net, C#, etc.) rather than SQL.
  • If you want to do complex operations on data in CLR.
  • If you want to be close to the data (i.e. not in ASP.NET or a WinForms app etc.)
  • The CLR has RegEx but SQL does not. 
  • You can call web services in CLR, but you can't in T-SQL.
  • The CLR has better performance (if you had to do a lot of math on every row, for example).
  • You can re-use code.

CLR Stored Procedures

This article will show how to create four types of CLR database stored procedures:

  • A stored procedure that returns a result set
  • A stored procedure that returns an output parameter, message, and returns code
  • A stored procedure that returns a dynamically created result set with a single row
  • A stored procedure that returns a dynamically created result set containing multiple rows.

Let’s see CLR stored procedures practically,

Step 1

Create a library project (CLR Procedures) in Visual Studio as below.

C#

Create one class files “CLRDynamicProcedures.cs”.

In file “CLRDynamicProcedures.cs” add the below lines of code.

  1. using Microsoft.SqlServer.Server;  
  2. using System.Data;  
  3. using System.Data.SqlClient;  
  4.   
  5. namespace CLRProcedures  
  6. {  
  7.     public class CLRDynamicProcedures  
  8.     {  
  9.         [SqlProcedure]  
  10.         public static void GetUsers()  
  11.         {  
  12.             using (SqlConnection connection = new SqlConnection("context connection=true"))  
  13.             {  
  14.                 connection.Open();  
  15.                 SqlCommand cmd = new SqlCommand(@"SELECT * FROM [dbo].[Users]", connection);  
  16.                 SqlContext.Pipe.ExecuteAndSend(cmd);  
  17.             }  
  18.         }  
  19.   
  20.         [SqlProcedure]  
  21.         public static int SpOutputParameter_Message_ReturnCode(string emailAddress, out int outVal)  
  22.         {  
  23.             outVal = 10;  
  24.   
  25.             using (SqlConnection connection = new SqlConnection("context connection=true"))  
  26.             {  
  27.                 connection.Open();  
  28.                 SqlCommand cmd = new SqlCommand(@"SELECT COUNT(*) FROM [dbo].[Users] WHERE EmailAddress=@EmailAddress", connection);  
  29.                 SqlParameter modifiedSinceParam = cmd.Parameters.Add("@EmailAddress", SqlDbType.NVarChar);  
  30.                 modifiedSinceParam.Value = emailAddress;  
  31.                 int userCount = (int)cmd.ExecuteScalar();  
  32.                 SqlContext.Pipe.Send(string.Format("Total number of users having email address {0} is {1}", emailAddress, userCount));  
  33.             }  
  34.   
  35.             return 5;  
  36.         }  
  37.   
  38.         [SqlProcedure]  
  39.         public static void GetUserByUserID(int userID)  
  40.         {  
  41.             SqlMetaData[] md = new SqlMetaData[2];  
  42.             md[0] = new SqlMetaData("UserID", SqlDbType.Int);  
  43.             md[1] = new SqlMetaData("EmailAddress", SqlDbType.NVarChar, 150);  
  44.             SqlDataRecord row = new SqlDataRecord(md);  
  45.             using (SqlConnection connection = new SqlConnection("context connection=true"))  
  46.             {  
  47.                 connection.Open();  
  48.                 SqlCommand cmd = new SqlCommand(@"SELECT TOP 1 UserID,EmailAddress FROM [dbo].[Users] WHERE UserID=@UserID", connection);  
  49.                 SqlParameter modifiedSinceParam = cmd.Parameters.Add("@UserID", SqlDbType.NVarChar);  
  50.                 modifiedSinceParam.Value = userID;  
  51.                 using (SqlDataReader reader = cmd.ExecuteReader())  
  52.                 {  
  53.                     while (reader.Read())  
  54.                     {  
  55.                         row.SetSqlInt32(0, (int)reader.GetSqlInt32(0));  
  56.                         row.SetSqlString(1, (string)reader.GetSqlString(1));  
  57.                     }  
  58.                 }  
  59.             }  
  60.             SqlContext.Pipe.Send(row);  
  61.         }  
  62.   
  63.         [SqlProcedure]  
  64.         public static void GetUsersByEmail(string emailAddress)  
  65.         {  
  66.             SqlMetaData[] md = new SqlMetaData[2];  
  67.             md[0] = new SqlMetaData("UserID", SqlDbType.Int);  
  68.             md[1] = new SqlMetaData("EmailAddress", SqlDbType.NVarChar, 150);  
  69.             SqlDataRecord row = new SqlDataRecord(md);  
  70.             SqlContext.Pipe.SendResultsStart(row);  
  71.   
  72.             using (SqlConnection connection = new SqlConnection("context connection=true"))  
  73.             {  
  74.                 connection.Open();  
  75.                 SqlCommand cmd = new SqlCommand(@"SELECT UserID,EmailAddress FROM [dbo].[Users] WHERE EmailAddress=@EmailAddress", connection);  
  76.                 SqlParameter modifiedSinceParam = cmd.Parameters.Add("@EmailAddress", SqlDbType.NVarChar);  
  77.                 modifiedSinceParam.Value = emailAddress;  
  78.                 using (SqlDataReader reader = cmd.ExecuteReader())  
  79.                 {  
  80.                     while (reader.Read())  
  81.                     {  
  82.                         row.SetSqlInt32(0, (int)reader.GetSqlInt32(0));  
  83.                         row.SetSqlString(1, (string)reader.GetSqlString(1));  
  84.                         SqlContext.Pipe.SendResultsRow(row);  
  85.                     }  
  86.                 }  
  87.             }  
  88.   
  89.             SqlContext.Pipe.SendResultsEnd();  
  90.         }  
  91.     }  
  92. }  

Step 2

Open project property and set output path= C:\dlls as below,

C#

Step 3

Build or compile library project and verify the dll copied in output folder (C:\dlls).

Step 4

Open new query window for the targeted database in MSSQL Server Management Studio and add below SQL statement in a query window to create “Users” table with some data.

  1. CREATE TABLE [dbo].[Users](  
  2.     [UserID] [int] IDENTITY(1,1) NOT NULL,  
  3.     [UserName] [nvarchar](200) NOT NULL,  
  4.     [RealName] [nvarchar](200) NOT NULL,  
  5.     [EmailAddress] [varchar](150) NULL,  
  6.     [ModifiedDate] [dateNULL,  
  7.  CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED   
  8. (  
  9.     [UserID] ASC  
  10. )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ONON [PRIMARY]  
  11. ON [PRIMARY]  
  12.   
  13. GO  
  14. SET ANSI_PADDING OFF  
  15. GO  
  16. SET IDENTITY_INSERT [dbo].[Users] ON   
  17.   
  18. INSERT [dbo].[Users] ([UserID], [UserName], [RealName], [EmailAddress], [ModifiedDate]) VALUES (44, N'dinesh.singh', N'Dinesh', N'[email protected]'CAST(N'2018-05-15' AS Date))  
  19. INSERT [dbo].[Users] ([UserID], [UserName], [RealName], [EmailAddress], [ModifiedDate]) VALUES (45, N'ramesh.singh', N'Ramesh', N'[email protected]'CAST(N'2018-05-15' AS Date))  
  20. SET IDENTITY_INSERT [dbo].[Users] OFF  

Step 5

Let’s create a CLR database stored procedure that returns a result set.

Open SQL management studio query window and write & execute below SQL statement to create the stored procedure:

  1. CREATE PROCEDURE CLRGetUsers  
  2. AS EXTERNAL NAME StoredProcedures.[CLRProcedures.CLRDynamicProcedures].GetUsers  

Note
At First, Run creates an assembly statement; after that run create procedure statement don’t run both at the same time otherwise you will get an error as below.

C#

Let’s see whether CLR database assembly and procedure are created in SQL database object explorer or not.

C#

From the above screen, CLR assembly and procedure have been created in SQL database. Now, let’s run the created CLR procedure “CLRGetUsers” and see the output.

C#

Now, you can see we are getting results from SQL database through CLR stored procedure “CLRGetUsers”.

Step 5

Let’s create a CLR database stored procedure that returns an output parameter, message, and returns code.

Open SQL management studio query window and write & execute below SQL statement to create stored procedure:

  1. CREATE PROCEDURE CLRSpOutputParameter_Message_ReturnCode @emailAddress nvarchar(50), @outVal int OUT  
  2. AS EXTERNAL NAME StoredProcedures.[CLRProcedures.CLRDynamicProcedures].  
  3. SpOutputParameter_Message_ReturnCode  

Let’s see whether CLR database procedure is created in SQL database object explorer or not.

C#

Now, it is clear that procedure has created. Let's execute the procedure.

C#

Now, you can see we are getting results from SQL database through CLR stored procedure “CLRSpOutputParameter_Message_ReturnCode”.

Step 6

Let’s create a CLR database stored procedure that returns a dynamically created result set with a single row.

Open SQL management studio query window and write & execute below SQL statement to create the stored procedure:

  1. CREATE PROCEDURE CLRGetUserByUserID @userID int  
  2. AS EXTERNAL NAME StoredProcedures.[CLRProcedures.CLRDynamicProcedures].GetUserByUserID  

Let’s see whether CLR database procedure has created in SQL database object explorer or not.

C#

Now, it is clear that procedure has created. Let’s execute this procedure.

C#

Now, you can see we are getting results from SQL database through CLR stored procedure “CLRGetUserByUserID”.

Step 7

Let’s create a CLR database stored procedure that returns a dynamically created result set containing multiple rows.

Open SQL management studio query window and write & execute below SQL statement to create the stored procedure:

  1. CREATE PROCEDURE CLRGetUsersByEmail @emailAddress nvarchar(150)  
  2. AS EXTERNAL NAME StoredProcedures.[CLRProcedures.CLRDynamicProcedures].GetUsersByEmail  

Let’s see whether CLR database procedure has created in SQL database object explorer or not.

C#

Now, it is clear that procedure has created. Let’s execute this procedure.

C#

Now, you can see we are getting results from SQL database through CLR stored procedure “CLRGetUsersByEmail”.

Points of interest

If you are getting an error as below while executing CLR database stored procedure:

C#

Then you must run below SQL statement to enable CLR.

  1. sp_configure 'show advanced options', 1;    
  2. GO    
  3. RECONFIGURE;    
  4. GO    
  5. sp_configure 'clr enabled', 1;    
  6. GO    
  7. RECONFIGURE;    
  8. GO    

You can run CLR procedure successfully.

To disable CLR integration, use the clr enabled option of the sp_configure stored procedure.

  1. sp_configure 'show advanced options', 1;    
  2. GO    
  3. RECONFIGURE;    
  4. GO    
  5. sp_configure 'clr enabled', 0;    
  6. GO    
  7. RECONFIGURE;    
  8. GO    

To un-install CLR database procedure you must write & execute below SQL statement in MSSQL server management studio query window.

  1. IF EXISTS (SELECT name FROM sysobjects WHERE name = 'CLRGetUsers')    
  2.    DROP PROCEDURE CLRGetUsers  
  3.   
  4. IF EXISTS (SELECT name FROM sysobjects WHERE name = 'CLRSpOutputParameter_Message_ReturnCode')    
  5.    DROP PROCEDURE CLRSpOutputParameter_Message_ReturnCode  
  6.   
  7. IF EXISTS (SELECT name FROM sysobjects WHERE name = 'CLRGetUserByUserID')    
  8.    DROP PROCEDURE CLRGetUserByUserID  
  9.   
  10. IF EXISTS (SELECT name FROM sysobjects WHERE name = 'CLRGetUsersByEmail')    
  11.    DROP PROCEDURE CLRGetUsersByEmail  

To un-install CLR database assembly you must write & execute below SQL statement in the MSSQL server management studio query window.

  1. IF EXISTS (SELECT name FROM sys.assemblies WHERE name = 'StoredProcedures')    
  2.    DROP ASSEMBLY StoredProcedures   

Congratulations --  you have successfully created, installed and uninstalled CLR database stored procedures. If you have any query or concern just do let me know or just put in the comment box and I will respond as soon as possible. I am open to discussing anything even silly questions as well. If you have any suggestions related to this article, please let me know and  I promise I will improve this article to a maximum level. 

Summary

In this article, we have learned how to create, install and uninstall CLR database stored procedure and assembly in C#.

G
M
T
 
Text-to-speech function is limited to 200 characters


Similar Articles