4. To my son, Derek Steven Comingore, and the next generation
of programmers.
—Derek Comingore
To Misty, Mariah, and Kyle, for your love, support, and patience.
—Douglas Hinson
5. About the Authors
Derek Comingore is an independent consultant, trainer, and speaker specializing in SQL Server and .NET
technologies. He has recently started two ventures, an online Microsoft community for colleagues to learn
from one another, located at www.RedmondSociety.com, and a second for SQL Server consulting at
www.SQLServerDBAs.com. Derek holds the MCAD/MCDBA Microsoft certifications, the Carnegie Mellon
Personal Software Process (PSP) credential, and an AAS/BS in Computer Information Systems from
University of North Dakota. Derek’s blog is located at http://RedmondSociety.com/blogs/Derek.
Douglas Hinson has worked as an independent software and database consultant in the logistics and
financial industries, with an extensive SQL Server background. He has coauthored several Wrox books,
including Professional SQL Server 2005 Integration Services.
6. Credits
Executive Editor Vice President and Executive Publisher
Bob Elliott Joseph B. Wikert
Development Editor Project Coordinators
Brian MacDonald Patrick Redmond
Ryan Steffen
Technical Editor
Dan Meyers Graphics and Production Specialists
Carrie A. Foster
Production Editor Peter Gaunt
Felicia Robinson Denny Hager
Alicia B. South
Copy Editor Ronald Terry
Foxxe Editorial Services
Quality Control Technician
Editorial Manager Laura Albert
Mary Beth Wakefield John Greenough
Production Manager Proofreading and Indexing
Tim Tate Techbooks
Vice President and Executive Group Publisher
Richard Swadley
7.
8. Contents
Acknowledgments xv
Introduction xvii
Chapter 1: Introducing SQL CLR 1
What is SQL CLR? 1
The Evolution of SQL CLR 2
Pre-SQL Server 2005 Extensibility Options 2
Why Does SQL CLR Exist? 2
Supported SQL CLR Objects 3
The .NET Architecture 4
CTS 4
CLS 5
CIL 5
VES 5
JIT 5
Managed Code and Managed Languages 6
Hosting the CLR 7
SQL CLR Architecture 7
Application Domains 8
The CLR Security Model 8
SQL CLR CAS Permission Sets 9
RBS/RBI 9
Key SQL CLR Decisions 9
Using SQL CLR or T-SQL 9
Using SQL CLR or Extended Stored Procedures 10
Using SQL CLR or OLE Automation Procedures 10
Using the Data Tier or Application Tier for Business Logic 11
SQL CLR Barriers of Entry 11
Security Considerations 11
The DBA Perspective on SQL CLR 12
Implementation Considerations 12
Performance Considerations 13
Maintenance Considerations 13
SQL Server 2005 SQL CLR support 14
9. Contents
Visual Studio 2005 SQL CLR support 14
Required Namespaces for SQL CLR Objects 15
Summary 15
Chapter 2: Your First CLR Stored Procedure 17
Setting Up SQL Server Express and the AdventureWorks Database 18
The Mechanics of a Creating and Deploying a CLR Routine 18
Enabling CLR in SQL Server 2005 20
Creating Your First SQL CLR Routine without VS2005 22
Coding the Class 22
Compiling the .NET DLL 24
Creating the Assembly 25
Choosing between User-Defined Functions and Stored Procedures 26
Creating the T-SQL Stored Procedure 27
How SQL Server Manages Assemblies 28
Assembly Metadata 29
Extracting Assembly DLL and Source Code 31
Creating Your First CLR User-Defined Function 32
Using Visual Studio to Create a CLR Routine 33
Creating the Class 34
Deploying the Class 36
What the Auto-Deployment Process Does 37
Suggested Conventions 38
Assemblies 38
Classes 38
Structures 38
Class and Structure Functions or Methods 38
Removing SQL CLR Objects 39
Reviewing Assembly Dependencies 39
Dropping an Assembly 40
Summary 40
Chapter 3: SQL CLR Structure and Common Tasks 43
SQL CLR Code Structure 43
SQL CLR Common Tasks 46
Using SQL CLR Data Type Classes 46
Detecting SQL CLR Availability 49
Performing Data Access 50
viii
10. Contents
Returning Resultsets and Messages 53
Programming Transactions 58
Summary 67
Chapter 4: Creating SQL CLR Objects 69
Managed Stored Procedures 69
Managed Code 69
The SqlProcedure Attribute 70
Parameters 72
Return Values 74
Creating, Altering, and Dropping Managed Stored Procedures 75
Managed Functions 77
Scalar-Valued Functions 77
Creating, Altering, and Dropping, Managed Scalar-valued Functions 80
Table-Valued Functions 81
Managed Triggers 83
SqlTriggerContext Class 86
Accessing the Virtual Inserted and Deleted Temporary Tables 87
Enabling and Disabling Triggers 88
Managed DML Triggers 89
Managed DDL Triggers 92
Managed Aggregates 93
Managed Code 93
SqlUserDefinedAggregate Attribute 96
Creating, Altering, and Dropping UDAs 96
Managed Types 97
Managed Code 97
SqlUserDefinedType Attribute 101
Creating, Altering, and Dropping UDTs 101
Summary 101
Chapter 5: Comparing T-SQL with Managed Code 103
Syntactic Comparisons 104
Variable Declaration and Scope 104
Automatic Variables and System Functions 106
Flow of Control 107
Syntax Checking 111
Custom Attributes and Optimizers 111
ix
11. Contents
Organizational Comparison 112
Structured Programming 112
Object-Oriented Programming? 116
Error Handling 118
Capability Comparison 119
T-SQL Data-Centric Built-Ins 119
Handling NULL Values 122
String Parsing 123
Array Handling 125
Computations and Calculations 126
Cursor Processing 131
New .NET Base Class Library (BCL) Capabilities 137
Commingling SQL CLR and T-SQL 138
Submitting Data to Database 141
Retrieve Data from Database 145
Set-Based Operations 148
Forward-Only, Read-Only Row Navigation Example 149
Performance and Other Comparisons 161
Methodology of Comparison 162
A Final Word on Performance 167
Maintainability 168
Portability 169
Summary 169
Chapter 6: Replacing Extended Stored Procedures,
Functions, and Other T-SQL Objects 171
Historical Perspective on Extended Stored Procedures 172
Why Replace XPs with SQL CLR? 172
Faster and Easier to Code 173
Plays Nice with SQL Server 173
Not Restricted to the Master Database 173
SQL CLR Replacements for XPs 174
Preparing SQL Server for External-Access Assemblies 174
Determining If a File Exists 175
Reading from the Registry 179
Replacing xp_CmdShell 182
Extended Stored Procedures for Mere Mortals 188
Writing Data to a CSV File 188
Retrieving HttpWebRequest Content 191
Calling Unmanaged Code API Functions 193
x
12. Contents
Replacing OLE Automation 195
Creating System SPs and UDFs 199
Summary 200
Chapter 7: The .NET Framework’s Base Class Library 201
Accessing External Data Sources 201
Performing File IO 201
Creating and Consuming XML Documents 207
Consuming Web Services 213
Building Effective Monitoring Tools 223
Auditing Server Processes 223
Auditing Installed Software 227
Summary 230
Chapter 8: Using SQL CLR Stored Procedures in Your Applications 231
SQL CLR Application Usage Architecture 231
SQL Server Connections and SQL CLR Stored Procedures 232
Connection Conclusions 238
Console Apps and SQL CLR Extended Procs 238
WinForms and SQL CLR UDTs 241
Creating the Point SQL CLR UDT 241
Creating a Windows Form to Display a SQL CLR UDT 242
Accepting WinForm Input to Save a SQL CLR UDT 245
Web Forms and SQL CLR Aggregates 246
Integration Services and SQL CLR TVFs 248
Building the SQL CLR TVF 249
Using the SQL CLR TVF in an SSIS Package 253
Reporting Services and SQL CLR TVFs 255
Summary 256
Chapter 9: Handling Errors in CLR Stored Procedures 257
Exception-Handling Mechanisms Used in SQL CLR 258
How T-SQL @@Error Exception-Handling Works 258
How T-SQL Try . . . Catch Error-handling Works 262
How .NET Structured Error-Handling Works 266
How SQL CLR Error Handling Works 270
SQL CLR Error-Handling Strategies 272
SQL CLR Objects Throw Errors 272
Exception Handling at Design Time 274
xi
13. Contents
Clean Up after Exceptions 276
SQL CLR Handling T-SQL Object Errors 277
T-SQL Objects Handling SQL CLR Exceptions 280
Summary 281
Chapter 10: CLR Administration and Security 283
.NET for the DBA and System Admin 284
Where the .NET Framework Is Located on Your Server 284
Only One Version of CLR Can Be Hosted in SQL Server 284
How SQL Server Manages Memory Usage in SQL CLR 286
How to Look inside a Compiled Assembly 287
Security and SQL Server–Hosted CLR 288
Security Starts with Surface Area Configuration 288
Security by Identifying SQL CLR Code and .NET Framework Usage 288
Securing the Loading of Assemblies 291
Adding Role-Based User Access to the T-SQL Prototype 293
Restricting Code at the Assembly Level 293
SQL CLR Assembly Metadata 302
Where are Noncore Assemblies Stored? 302
Where Are Core .NET Assemblies Stored? 304
Managing the SQL CLR Lifecycle 305
Start by Limiting the .NET Language 305
Setting Up the Environments 305
Promoting Source through the Environments 306
Backups 321
Monitoring and Troubleshooting SQL CLR 321
Monitoring with SQL Server Profiler 321
Using Dynamic Management Views 322
Monitoring Counters with Performance Monitor 325
Troubleshooting SQL CLR 326
Summary 329
Chapter 11: Case Study 331
Business Case 332
DateTime Calculation Background 334
Implicit Casting Issues 334
Storing Time in Date-Only Fields 335
The .NET DateTime Class 336
The .NET TimeSpan Class 338
Solution Approach 340
xii
14. Contents
Solution Prerequisites 342
T-SQL-Based Solution 343
T-SQL Object Type Decision 344
T-SQL Optional Parameters 344
Validation of Date and Time Input Parameters 345
Designing around Variable-Based Cursors 346
Creating the Table-Valued Functions 348
Creating and Calculating the Business Default Hours Structure 352
Altering Business Default Hours Structure with Exceptions 354
Considering the Parameterized Time Period 356
Calculating the Business Availability 356
SQL CLR-Based Solution 357
Setting up a .Net Studio Solution and Database Projects 358
Adding Nondatabase Projects to SQL CLR Solutions 358
Creating the Corp.SQLCLR.Scheduling Assembly 365
Creating the SQL CLR Object 383
Calculating the Business Availability 385
Solution Comparisons 386
Testing and Debugging 386
Adding a .NET Console Test Harness 388
Deployment and Administration 391
Performance 391
Development Perspective 392
Summary 392
Index 393
xiii
15.
16. Acknowledgments
Books are a lot of work and they are not the sole creation of the authors. There are countless people
involved in producing the work that you hold in your hands. So, first I wish to thank the core members
of the “Pro SQL CLR” team, including Brian MacDonald, development editor; Bob Elliott, acquisitions
editor; Dan Meyers, technical editor; and Douglas Hinson, coauthor. Brian MacDonald helped keep the
book’s schedule on track which was difficult as I had went through some huge changes in my personal
life. Douglas Hinson, my coauthor, ended up writing an additional chapter to help me. Dan Meyers,
a good personal friend of mine, provided us with stellar technical edits of the work. Dan is a Business
Intelligence (BI) expert on the SQL Server platform, and I have meet few outside of Microsoft who have
his knowledge of Analysis Services. And Bob Elliot, who provided me with the opportunity to lead this
project. Like Brian, Bob keep me going when I thought I could not proceed any further; thank you.
Personally, I wish to thank my family. There is no dollar amount that can replace the feeling when another
person believes in you and your capabilities; my family could not be any more supportive of my ambitions.
And finally I wish to thank my son, who brings me more joy in life then anything else.
—Derek Comingore
First, I thank God for the continuous blessing of life. To my beautiful wife Misty, thank you for being so
supportive and patient during this project. You are a wonderful wife and mother whom I can always
count on. To Mariah and Kyle, thanks for getting Daddy out of the office to watch Star Wars and print
Hello Kitty pictures. I love you both. To my parents, thanks for instilling in me the values of persistence
and hard work. Thanks Jenny, for being my sister and my friend. Thanks to all my extended family for
your love and support. Thanks, Brian for working your magic behind the scenes. And Dan Meyers,
thanks for your time and attention for the technical editing on this book.
—Douglas Hinson
17.
18. Introduction
“Host a .NET language routine in SQL Server?” If you picked up this book and are reading this introduc-
tion, you either saw the title and thought that very question, or you have already been trying to do just
that and have some questions. Either way you will be satisfied with the content of this book. In SQL
Server 2005, Microsoft’s SQL Server Development Team introduced the capability to write code in a
.NET language that could be compiled and run inside SQL Server. When should you consider doing
this? How would you do this? What new capabilities does SQL CLR give you? What should you worry
about? Like you, we were curious and felt compelled to dig into this new feature of SQL Server 2005,
known as CLR Integration, or by its internal name, SQL CLR. New software architecture capabilities like
this one require hours of deliberation to determine if and when to employ them. If you are a DBA or a
developer and your team is thinking about using SQL CLR, this book will teach you what you need to
know to make a decision about using SQL CLR in your solutions without having to learn the hard way.
Think about .NET code in the body of your T-SQL user-defined functions, procedures, and extended
stored procedures and you’ll start getting the picture of SQL CLR. Arrays, datasets, even object-oriented
programming techniques that are available when you develop in .NET are just not possible in current
T-SQL development. But this is only a start. SQL CLR opens up the ability to create user-defined types,
triggers, user-defined table values functions, and user-defined aggregates using a .NET managed lan-
guage. Programming using SQL CLR and .NET also opens up abilities to read and write to resources
outside of SQL Server as well as tighter integration with XML, web services, and simple file and logging
capabilities. These external activities are cool, but they create some security risks that you’ll need to
know how to lock down before you attempt to ask your DBA to deploy. Read up on how to lock down
.NET assembly capabilities in Chapter 10 and you’ll look like an expert.
Like you, we are both developers and DBAs that don’t have time to learn something that we won’t ever
use. Typically, we leave the book open while we are building or debugging some code. We started digging
into SQL CLR to see how it worked and whether we should even use it. We finished with the answers to
these questions and an idea that we could write a book about SQL CLR that you’d leave open while you
are learning. The best thing about it is you’ll get hours and hours of experimentation boiled down into 11
real-world chapters. Use the time you save to decide how you can use SQL CLR in your next SQL Server
development project.
Who This Book Is For
Are you a DBA who needs to get up to speed on the integration of .NET assemblies into SQL Server? Are
you a developer who wants to see how far you can push coding in your favorite .NET language instead of
T-SQL for complex cursor and looping tasks? Perhaps you are a software architect who needs an in-depth
study of the new capabilities of SQL CLR both within the database and by interacting with external
resources outside of SQL Server. If any of these descriptions sound familiar, this book is for you.
Learning new technology has always been demanding. Developers and architects have been more subject
to Moore’s law lately than the DBAs. First, we were hit with the whole idea of a unified .NET framework.
19. Introduction
Then we endured a wild ride with the evolution from version 1.0 to the ultra-slick features of version 2.0.
Now it’s the DBAs’ turn. The DBAs had a free ride for a while with SQL Server 2000, but now that SQL
Server 2005 has arrived, we’ve got a short on ramp to get on the .NET superhighway. SQL Server 2005 is
packed with new features. The more we use it, the more stuff we find in this release. The ability to code
.NET in SQL Server was one of the features that grabbed our attention immediately. Now that we’ve had
a chance to learn this new technology, we want to help you get up to speed on SQL CLR as soon as possi-
ble. Understanding what you can do and how to do it will be a little bit of a challenge, but read these
chapters and you’ll immediately see some new possibilities for your SQL Server development.
We approached the writing of this book for two distinct audiences: the developers and architects who
are more familiar with .NET concepts, and DBAs, who are developers in their own right, but maybe a
little behind on the .NET learning curve. Neither of these two audiences is expected to be beginners, so
if you are just starting to learn database programming, this book may not meet your needs. You need a
solid grounding in T-SQL to understand best where SQL CLR objects fit. If you already have some T-SQL
coding experience as well as a little bit of .NET, you will be able to follow along as we introduce the tech-
nology and then immediately jump into coding our first SQL CLR stored procedure. If you are interested
in a comparative analysis, you should start with Chapter 5, where we dig into the performance differ-
ences between T-SQL and SQL CLR. If you are just starting to look into SQL CLR, or if you’ve been using
it for a while and you are stuck and looking for answers, you’ll find something that will stick with you
in these chapters.
How This Book Is Structured
When we first discussed putting a book together on SQL CLR we had only one goal: to put together not
only a book on SQL CLR that you would bring to work but also one that you’d use continuously. If you
are going to use it daily, we think that it not only has to answer the questions that you have when you
start, questions about what SQL CLR is and how it works, but also be able to answer the questions that
will you have two months from now. How does that impersonation stuff work again? How do you use
the code access security model to restrict assemblies to creating files in only one directory? We think that
a book worth using daily has to answer these questions. That’s what we put together for this book: one
small part reference manual and one big part here’s-how-you-really-do-it.
Writing about SQL CLR and staying in the middle of the road between the developers and the DBAs is
a tall task, especially when you consider the subject matter. SQL CLR spans two similar but completely
different code camps: .NET framework-based coding and procedural T-SQL-based database coding.
Either approach can solve problems, but to appreciate the appropriate use and capabilities of SQL CLR
objects, you really need both a good understanding of the elegance of .NET coding capabilities and the
raw crunching power of the SQL Server engine. We understand that not everyone gets to work in both
worlds often enough to be able to make those finer connections. For those of you in this situation, you’ll
find attempts to bridge one side to another. For example, we may compare a .NET ByRef parameter to a
T-SQL INPUT OUTPUT parameter to bring the two development environment concepts together.
We have structured our chapters in an attempt to interleave just enough background information to let
us dive into the action. This is partly to keep with our theme of creating the book you’ll keep on your
desk but also to avoid what is commonly referred to as the “nap” effect. This is an unscientific phe-
nomenon that occurs when you have to read through too much reference material and you wake up at
3:00 in the morning having fallen asleep with the TV still on. We want you reading with the computer
on, not the TV. When you start working through the examples and see the magic for yourself, you’ll start
coming up with ideas on where you can use SQL CLR.
xviii
20. Introduction
The chapters in this book start from ground zero, but in Chapter 2 you’ll be creating a basic SQL CLR
stored procedure. From there you’ll come up for air to get a few .NET concepts in place and then you’ll
immediately put those new skills to work. After you’ve seen what you can do with SQL CLR, we’ll step
back and look at a comparison between SQL CLR and T-SQL to put some perspective on the hype. Then
we’ll dive into some more complex SQL CLR objects and explore the topic of replacing the soon-to-be
extinct extended stored procedures. To round out the book, we’ve focused on some of the DBA concerns
of SQL CLR particularly those related to security and administration. We hope you’ll enjoy using this
book as much as we do.
Chapter 1 introduces you to the concepts and architecture of SQL CLR.
Chapter 2 dives right in with the building of your first SQL CLR stored procedure. You’ll learn where all
the moving parts are and where the metadata is stored within SQL Server.
Chapter 3 covers the basics of the .NET namespaces. In T-SQL development, you have a limited function
library. In .NET there are many ready-made objects that make programming easier and safer.
Chapter 4 shows you how to build all of the support SQL CLR objects.
Chapter 5 takes a step back to compare and contrast the capabilities of programming in T-SQL versus
.NET languages. Here, we develop routines in both languages and perform benchmarking to determine
where each technique excels.
Chapter 6 looks at replacing the common extended stored procedures using SQL CLR routines.
Chapter 7 uses the Problem/Design/Solution paradigm to show advanced examples of employing SQL
CLR to fulfill business requirements.
Chapter 8 shows how you can use SQL CLR objects in external applications. It is one thing to build the
SQL CLR object, but this chapter shows you how to interact with them.
Chapter 9 demonstrates some error-handling techniques in SQL CLR and compares the differences
between T-SQL and .NET error handling.
Chapter 10 describes the security risks and details the process and procedures that administrators will
need to know to safely manage SQL CLR deployments.
Chapter 11 details a case study of solving a business problem using T-SQL and SQL CLR to demonstrate
advantages of deploying appropriate solutions in SQL CLR.
What You Need to Use This Book
To follow along with this book, you’ll need a copy of SQL Server Express 2005 at a minimum. SQL Server
Express is the free successor to MSDE (the older SQL Server 2000–based engine that had a workload
governor on it to limit concurrent access). Get SQL Server Express at http://msdn.microsoft.com/
vstudio/express/sql. In addition, there is a free management tool built explicitly for the Express
edition called SQL Server Management Studio Express, which can also be found at http://msdn
.microsoft.com/vstudio/express/sql.
xix
21. Introduction
Visual Studio 2005 is the preferred development environment to create, debug, and deploy your SQL
CLR routines. However, Visual Studio 2005 is not required. You could use Notepad to create your source
code, compile the source code with your managed language’s corresponding command-line compiler,
and then manually deploy to SQL Server. But practically speaking, you’ll want the productivity advan-
tages of using the Professional Edition of Visual Studio 2005 IDE to create, deploy, and debug your SQL
CLR objects. Use either Visual Studio Professional Edition, Visual Studio Tools for Office, or Visual
Studio Team System. We will be using the Professional Edition of Visual Studio 2005 for the creation of
our code samples in this book.
Conventions
To help you get the most from the text and keep track of what’s happening, we’ve used a number of con-
ventions throughout the book.
Boxes like this one hold important, not-to-be forgotten information that is directly
relevant to the surrounding text.
Tips, hints, tricks, and asides to the current discussion are offset and placed in italics like this.
As for styles in the text:
❑ We highlight new terms and important words when we introduce them.
❑ We show keyboard strokes like this: Ctrl-A.
❑ We show file names, URLs, and code within the text like this: persistence.properties.
❑ We present code in two different ways:
Code examples are displayed like this.
In code examples we highlight new and important code with a gray background.
The gray highlighting is not used for code that’s less important in the present context, or has been
shown before.
Source Code
As you work through the examples in this book, you may choose either to type in all the code manually
or to use the source code files that accompany the book. All of the source code used in this book is avail-
able for download at http://www.wrox.com. Once at the site, simply locate the book’s title (either by
using the Search box or by using one of the title lists), and click the Download Code link on the book’s
detail page to obtain all the source code for the book.
xx
22. Introduction
Because many books have similar titles, you may find it easiest to search by ISBN; this book’s ISBN is
0-470-05403-4 (changing to 978-0-470-05403-1 as the new industry-wide 13-digit ISBN numbering
system is phased in by January 2007).
Once you download the code, just decompress it with your favorite compression tool. Alternately, you can
go to the main Wrox code download page at http://www.wrox.com/dynamic/books/download.aspx
to see the code available for this book and all other Wrox books.
Errata
We make every effort to ensure that there are no errors in the text or in the code. However, no one is per-
fect, and mistakes do occur. If you find an error in one of our books, like a spelling mistake or faulty piece
of code, we would be very grateful for your feedback. By sending in errata you may save another reader
hours of frustration and at the same time you will be helping us provide even higher-quality information.
To find the errata page for this book, go to http://www.wrox.com and locate the title using the Search box
or one of the title lists. Then, on the book details page, click the Book Errata link. On this page, you can
view all errata that has been submitted for this book and posted by Wrox editors. A complete book list
including links to each’s book’s errata is also available at www.wrox.com/misc-pages/booklist.shtml.
If you don’t spot “your” error on the Book Errata page, go to www.wrox.com/contact/techsupport
.shtml and complete the form there to send us the error you have found. We’ll check the information
and, if appropriate, post a message to the book’s errata page and fix the problem in subsequent editions
of the book.
p2p.wrox.com
For author and peer discussion, join the P2P forums at p2p.wrox.com. The forums are a web-based sys-
tem for you to post messages relating to Wrox books and related technologies and interact with other
readers and technology users. The forums offer a subscription feature to e-mail you topics of interest of
your choosing when new posts are made to the forums. Wrox authors, editors, other industry experts,
and your fellow readers are present on these forums.
At http://p2p.wrox.com, you will find a number of different forums that will help you not only as you
read this book but also as you develop your own applications. To join the forums, just follow these steps:
1. Go to p2p.wrox.com and click the Register link.
2. Read the terms of use and click Agree.
3. Complete the required information to join as well as any optional information you wish to provide
and click Submit.
4. You will receive an e-mail with information describing how to verify your account and complete
the joining process.
You can read messages in the forums without joining P2P, but in order to post your own messages, you
must join.
xxi
23. Introduction
Once you join, you can post new messages and respond to messages other users post. You can read mes-
sages at any time on the web. If you would like to have new messages from a particular forum e-mailed
to you, click the Subscribe to this Forum icon by the forum name in the forum listing.
For more information about how to use the Wrox P2P, be sure to read the P2P FAQs for answers to ques-
tions about how the forum software works as well as many common questions specific to P2P and Wrox
books. To read the FAQs, click the FAQ link on any P2P page.
xxii
24. Introducing SQL CLR
SQL Server’s .NET integration is arguably the most important feature of SQL Server 2005 for
developers. Developers can now move their existing .NET objects closer to the database with SQL
CLR. SQL CLR provides an optimized environment for procedural- and processing-intensive tasks
that can be run in the SQL Server tier of your software’s architecture. Also, database administra-
tors need a strong knowledge of SQL CLR to assist them in making key administrative decisions
regarding it. If you ignore SQL CLR, you’re missing out on the full potential SQL Server 2005 can
offer you and your organization, thus limiting your effectiveness with the product.
SQL CLR is a very hot topic in the technical communities but also one that is frequently misunder-
stood. Unquestionably, there will be additional work devoted to SQL CLR from Microsoft and
Paul Flessner (Microsoft’s senior vice president, server applications), including the support of
future database objects being created in SQL CLR. The book you are reading is your one and only
necessary resource for commanding a strong knowledge of SQL CLR, including understanding
when to use the technology and, just as importantly, when not to use it.
What is SQL CLR?
SQL CLR is a new SQL Server feature that allows you to embed logic written in C#, VB.Net, and
other managed code into the body of T-SQL objects like stored procedures, functions, triggers,
aggregates and types. Client applications interact with these resulting routines like they are writ-
ten in native T-SQL. Internally, things like string manipulations and complex calculations become
easier to program because you are no longer restricted to using T-SQL and now have access to
structured .Net languages and the reuse of base class libraries. Externally, the logic you create is
wrapped in T-SQL prototypes so that the client application is not aware of the implementation
details. This is advantageous because you can employ SQL CLR where you need it without re-
architecting your existing client code.
With SQL CLR, you are also freed from the constraint of logic that applies only within the context
of the database. You can with appropriate permissions write logic to read and write to file systems,
25. Chapter 1
use logic contained in external COM or .Net DLLs, or process results of Web service or remoting meth-
ods. These capabilities are exciting and concerning, especially in the historical context of new feature
overuse. To help you use this new feature appropriately, we want to make sure that you understand how
it integrates with SQL Server and where this feature may be heading. In this chapter, we’ll give you this
type of overview. We’ll spend the rest of the book explaining these concepts using real-world SQL CLR
examples that you can use today.
The Evolution of SQL CLR
A few years ago, we came across a product roadmap for Visual Studio and SQL Server that mentioned a
feature that was described as “creating SQL Server programming objects in managed languages.” At the
time, we could not comprehend how this feature would work or why Microsoft had chosen to do this.
.NET 1.0 had just been released not, and to be able to use these compiled procedural languages to create
database objects just did not “compute” to us.
At the time of this writing, the year is 2006 and Microsoft SQL Server 2005 has arrived with a big roar in
the database market. CLR Integration is the official Microsoft term for the .NET Framework integration
into SQL Server. SQL CLR was the original term used by Microsoft to refer to this technology and it con-
tinues to be used predominantly in the surrounding technical communities.
The Common Language Runtime (CLR) is the core of the Microsoft .NET Framework,
providing the execution environment for all .NET code. SQL Server 2005 hosts the
CLR, thus the birth name of the technology “SQL CLR,” and its successor “CLR
Integration.”
Pre-SQL Server 2005 Extensibility Options
Before SQL Server 2005, there was a handful of options a database developer could implement to extend
beyond the boundaries of T-SQL. As we will discuss in this chapter, SQL CLR is almost always a better
environment for these routines. The pre-SQL Server 2005 extensible options are:
❑ Extended Stored Procedures, C/C++ DLLs that SQL Server can dynamically load, run, and
unload.
❑ sp_oa Procedures, OLE automation extended stored procedures. You can use these system pro-
cedures to invoke OLE objects. Even with the arrival of the SQL CLR technology there may be
times when you still need to use these procedures for those situations in which you must use a
Object Linking and Embedding (OLE) object.
Why Does SQL CLR Exist?
Dr. E. F. “Ted” Codd is the “father” of relational databases and thus Structured Query Language (SQL)
as well. SQL is both an American National Standards Institute (ANSI) and International Organization for
Standardization (ISO) standard. SQL (and its derivatives, including T-SQL) are set-based languages
designed to create, retrieve, update, and delete (CRUD) data that is stored in a relational database
2
26. Introducing SQL CLR
management system (RDBMS). SQL was and still is the natural choice when you only require basic
CRUD functionality.
There are many business problems in the real world that require much more than basic CRUD function-
ality, however. These requirements are usually fulfilled in another logical layer of a software solution’s
architecture. In today’s current technical landscape, web services, class libraries, and sometimes even
user interfaces fulfill the requirements beyond CRUD. Passing raw data across logical tiers (which some-
times can be physical tiers as well) can be undesirable, depending upon the entire solution’s require-
ments; in some cases, it may be more efficient to apply data transformations on the raw data before
passing it on to another logical tier in your architecture. SQL CLR allows the developer to extend beyond
the boundaries of T-SQL in a safer environment than what was previously available, as just discussed.
There are unlimited potential uses of SQL CLR, but the following situations are key candidates for it:
❑ Complex mathematical computations
❑ String operations
❑ Recursive operations
❑ Heavy procedural tasks
❑ Porting extended stored procedures into the safer managed code environment
The Goals of SQL CLR
The architects and designers of the CLR integration into SQL Server at Microsoft had a few objectives for
the functionality:
❑ Reliability: Managed code written by a developer should not be able to compromise the SQL
Server hosting it.
❑ Scalability: Managed code should not stop SQL Server from supporting thousands of concur-
rent user sessions, which it was designed to support.
❑ Security: managed code must adhere to standard SQL Server security practices and permis-
sions. Administrators must also be able to control the types of resources that the CLR assemblies
can access.
❑ Performance: Managed code being hosted inside SQL Server should execute just as fast as if the
code were running outside of SQL Server.
Suppor ted SQL CLR Objects
SQL CLR objects are the database objects that a developer can create in managed code. Originally, most
people thought that SQL CLR would only allow the creation of stored procedures and functions, but
luckily there are even more database programming objects supported. As of the RTM release of SQL
Server 2005, you can create the following database objects in a managed language of your choice:
❑ Stored procedures
❑ Triggers (supporting both Data Manipulation Language [DML] and Data Definition Language
[DDL] statements)
3
27. Chapter 1
❑ User-defined Functions (UDF) (supporting both Scalar-Valued Functions [SCF] and Table-
Valued Functions [TVF])
❑ User-defined aggregates (UDA)
❑ User-defined types (UDT)
Stored procedures are stored collections of queries or logic used to fulfill a specific requirement. Stored
procedures can accept input parameters, return output parameters, and return a status value indicating
the success or failure of the procedure. Triggers are similar to stored procedures in that they are collec-
tions of stored queries used to fulfill a certain task; however, triggers are different in that they execute in
response to an event as opposed to direct invocation. Prior to SQL Server 2005, triggers only supported
INSERT,UPDATE, DELETE events, but with SQL Server 2005 they also support other events such as
CREATE TABLE.
Functions are used primarily to return either a scalar (single) value or an entire table to the calling code.
These routines are useful when you want to perform the same calculation multiple times with different
inputs. Aggregates return a single value that gets calculated from multiple inputs. Aggregates are not new
with SQL Server 2005; however, the ability to create your own is new. User-defined types provide you with
a mechanism to model your specific data beyond what the native SQL Server data types provide you with.
The .NET Architecture
The assembly is the unit of deployment for managed code in .NET, including SQL Server’s implementa-
tion of it. To understand what an assembly is, you need a fundamental understanding of the CLR (which
is the heart of the .NET Framework, providing all managed code with its execution environment). The
CLR is the Microsoft instance of the CLI standard. The CLI is an international standard developed by the
European Computer Manufactures Association (ECMA) that defines a framework for developing appli-
cations in a language agnostic manner. The CLI standard’s official name is ECMA-335, and the latest
draft of this standard, as of the time of this writing, was published in June 2005.
There are several key components of the CLI and thus the Microsoft implementation of it (the CLR and
Microsoft Intermediate Language [MSIL] code):
❑ Common Type System (CTS)
❑ Common Language Specification (CLS)
❑ Common Intermediate Language (CIL)
❑ Virtual Execution System (VES)
❑ Just-in-Time compiler (JIT)
Figure 1-1 shows how these components work together.
CTS
The CTS defines a framework for both value types and reference types (classes, pointers, and interfaces).
This framework defines how types can be declared, used, and managed. The CTS describes type safety,
4
28. Introducing SQL CLR
how types are agnostic of programming language, and high-performing code. The CTS is a core compo-
nent in supporting cross-language interoperability given the same code base. In the Microsoft .NET
context, this is implemented by the .NET Framework as well as custom types created by users (all types
in .NET must derive from System.Object).
CLS
The CLS defines an agreement between programming language and class library creators. The CLS con-
tains a subset of the CTS. The CLS serves as a baseline of CTS adoption for designers of languages and
class libraries (frameworks). In the Microsoft.NET context, this could be any .NET-supported language
including Visual Basic .NET and C#.
CIL
CIL is the output of a compiler that adheres to the CLI standard. ECMA-335 specifies the CIL instruction
set. CIL code is executed by the VES (discussed shortly). In the Microsoft .NET context, this is the code
you produce when you build a project in Visual Studio or via the command line using one of the sup-
plied compilers such as VBC for Visual Basic .NET and CSC for C#. Microsoft Intermediate Language
(MSIL) is the Microsoft instance of CIL.
VES
The VES is the execution environment for CIL code; the VES loads and runs programs written in CIL.
There are two primary pieces of input for the VES, CIL/MSIL code and metadata. In the Microsoft .NET
context, this occurs during the runtime of your .NET applications.
JIT
The JIT compiler is a subsystem of the VES, producing native CPU-specific code from CIL/MSIL code.
As its name implies, the JIT compiler compiles CIL/MSIL code at runtime as it’s requested, or just in
time. In the Microsoft.NET context, this is during runtime of your .NET applications as you instantiate
new classes and their associated methods.
How does the assembly fit into this CLI architecture? In the .NET context, it is when you compile your
source code (this is what occurs “behind the scenes” when you build a project in Visual Studio as well)
using one of the supported compilers, the container for your MSIL code is the assembly. There are two cat-
egories of assemblies in .NET: the EXE and the DLL (SQL CLR assemblies are always DLLs). Assemblies
contain both the MSIL code and an assembly manifest. Assemblies can be either single-file- or multi-file-
based. In the case of a single-file assembly, the manifest is part of the contents of the assembly. In the case
of the latter, the manifest is a separate file itself. Assemblies are used to identify, version, and secure MSIL
code; it is the manifest that enables all of these functions.
If you’re a compiler guru or you just wish to learn more about the internal workings of Microsoft’s
CLR implementation of the CLI standard, Microsoft has made the Shared Source Common Language
Infrastructure 1.0 Release kit available to the general public. You can find this limited open source ver-
sion of the CLR at www.microsoft.com/downloads/details.aspx?FamilyId=3A1C93FA-
7462-47D0-8E56-8DD34C6292F0&displaylang=en.
5
29. Chapter 1
Managed Languages
(ie Visual Basic.Net, C#)
Managed Languages
Compiler
(ie vbc.exe or csc.exe)
CLI
MSIL code
CLR
CPU specific instructions
01100110
Figure 1-1
Managed Code and Managed Languages
Code that is executed inside the CLR is called managed code. Thus, the languages that produce this code
are called managed languages. The languages are called managed because the CLR provides several run-
time services that manage the code during its execution, including resource management, type-checking,
and enforcing security. Managed code helps prevent you from creating a memory-leaking application. It
is this “managed nature” of CLR code that makes it a much more secure environment to develop in than
previous platforms.
6
30. Introducing SQL CLR
Hosting the CLR
The CLR was designed from the beginning to be hosted, but only since the arrival of SQL Server hosting
has the concept received so much attention. All Windows software today begins unmanaged, that is,
running native code. In the future, the operating system will probably provide additional CLR services
so that applications can actually begin as managed software as opposed to what we have today. Thus, in
today’s Windows environment any application that wishes to leverage the CLR and all its advantages
must host it in-process, and this means invoking it from unmanaged code. The .NET Framework
includes unmanaged application program interfaces (APIs) to enable this loading and initialization of
the CLR from unmanaged clients. It is also worthwhile to mention that the CLR supports the notion of
running multiple versions of itself side by side on the same machine, but a CLR host can only load one
version of the runtime; thus, it must decide which version to load before doing so.
There are several pieces of software that you use today that host the CLR, including ASP.NET, Internet
Explorer, and shell executables.
SQL CLR Architecture
SQL Server 2005 hosts the CLR in a “sandbox”-like environment in-process to itself, as you can see
Figure 1-2. When a user requests a SQL CLR object for the first time, SQL Server will load the .NET exe-
cution engine mscoree.dll (which is the CLR) into memory. If you were to disable SQL CLR (see
Chapter 2 for more details) at a later point in time, the hosted CLR would immediately be unloaded
from memory.
This contained CLR environment aids SQL Server in controlling key CLR operations. The CLR makes
requests to SQL Server’s operating system (SQLOS) for resources such as new threads and memory;
however, SQL Server can refuse these requests (for example, if SQL Server has met its memory restric-
tion, and doesn’t have any additional memory to allocate to the CLR). SQL Server will also monitor for
long-running CLR threads, and if one is found, SQL Server will suspend the thread.
SQLOS is not a topic for the novice; we are talking about the “guts” of SQL Server
here. SQLOS is an abstraction layer over the base operating system and its corre-
sponding hardware. SQLOS enables SQL Server (and future server applications
from Microsoft) to take advantage of new hardware breakthroughs without having
to understand each platform’s complexities and uniqueness. SQLOS enables such
concepts as locality (fully utilizing local hardware resources to support high levels
of scalability) and advanced parallelism. SQLOS is new with SQL Server 2005.
If you wish to learn more about SQLOS you can visit Slava Oks’s weblog at
http://blogs.msdn.com/slavao. Slava is a developer on the SQLOS team for
Microsoft.
7
31. Chapter 1
CLR
SQL Engine
Hosting Layer
SQL OS
Windows
Figure 1-2: The SQL CLR Architecture
Application Domains
You can think of an application domain as a mini-thread, that is an execution zone. Application domains
are managed implicitly by the CLR for you. Application domains are important because if the CLR code
encounters a fatal exception, its corresponding application domain will be aborted, but not the entire
CLR process. Application domains also increase code reliability, including the SQL Server hosting of it.
All assemblies in a particular database owned by the same user form an application domain in the SQL
Server context. As new assemblies are requested at runtime they are loaded into either an existing or
new application domain.
The CLR Security Model
Microsoft’s CLR security model is called code access security (CAS). The primary goal of CAS is to pre-
vent unauthenticated code from performing tasks that should require preauthentication. The CLR iden-
tifies code and its related code groups as it loads assemblies at runtime. The code group is the entity that
assists the CLR in associating a particular assembly with a permission set. In turn, the permission set
determines what actions the code is allowed to perform. Permission sets are determined by a machine’s
administrator. If an assembly requires higher permissions that what it was granted, a security exception
is thrown.
8
32. Introducing SQL CLR
So how does the CLR security model apply to SQL CLR? There are two methods of applying security in
SQL CLR, CAS permission sets and Role-Based Security (RBS) also known as Role-Based Impersonation
(RBI), both of which can be used to ensure that your SQL CLR objects run with the required permissions
and nothing more.
SQL CLR CAS Permission Sets
When you load your assemblies into SQL Server, you assign those assemblies a permission set. These
permission sets determine what actions the corresponding assembly can perform. There are three default
permission sets you can assign to your assemblies upon loading them into SQL Server (see Chapter 8 for
more details):
❑ SAFE indicates that computational or string algorithms as well as local data access is permitted.
❑ EXTERNAL_ACCESS inherits all permissions from SAFE plus the ability to access files, net-
works, registry, and environmental variables.
❑ UNSAFE is the same as EXTERNAL_ACCESS without some of its restrictions and includes the
ability to call unmanaged code.
RBS/RBI
RBS is useful when your SQL CLR objects attempt to access external resources. SQL Server will natively
execute all SQL CLR code under the SQL Server’s service account; this can be an erroneous approach to
enforcing security because all users of the SQL CLR object will run under the same Windows account
regardless of their individual permissions. There are specific APIs to allow SQL CLR developers to check
and impersonate the user’s security context (see Chapter 8 for more details).
RBS is only applicable when the user is logged in to SQL Server using Windows Authentication. If
your SQL CLR code determines the user is using SQL Server Authentication, it will automatically
deny them access to resources that require authentication.
Key SQL CLR Decisions
With the arrival of the SQL CLR technology, you’re now faced with several key decisions to be made
regarding when and how to use it. These key decisions are some of the hottest topics regarding the tech-
nology in the online and offline technical communities.
Using SQL CLR or T-SQL
The one decision always coming to the foreground is now, “Should I implement this object in T-SQL or
managed code?” Do not discount T-SQL just because you now have a more secure alternative in SQL CLR.
T-SQL has been greatly enhanced in SQL Server 2005. If you take away only one concept from this chapter,
let it be that SQL CLR is not a replacement for T-SQL — SQL CLR complements T-SQL. The following table
compares the various attributes of each environment.
9
33. Chapter 1
Attribute T-SQL SQL CLR
Code Execution Interpreted Compiled
Code Model Set-Based Procedural-Based
Access to subset of the .NET No Yes
Framework Base Class Libraries (BCL)
SQL Server Access Direct Access In-Process Provider
Support Complex types No Yes
Parameter Support Input and Output Input and Output
Parameters Parameters
Be aware that the CLR natively does not support VarChar or Timestamp datatypes.
Based on this information, you can draw some general conclusions about when to use T-SQL for a solu-
tion and when to employ SQL CLR: In general, if you are performing basic CRUD functionality you
should use traditional T-SQL for these tasks; for anything else, such as intensive cursor processing,
accessing external resources, you should use SQL CLR.
Using SQL CLR or Extended Stored Procedures
Extended Stored Procedures (XPs) are typically written in C/C++ against the SQL Server Extended
Procedure API, and produce a DLL that SQL Server can load, execute, and unload at runtime. XPs are
notorious for causing memory leaks and compromising the integrity of the SQL Server process. In addi-
tion, XPs will not be supported in future versions of SQL Server. SQL CLR provides a much safer alter-
native to using XPs. We recommend that all new development that requires such functionality employ
SQL CLR and not XPs. We also recommend that you immediately begin the process of converting your
existing XPs to the CLR (see Chapter 4 for more details).
One of the strongest reasons to adopt SQL CLR is to port existing XPs to the safer environment of
the CLR.
Using SQL CLR or OLE Automation Procedures
Since SQL Server 6.5 standard edition, SQL Server has supported the functionality of calling Component
Object Model (COM) objects from within T-SQL; this feature is known as OLE Automation. OLE
Automation is implemented in SQL Server using several XPs prefixed with sp_oa, oa meaning OLE
Automation. By leveraging these XPs in your T-SQL code you can instantiate objects, get or set proper-
ties, call methods, and destroy objects.
Similarly to using XPs, the COM objects you invoke with sp_oa run in the same address space as the
database engine, which creates the possibility of compromising the entire database engine. OLE
Automation has been known to cause memory leaks too; there have been knowledge base articles from
Microsoft about these XPs leaking memory natively without poor coding techniques. So again, the main
benefit of SQL CLR as compared to older technologies is stability and security.
10
34. Introducing SQL CLR
Using the Data Tier or Application Tier for Business Logic
Prior to SQL Server 2005, business logic would typically reside on another server in the form of a COM
object or a web service. With the advent of SQL CLR middle-tier developers now have a choice regard-
ing where they want their routines to “reside.” When you’re deciding where your business logic should
be placed, there is one key issue you must consider: the cost of bandwidth versus the cost of computing
resources. Generally speaking, you are going to want to consider leveraging SQL CLR for your business
logic when your data access returns a lot of data. On the other hand, when your business logic returns
minimal data, it probably makes more sense not to employ SQL CLR. Again, the key here is which
resources do you have more of, and which resource do you wish to use to support your business logic
processing? Maybe you have excessive amounts of bandwidth to spare, but your SQL Server’s CPUs and
memory are already maxed out. In this case, it may still make more sense to send a lot of data across the
wire as you would have done previously.
The other consideration is whether or not you wish to keep your business logic close to the database to
help promote its global use. Typically, developers will create a logical middle tier to encapsulate their
business logic, but one drawback of this approach is that your business logic is not as “close” to the
database it’s accessing. If you were to employ SQL CLR for your business logic it would help, but not
enforce, your middle-tier logics use. The bottom line here is that each environment and software solution
is unique, but these are the issues you should be contemplating when making these crucial decisions.
SQL CLR Barriers of Entr y
Not only are there crucial decisions that must be made about a new technology, but there are also barri-
ers of entry in order to properly use and obtain the benefit provided by the technology. SQL CLR is no
different in this aspect. There are security, implementation, performance, and maintenance tasks that
should be addressed.
Security Considerations
We realize that security from a developer’s standpoint is more of a nuisance and you’d rather leave this
task to the DBAs. But our experience as DBAs tell us that security is a from-the-ground-up thought pro-
cess with TSQL and even more so with SQL CLR. If you’re a developer, we have some shocking news:
you are going to have to understand SQL CLR security because it’s very important in dictating what
your assemblies are allowed to do. Organizations that are successful in deploying SQL CLR assemblies
will foster teamwork between its DBAs and developers (more than the typical organization does).
As an example of the concepts that you’ll be deciding about the security of SQL CLR code is how TSQL
and SQL CLR will enforce and respect security between shared calls. Links or Comingling is the term
assigned to the relationship formed between T-SQL and managed code calling one another. You should
already be aware of CAS permission sets as they were briefly covered earlier in the chapter, as well as
Role-Based Impersonation. You have also heard a bit about application domains; just be aware that
application domains, in a security context, are important because they form a level of isolation for your
managed code. So, if a piece of SQL CLR tries to perform an illegal operation, the entire application
domain gets unloaded. Bottom line, security is always important, but in the SQL CLR context an open
dialogue between both developers and DBAs is even more important. Chapter 9 will explore SQL CLR
security in depth.
11
35. Chapter 1
The DBA Perspective on SQL CLR
The DBA is typically very cautious about giving developers flexibility, as they should be. One piece of
poorly written code could compromise the entire SQL Server instance executing it. As we previously men-
tioned, XPs are notorious for causing SQL Server problems, and this has contributed to DBAs enforcing
strong policies on developers. After all, the DBA is ultimately responsible for the overall health of a SQL
Server, and not the developers.
SQL CLR’s arrival is forcing DBAs to consider the question of “should I enable this thing or not?” It has
been our experience with SQL Server 2005 thus far that DBAs will leave this feature turned off unless it
is explicitly required to fulfill certain requirements of the organization. SQL CLR is turned off, by default
upon a fresh installation of SQL Server 2005, part of Microsoft’s “secure by default” strategy.
Although leaving SQL CLR off is not necessarily a bad option, we also think enabling SQL CLR and
restricting what your developers can do via CAS permissions is a better solution. By allowing (and even
promoting) SQL CLR in your SQL Server environment, developers will have a safe, secure, and managed
alternative to T-SQL with permissions designated by you. After reading this book, DBAs will be well
equipped to be proactive about SQL CLR and at the same time be confident in what you are allowing
your developers to do with the technology.
Implementation Considerations
Before you even think about using SQL CLR (whether you’re a DBA or developer), you must learn either
VB.NET or C#. This is not an option. VB.NET and C# are the only officially supported SQL CLR lan-
guages. (Managed C++ is somewhere in between not supported and supported, because it does have a
Visual Studio template for SQL CLR projects, but it must also be compiled with a special /safe switch
for reliability). We encourage you to explore using other managed languages for creating SQL CLR
objects, but be aware that they are not officially supported as of the time of this writing.
Logically you’re probably now wondering what we mean by officially supported managed languages.
Remember, all managed code gets translated into MSIL, so really we are misleading you here. The lan-
guage you choose is largely about a choice of syntax, but what is supported and not supported is what
your managed code does and what types it uses. The reason VB.NET and C# are the officially supported
managed languages for SQL CLR is that they have built-in project templates that are guaranteed to gen-
erate code that is safe for SQL CLR execution. If you create a new VB.NET/C# Database/SQL Server
project, and select “Add Reference,” you will notice that not all of the .NET Framework classes or types
appear which brings us to the next implementation point. You do not have access to the complete .NET
Framework Base Class Library (BCL) in SQL CLR, as most people presume. In reality, you have access to
a subset of the BCL that adheres to the SQL Server host requirements.
Host Protection Attributes (HPAs) are the implementation for a CLR host’s requirements, which deter-
mine what types can be used when the CLR is hosted as opposed to when the CLR is running natively.
Additionally, HPAs become more important when coupled with the various CAS permission sets you
can apply to your SQL Server assemblies. For now, just understand that there are CLR host require-
ments, which assist SQL Server in determining if it should allow the use of a particular type or not.
If you use an unsupported managed language to create an assembly that you then load into SQL Server
as an UNSAFE assembly and that assembly does not adhere to the HPAs, the assembly could attempt
an operation that could threaten the stability of the SQL Server hosting it. Any time the stability of
12
36. Introducing SQL CLR
SQL Server is threatened by an assembly, the offending assembly’s entire application domain gets
unloaded. This fact goes a long way in proving that stability was designed and implemented well in
SQL CLR.
Finally, there is the relation of the CAS permission sets to implementation considerations (which we
started to discuss above). The CAS permission set assigned to your SQL CLR assemblies will ultimately
determine just how much you can do in the assembly. One of the most common questions about SQL CLR
is whether you can call native code in a SQL CLR assembly. The answer is based on the permission set
assigned to the assembly. In Chapter 3, we will thoroughly go through all of this material, but realize that
if you assign the UNSAFE permission set to an assembly it can attempt practically any operation (includ-
ing calling native code). Whether the host of the CLR executes “allows” it or not is another matter.
Performance Considerations
Performance is always important, but even more so when you’re talking about code running inside of a
relational database engine designed to handle thousands of concurrent requests. Consider these SQL
CLR performance issues:
First and foremost, if your routine simply needs to perform basic relational data access, it will always
perform better when implemented in T-SQL than in SQL CLR. If there is a “no brainer” performance
decision relating to SQL CLR, it is when your code just needs to perform CRUD functionality, use T-SQL
100% every time.
Second, transactions are important for your SQL CLR performance considerations. By default, all SQL
CLR code is enlisted in the current transaction of the T-SQL code that called it. Thus, if you have a long-
running SQL CLR routine, your entire transaction will be that much longer. The point is, be very hesitant
about creating long-running routines in SQL CLR (see Chapter 3 for more details on the handling of
transactions).
Last, once you have elected to use SQL CLR for a particular routine, be aware of the various resources
you have at your disposal to monitor SQL CLR performance (see Chapter 9 for more information). These
resources include:
❑ System and Dynamic Management Views
❑ SQL Trace Events (captured with SQL Server Profiler or system stored procedures for custom
monitoring needs)
❑ Performance Counters
Maintenance Considerations
If we had a dollar for every SQL Server instance we have worked on that was poorly maintained . . . we
wouldn’t be rich, but we’d be well off. Databases can easily become unwieldy beasts if you don’t take a
proactive approach to maintenance (this is usually the case when we work on SQL Server installations
that did not have an official DBA assigned to them). SQL CLR assemblies and their related database
objects are no different.
The DBA is usually the title of the person in an organization who is responsible for database mainte-
nance, so naturally this aspect of SQL CLR is going to affect him or her more than the developer. If the
13
37. Chapter 1
DBA chooses to enable SQL CLR in one of the SQL Servers, he or she should also be willing to keep track
and monitor the inventory of SQL CLR assemblies. Not only would it be a serious security risk to allow
developers to “push” SQL CLR assemblies to a production box without first consulting the DBA, but
you could also end up with potentially hundreds of assemblies stored in your database that no one uses
anymore or even knows their purpose.
SQL Ser ver 2005 SQL CLR suppor t
All nonportable editions of SQL Server 2005 support SQL CLR, including SQL Server Express. We also
found that SQL Server 2005 Mobile does not offer similar functionality via hosting the .NET Compact
Framework’s CLR in-process on portable devices. We will be using the Express edition of SQL Server 2005
for the creation of our code samples in this book. SQL Server Express is the free successor to MSDE (the
older SQL Server 2000–based engine that had a workload governor on it to limit concurrent access). SQL
Server Express can be found at http://msdn.microsoft.com/vstudio/express/sql. In addition,
there is a free management tool built explicitly for the Express edition called SQL Server Management
Studio Express, which can also be found at http://msdn.microsoft.com/vstudio/express/sql.
The following are the system requirements for SQL Server Express:
Resource Required Recommended
Processor 600-megahertz (MHz) Pentium III–compatible 1–gigahertz (GHz) or faster
or faster processor processor
Operating Windows XP with Service Pack 2 or later N/A
System Windows 2000 Server with Service Pack 4 or later
Windows Server 2003 Standard, Enterprise, or
Datacenter editions
Windows Server 2003 Web Edition Service Pack 1
Windows Small Business Server 2003 with
Service Pack 1 or later
Memory 192 megabytes (MB) of RAM 512 megabytes (MB)
Hard Disk Approximately 350 MB of available hard-disk Approximately 425 MB of
Drive space for the recommended installation additional available hard-disk
space for SQL Server Books
Online, SQL Server Mobile Books
Online, and sample databases
Display Super VGA (1,024x768) or higher-resolution N/A
video adapter and monitor
Visual Studio 2005 SQL CLR suppor t
Visual Studio 2005 is the preferred development environment to create, debug, and deploy your SQL
CLR routines in, however Visual Studio 2005 is not required. You could even use Notepad to create your
source code, compile the source code with your managed language’s corresponding command-line com-
piler, and then manually deploy it to SQL Server. If you do wish to use Visual Studio 2005, you will need
14
38. Introducing SQL CLR
at least the Professional Edition of Visual Studio 2005 to be able to create, deploy, and debug your SQL
CLR objects in Visual Studio. Thus, you need either Visual Studio Professional Edition, Visual Studio
Tools for Office, or Visual Studio Team System. We will be using the Professional Edition of Visual
Studio 2005 for the creation of our code samples in this book. The following are the requirements for
Visual Studio 2005 Professional Edition:
Resource Recommended
Processor 600 mHz
Operating System Windows XP with Service Pack 2 or later
Windows XP Professional x64 Edition (WOW)
Windows Server 2003 with Service Pack 1
Windows Server 2003 x64 Edition (WOW)
Windows Server 2003R2
Windows Server 2003R2 x64 Edition (WOW)
Windows Vista
Memory 192 MB of RAM or more
Hard Disk 2 GB available
Drive DVD-ROM drive
Required Namespaces for SQL CLR Objects
There are four namespaces required to support the creation of SQL CLR objects. The required name-
spaces are:
❑ System.Data
❑ System.Data.Sql
❑ System.Data.SqlTypes
❑ Microsoft.SqlServer.Server
All of these namespaces physically reside in the System.Data assembly. System.Data is part
of the BCL of the .NET Framework and resides in both the Global Assembly Cache (GAC) as well as
in the .NET 2 Framework directory: C:WINDOWSMicrosoft.NETFrameworkv2.0.50727
System.Data.dll.
System.Data is automatically referenced for you when using Visual Studio 2005 for creating your
SQL CLR objects. Also, the above-mentioned namespaces are automatically imported for you as well.
Summar y
In this introductory chapter, we have covered a lot of information that you need to comprehend before
you begin creating your SQL CLR objects. You learned of the database objects you can create in the SQL
CLR technology. We have shown the architecture of the .NET Framework and when it is being hosted by
15
39. Chapter 1
SQL Server. We have addressed the biggest decisions developers and administrators have to make
regarding SQL CLR. We also wanted to inform you that we are using SQL Server Express coupled with
Visual Studio Professional for the production of this book’s sample code, we choose these editions of the
tools because they are the “lightest” editions of each product that support the SQL CLR technology, and
we feel the vast majority of Microsoft developers use Visual Studio as opposed to the command-line
compilers. Now that you have a strong foundation in how .NET and SQL CLR works, its time to begin
creating your first SQL CLR objects. In Chapter 2, we are going to be covering how to create, deploy, and
debug a managed stored procedure.
16
40. Your First CLR Stored
Procedure
The ability to integrate the idiom of .NET programming via the CLR into the database world of
SQL Server has generated many strong opinions for and against its use. Some purists have argued
that a non-set-based programming approach has no place in the database arena. Some have wor-
ried that developers will overuse SQL Server Common Language Runtime (SQL CLR) routines to
avoid learning the programmatic idioms of T-SQL. Others are concerned about the security and
complexity and want to turn it off completely. Opening up SQL Server to capabilities beyond pure
database operations will drive and is driving this discussion beyond the DBA community. Both
DBAs and developers are exploring and taking sides on how to use these capabilities, and many
issues are up for discussion. Who should build SQL CLR objects? Should only developers build
SQL CLR routines, or only DBAs, or both? When is it appropriate to use a SQL CLR routine versus
a T-SQL object? How do you build a SQL CLR stored procedure or user-defined function? These
are just some of the questions you’ll have as you start digging into extending SQL Server using
SQL CLR. Before you drown in all the details of the philosophical, let’s answer the question of how
to create SQL CLR routines and obtain a good grounding in how they work inside SQL Server.
Our first task is to expose you to the technology, to show you the mechanics of hosting managed
code into the SQL environment. Get your feet wet by walking through this how-to chapter to build
some working CLR routines — namely user-defined function and stored procedures. In this chap-
ter, you’ll go through the creation of a basic SQL CLR stored procedure. We’ll work manually at
first using Notepad, without the Visual Studio environment. This will give you the blue-collar
knowledge of how to put a SQL CLR object together from the ground up. You’ll learn the inner
workings of these new objects as well as gain an understanding of how the managed code fits into
the SQL Server metadata. We’ll start slow in case you’re not yet familiar with the .NET environ-
ment. Then, we’ll build the same project using the Visual Studio environment and get you up to
speed on the improved 2005 integrated development environment (IDE). Finally, we’ll give you an
idea of how you’ll need to approach your development processes to ease the pain of deployment
later as you deploy into robust production environments. As with all technology, the key to using
41. Chapter 2
it appropriately is to understand how it works. This insight helps you learn what it can do, as well as its
limitations. While this chapter won’t answer all your questions, you’ll get the basics of how to create and
deploy some basic SQL CLR stored procedures and user-defined functions.
Setting Up SQL Ser ver Express and the
AdventureWorks Database
In this book, our examples are built using the .NET Framework 2.0 or higher. We will be using the
AdventureWorks sample database for some examples, and for others we recommend that you create
a sample database called CLRTESTDB. This can be done most easily by opening up SQL Server
Management Studio and right-clicking the database node in the Object Explorer underneath your SQL
Express server. Click New Database in the pop-up menu and then type the name CLRTESTDB into the
Database Wizard and click OK to accept all the defaults. If you are using just the Visual Studio 2005
Professional product with SQL Server Express, or if you installed a copy of SQL Server 2005 using the
default options, you may not have the AdventureWorks database installed. If you are using SQL Server
Express, go to www.microsoft.com/downloads and search on AdventureWorksDB.msi for the
download. Open the MSI by double-clicking it to activate the Windows installer that will extract the
AdventureWorks_data.mdf and AdventureWorks_ldf into the file path C:Program FilesSQL
Server 2000 Sample Databases. Follow the instructions in the Readme file to run the installation
scripts that will install the database.
If you installed SQL Server 2005 with the default options, you have two ways to get AdventureWorks
up and running. You can download the AdventureWorksDB.msi and install it as well, or you can go to
Control Panel ➪ Add Remove Programs and click the Change button. When the wizard comes up, click
the link to add new components. You’ll be asked to point to the setup.exe on the installation disk and
then follow the Setup Wizard to add the AdventureWorks database.
A common issue is not being able to connect to the SQLExpress instance within Visual Studio Data
Connections because of the instancing of the SQLExpress engine. To connect, use the server name
.SQLEXPRESS or replace the “.” with your machine name.
The Mechanics of a Creating and Deploying
a CLR Routine
The procedural aspects of creating, deploying, and using a CLR-based routine in SQL Server will seem
straightforward after you do a few of them. Figure 2-1 shows each step graphically. The steps are simply:
1. Create a public class using a .NET language using at least one static method as an entry point.
2. Compile the class into a .NET DLL file.
3. Load the DLL file into a target database using a new DDL CREATE ASSEMBLY T-SQL statement.
18
42. Your First CLR Stored Procedure
4. Wrap a DLL entry point in the loaded assembly with a T-SQL object using standard DDL T-SQL
statements for the object type (stored procedure, function, trigger, and so on) with an additional
reference to the loaded assembly.
Class Definition
(source class file)
“Traditional”
Programmar’s File System Based
Arena
Binary Assembly
(dll file)
Load Assembly info
Database
(dll file in sys catalog)
“Traditional”
SQL Server Based
DBA’s Arena
Wrap Entry Points with
TSQL Objects
Figure 2-1
Figure 2-1 shows immediately that the biggest difference between using SQL-CLR- and T-SQL-based
routines will at first center on who does what. The deployment aspect of SQL CLR routines is solidly in
the court of the DBA. This is because they are usually the only roles with rights to move objects in and
out of production databases. In terms of development, it will probably depend on the skill sets of the
team. For pure T-SQL-based routines, it has traditionally been the responsibility of the developer to
define the interface or prototype of the objects and the role of the DBA to develop and fine-tune the body
of the routine. With the availability of SQL CLR, the DBA will need to be more involved in the design
phase to ensure that the SQL CLR routines are used appropriately. Most DBAs are not going to be happy
finding out at the end of a project that they are going to need to deploy SQL CLR objects that access the
Internet or expose SQL Server entry points in web services. There may be nothing wrong with these type
of deployments, but the DBA is going to want to be involved in these decisions early.
19
43. Chapter 2
The development of the body, or the content of the managed code, may, in the short term, alternate
between the developer and DBA roles. This may be an uncertain set of roles until DBAs and developers
become familiar with the capabilities and limitations of the target .NET language being used in their shops.
More likely is that the CLR routines will involve a closer working relationship between developer and DBA
roles to make the use of these routines appropriate and will expand the skills levels of both roles.
Enabling CLR in SQL Ser ver 2005
To get started, you’ll need to enable the Common Language Runtime (CLR) feature for the SQL Server
instance. As part of a more security-sensitive installation process, not all features are installed in SQL
Server by default. This is a marked departure from previous SQL Server 2000 installations. Many shops
that have made the transition to SQL Server 2005 have found that the installation process is more “fussy”
then previously, but most agree that the tradeoff of knowing specifically what features are turned on
makes for a safer, more secure platform. If you are an admin on your machine, navigate to Microsoft SQL
Server 2005 ➪ Configuration Tools ➪ SQL Server Surface Area Configuration menu to invoke the Surface
Area tool. The surface area tool is a Setup Wizard that walks you through administering features that you
want to install or restrict. This tool has the ability to control local and remote servers, but the default
startup points to the local environment. If you are walking through this chapter using a remote develop-
ment server, click on the hypertext label change computer shown in the lower middle of Figure 2-2. Select
the option of a remote computer, and type the name or IP address of the remote SQL Server you wish to
add to the Surface Area Configuration Wizard.
Figure 2-2
20