CLR Integration With MS SQL Server
CLR Integration With MS SQL Server
the
Query
window,
type
the
following:
create
new
database
and
table,
type
-- ===================================================
-- Database:
CeilInn5
-- ===================================================
IF EXISTS(SELECT name FROM sys.databases
WHERE name = N'CeilInn5')
DROP DATABASE CeilInn5;
GO
CREATE DATABASE CeilInn5;
GO
USE CeilInn5;
GO
IF OBJECT_ID(N'Employees', N'U') IS NOT NULL
DROP TABLE Employees
GO
CREATE TABLE Employees
(
EmployeeNumber int NOT NULL,
DateHired date NULL,
FirstName nvarchar(20),
LastName nvarchar(20) NOT NULL,
HourlySalary money
);
GO
INSERT INTO Employees
VALUES(62480, N'19981025',
(35844, N'20060622',
(24904, N'20011016',
(48049, N'20090810',
(25805, N'20040310',
(58405, N'19950616',
GO
the
following:
VALUES(N'104');
GO
INSERT INTO Rooms(RoomNumber, BedType, Rate, Available)
VALUES(N'105', N'King', 95.50, 1),
(N'106', N'King', 95.50, 1);
GO
INSERT INTO Rooms(RoomNumber, Available)
VALUES(N'107', 1);
GO
INSERT INTO Rooms(RoomNumber, BedType, Rate)
VALUES(N'108', N'King', 95.50);
GO
INSERT INTO Rooms(RoomNumber, Available)
VALUES(N'109', 1);
GO
INSERT INTO Rooms(RoomNumber, RoomType, Rate, Available)
VALUES(N'108', N'Conference Roome', 450, 1),
(N'110', N'Conference Roome', 650, 1);
GO
INSERT INTO Rooms(RoomNumber, BedType, Rate, Available)
VALUES(N'201', N'Queen', 90, 1),
(N'202', N'Queen', 90, 1),
(N'203', N'Queen', 90, 1),
(N'205', N'King', 98.85, 1),
(N'207', N'King', 98.75, 1);
GO
6. To execute, press F5
CLR Fundamentals
As stated already, to provide CLR integration, you will write your code in a language that supports the
.NET Framework. This means that the language will use classes available from that library.
The .NET Framework primarily supports databases through an object called a data set. This object is
represented by a class named DataSet. In reality, a data set is a group of lists, like the tables of a
Microsoft SQL Server database. Normally, a data set by itself means nothing. It is the objects (tables)
it contains that define it.
To support tables, the .NET Framework provides a class named DataTable. As you know already, a
table is made of columns and records. The columns of a table are supported in the .NET Framework by
a class named DataColumn. A record of a table is represented in the .NET Framework by a class
named DataRow. All these classes are defined in a namespace named System.Data. The
System.Data namespace is created in the System.Data.dll assembly. This means you will need this
library in your project.
To provide support for Microsoft SQL Server databases, the .NET Framework provides the
System.Data.Sql and the System.Data.SqlClient namespaces. Both namespaces are defined in the
System.Data.dll library.
The System.Data.Sql contains classes that specifically support Microsoft SQL Server.
The System.Data.SqlClient namespace contains classes used to establish a connection to a server,
create commands to a database, execute the desired commands, or read data from database objects
(tables, views, etc). To use a Microsoft SQL Server database, you will usually need to reference the
System.Data.SqlClient namespace. Otherwise, you can use a technology named OLEDB. In this case,
you would use System.Data.OleDb.
One of the primary requirements of a database system is that of data types. The .NET Framework data
types that support, or are equivalent to, Microsoft SQL Server types are defined in the
System.Data.SqlTypes namespace. This namespace contains various classes and structures that
each provides an equivalent to a Microsoft SQL Server data type. Here are the data types we started
bit
SqlBoolean
tinyint
SqlByte
smallint
SqlInt16
int
SqlIn32
bigint
SqlInt64
GUID
SqlGuid
float, real
SqlSingle
decimal, numeric
SqlDecimal, SqlDouble
money, smallmoney
SqlMoney
date,
time,
datetime,
smalldatetime, datetimeoffset
datetime2,
SqlDateTime
FILESTREAM
SqlFileStream
binary, varbinary
SqlBinary
xml
SqlXml
The System.Data.SqlTypes namespace contains many other structures you can use to implement
functionality available from object-oriented languages but not directly available in Microsoft SQL
Server:
SqlBytes: This class can be used to create a reference to a stream of values
SqlChars: This class can be used for an array of characters
SqlTruncateException: This exception is thrown if you use an incompatible value that must be
truncated
SqlNullValueException: This exception is thrown if the value of a variable is set to null (C#) or
Nothing (Visual Basic)
The System.Data.SqlTypes namespace is defined in the System.Data.dll assembly.
To provide additional functionality of a Microsoft SQL Server database, the .NET Framework provides
the System.Data.Sql namespace. This namespace is also part of the System.Data.dll library.
Equipped with all these data types, classes, and your knowledge, you can implement the functionality
appropriate to integrate your code with a Microsoft SQL Server database. To assist you with the
necessary classes for this integration, the .NET Framework provides the Microsoft.SqlServer.Server
namespace that is equipped with various interfaces, classes, and enumerations. To use one of the
classes of this namespace, you can reference it using an attribute.
The C++, Visual Basic, Pascal, Transact-SQL and many other languages support the concept of
functions. Some other languages like C# or Java don't share that concept. They use only the word
"method". Here, we will use the word function in the first sense. Because we will write our code in C#,
we have to create classes and use methods.
tree
view,
expand
Visual
C#
if
necessary.
the
Name
text
box,
replace
the
string
with
CeilInn
6. To save the project, on the Standard toolbar, click the Save button
7. Set the Name to CeilInn1
8. Set the Location to C:\
9. Uncheck
Create
Directory
For
Solution
Ctrl
16. Click OK
17. In the Solution Explorer, right-click CeilInn1 -> Add -> New Item...
18. In the Templates list, click Code File
19. Set
the
Name
to
CeilInn
21. In
the
Code
Editor,
type
the
using System;
using Microsoft.SqlServer.Server;
public class Payroll
{
[Microsoft.SqlServer.Server.SqlFunction]
public static void Calculate(decimal Week1Time,
decimal Week2Time,
decimal HourlySalary,
out decimal RegularTime,
out decimal RegularPay,
out decimal Overtime,
out decimal OvertimePay,
out decimal TotalEarnings)
{
decimal overtimeSalary = 0.00M;
decimal week1RegularTime = 0.00M;
decimal week1RegularPay = 0.00M;
decimal week1Overtime = 0.00M;
decimal week1OvertimePay = 0.00M;
decimal week2RegularTime = 0.00M;
decimal week2RegularPay = 0.00M;
decimal week2Overtime = 0.00M;
decimal week2OvertimePay = 0.00M;
// The overtime is paid time and half
overtimeSalary = HourlySalary * 1.5M;
// If the employee worked under 40 hours, there is no overtime
if (Week1Time < 40)
{
week1RegularTime = Week1Time;
week1RegularPay = HourlySalary * week1RegularTime;
week1Overtime = 0M;
week1OvertimePay = 0M;
}
// If the employee worked over 40 hours, calculate the overtime
else if (Week1Time >= 40)
{
week1RegularTime = 40M;
week1RegularPay = HourlySalary * 40M;
week1Overtime = Week1Time - 40M;
week1OvertimePay = week1Overtime * overtimeSalary;
}
if (Week2Time < 40)
{
week2RegularTime = Week2Time;
week2RegularPay = HourlySalary * week2RegularTime;
week2Overtime
= 0M;
week2OvertimePay = 0M;
}
else if (Week2Time >= 40)
{
week2RegularTime = 40;
week2RegularPay = HourlySalary * 40M;
week2Overtime
= Week2Time - 40M;
week2OvertimePay = week2Overtime * overtimeSalary;
}
following:
2. Select the whole code you previously wrote and press Delete
3. To create an assembly to import the function, type the following (change the path based on the
Location
where
you
created
the
project
in:
USE CeilInn5;
GO
CREATE ASSEMBLY PayrollProcessing
FROM N'C:\CeilInn1\bin\Release\CeilInn1.dll'
WITH PERMISSION_SET = SAFE;
GO
4. Press
F5
to
Make sure you get a message that the Command(s) Completed Successfully
execute.
F5
to
execute
Week 1:
42.50
Week 2:
36.00
Hourly Salary: 25.85
Regular Time:
76.00
Regular Pay:
1964.60
Overtime:
2.50
Overtime Pay:
96.94
Total Earnings: 2061.54
------------------------
Stored Procedures
Besides functions, the CLR allows you to create stored procedures. To support them, the .NET
Framework provides the SqlProcedure class defined in the Microsoft.SqlServer.Server
namespace. To use this class, create a static method but mark it with the
Microsoft.SqlServer.Server.SqlProcedure attribute. As mentioned already, you can specify
the optional name in the parentheses. Name is the only option of the procedure attribute.
System;
System.Data.SqlTypes;
System.Data.SqlClient;
Microsoft.SqlServer.Server;
GO
/*
CREATE ASSEMBLY GetRoomInformation
FROM N'C:\RoomInformation1\bin\Release\RoomInformation1.dll'
WITH PERMISSION_SET = SAFE;
GO
CREATE PROCEDURE ShowRoomInfo(@RmNumber nvarchar(100) OUTPUT,
@Criterion nvarchar(10))
AS EXTERNAL NAME GetRoomInformation.RoomInfo.GetInformation;
GO
*/
DECLARE @RoomResult nvarchar(100);
EXECUTE ShowRoomInfo @RoomResult output, N'108';
SELECT @RoomResult AS 'Room Information';
GO
31. Press F5 to execute
Triggers
The .NET Framework provides support for triggers through the SqlTriggerContext class.
If you had created a trigger in the database you want to work on, the
Microsoft.SqlServer.Server.SqlTriggerContext class allows you
to get information about a trigger that occurred such as the reason
for the trigger and the column(s) that was(were) affected on the table(s).