1. Trang chủ
  2. » Công Nghệ Thông Tin

Microsoft SQL Server 2008 R2 Unleashed- P188 potx

10 80 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 281,35 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Developing Custom Managed Database Objects This chapter examines the deep integration of the .NET Framework with SQL Server 2008.. Developing Custom Managed Database Objects SQL Server 2

Trang 1

This page intentionally left blank

Trang 2

SQLCLR: Developing

SQL Server Objects in

.NET

What’s New for SQLCLR in SQL Server 2008

Developing Custom Managed Database Objects

This chapter examines the deep integration of the NET

Framework with SQL Server 2008 It delves into SQL Server

2008’s support for the creation of custom managed database

objects, otherwise known as SQLCLR.

What’s New for SQLCLR in SQL

Server 2008

Although there are only a few changes to SQLCLR in SQL

Server 2008, including support for multiparameter

aggre-gates, support for large-value data types (such as

nvarchar(MAX)) and support for the new SQL Server 2008

data types (such as dateandtime), SQLCLR itself

intro-duces a wealth of new possibilities for developing with NET

and SQL Server that you should consider leveraging in your

data-driven applications

In the following sections, we give you all the tools you

need to write your own stored procedures, functions,

trig-gers, data types, and aggregate functions in C# or VB NET

Developing Custom Managed

Database Objects

SQL Server 2008 hosts the common language runtime

(CLR), implementing what’s known as the Hosting API The

Hosting API gives SQL Server 2008 full control over the

execution of NET code in a carefully managed environment

that honors the shared resource usage of both SQL Server

and the CLR The CLR provides an execution context far

Trang 3

CHAPTER 46 SQLCLR: Developing SQL Server Objects in NET

safer than that of code you might formerly have run in an extended stored procedure or

COM object under SQL Server 2000 and previous editions

In the sections that follow, you will create one of each of the managed versions of

data-base routines and types You work with both the SQL Server project type in Visual Studio

2008 as well as the T-SQL Data Definition Language (DDL) syntax for managed objects

Finally, you’ll learn about advanced topics such as transaction control in mixed (T-SQL

and managed) environments

An Introduction to Custom Managed Database Objects

The capability to run managed code presents a world of possibilities, yet these features

must be leveraged appropriately The meaning of appropriate will ultimately be the result

of ongoing dialogs between database administrators and the developers who want to use

the NET Framework in SQL Server

Just like SQL Server’s capability to host web services (covered in Chapter 48, “SQL Server

Web Services”), this feature set begins to blur the line between SQL Server as a database

server and SQL Server as a lightweight application server

.NET assemblies are built using Visual Studio or the command-line compilers and then

literally uploaded into the database and loaded into memory on the same physical server

as the SQL Server instance CLR objects may therefore consume valuable server and

network resources

This scenario presents a challenging new management paradigm that database

administra-tors, managers, and developers have to negotiate Administrators are just beginning to

consider strategies for what kinds of NET code they should allow to run and in which

contexts Following are a few general rules to consider regarding when managed objects

should and should not be used:

Data selection and modification should always be performed using T-SQL because

that’s what it’s optimized to do You should not create a T-SQL wrapper in your NET

code

You should use managed code when you need to overcome the procedural

limita-tions of T-SQL, such as avoiding the use of nested cursors that connect to multiple

databases and other awkward constructs (SQL was never developed to be a

proce-dural language, only a set-based query language.)

You should use managed code when you want to extend the per-row or per-set

effects of routines to leverage managed resources, such as XML parsers, web services,

and custom code libraries

The software development staff still must decide what to do, but we can be thankful that

SQL Server has some rules of its own for what kinds of operations can be called and

under which permission sets, as discussed in the following section

Trang 4

FIGURE 46.1 Blessed assemblies in the Add References dialog in Visual Studio 2008

Managed Object Permissions

The first thing to know about managed object permissions is that SQL Server has only

blessed a certain group of assemblies usable under each of the three SQL Server permission

sets

Figure 46.1 shows the Add References dialog for a SQL Server project in Visual Studio

2008, listing these NET Framework assemblies They are the only assemblies (aside from

user-created assemblies) that can be referenced in SQL Server projects Note that this list

doesn’t change in Visual Studio, regardless of the permission set used Note also that SQL

Server and/or Visual Studio walks down the reference chain to see whether any

refer-enced assemblies reference anything that is not blessed Therefore, you shouldn’t bother

trying to get around this list; there isn’t even a Browse button on the dialog box as there

is with the other project types

The Three Permission Sets

SQL Server has three built-in NET Code Access Security (CAS) permission sets that define

which kinds of operations can be executed at runtime Using the CAS layer is a huge

improvement over running extended stored procedures under default login credentials

because it allows for fine-grained permission granting and revocation

These are the permission sets, in increasing order of freedom:

SAFE

EXTERNAL_ACCESS

UNSAFE

These keywords are used in the DDL syntax for assemblies

Trang 5

CHAPTER 46 SQLCLR: Developing SQL Server Objects in NET

Assuming that you have built an assembly targeted for SQL Server use (which you do in

the next section), you can use the following syntax for loading that assembly into your

database of choice:

CREATE ASSEMBLY AssemblyName [AUTHORIZATION LoginName]

FROM StringPathToAssemblyDll | BinaryDataValue

[WITH PERMISSION_SET (SAFE | EXTERNAL_ACCESS | UNSAFE) ]

This syntax is reasonably self-explanatory: you tell SQL Server the name of the assembly

and the path (using a UNC if needed) to it If you’re loading an assembly from a

varbinarycolumn, you supply the actual data that makes up the compiled code of the

assembly instead of the path to it (Visual Studio does this)

NOTE

CREATE ASSEMBLYandALTER ASSEMBLYare commands used by Visual Studio’s Deploy

feature, which does the managed code DDL work for you

TheWITH PERMISSION SETclause is optional, and it defaults to SAFE Marking an assembly

with the SAFEpermission set indicates that no external resources (for example, the

Registry, web services, file I/O) are going to be accessed The DDL will fail if assemblies

such as System.IOare referenced, and anything causing a permission demand for

execut-ing similar operations will result in an exception beexecut-ing thrown at runtime Markexecut-ing an

assembly with the EXTERNAL_ACCESSpermission set tells SQL Server that it will be using

resources such as networking, files, and so forth Assemblies such as System.Web.Services

(but not System.Web) may be referenced with this set

Marking an assembly with theUNSAFEpermission set tells SQL Server that not only might

external resources be used, but unmanaged code may even be invoked from managed code

Some assemblies in the NET Framework go so far as to tell the processes that ultimately

host them (such as SQL Server or Internet Explorer) about their relative safety, using a

specific NET attribute: HostProtectionAttribute(HPA)

The enumeration flags of the HPA’s parameter indicate to the host what kinds of

opera-tions the classes decorated with it may attempt Because documentation of the HPA with

regards to SQL Server is scant, it’s unclear whether SQL Server ultimately relies on the HPA

to determine what may be loaded (It seems to do so at runtime, but the blessed list is

likely to be hard coded.)

Following are some of the operations you cannot perform with NET code running under

SQL Server’s SAFEandEXTERNAL_ACCESSoptions (but possibly under UNSAFE):

Thread synchronization

External process management

Framework security changes

Use of non-read-only static fields

Trang 6

Only those in the sysadminrole can upload UNSAFEassemblies to SQL Server (Just don’t

tell your DBA we told you how to do it.)

TheEXTERNAL_ACCESSpermission on masteris required for uploading EXTERNAL_ACCESS

assemblies And anyone in the db_ownerrole may load SAFEassemblies

Developing Managed Objects with Visual Studio 2008

When SQL Server 2008 is installed, it includesMicrosoft.SqlServer.Server, the

assem-bly that contains the attributes and other classes needed for SQLCLR (the common

acronym for managed code running in SQL Server) programming

The first step in working with SQLCLR is to enable the feature in SQL Server

Setting Up the Server for Managed Code Execution

Before you can work with managed database objects, you need to execute the following

T-SQL commands in the context of the masterdatabase:

sp_configure ‘clr enabled’, 1

RECONFIGURE

go

This step is necessary because SQL Server comes with managed code execution turned off

by default

At this point, you’re ready to create your first SQLCLR project using Visual Studio 2008

(VS) Start VS and create a new C#-based SQL Server project with a name of your choosing

(the example is named SQL2008SQLCLR) Figure 46.2 shows the Add New Project dialog

FIGURE 46.2 Using the Add New Project dialog in Visual Studio 2008 to create a SQLCLR

project

Trang 7

CHAPTER 46 SQLCLR: Developing SQL Server Objects in NET

Next, VS asks you to create or add a reference to a database to which you will deploy your

new assembly During deployment, your assembly (and with it, all its SQLCLR types and

routines) is uploaded directly into SQL Server’s system tables Select AdventureWorks2008

so you can work with the examples that follow

Next, you create your first managed SQL Server object, a stored procedure written in C#

Developing Managed Stored Procedures

Stored procedures are a great starting point for getting into SQLCLR because they are easy

to implement To do so, right-click your new project in VS’s Solution Explorer and then

select Add, Stored Procedure Name your new class StoredProcedures.cs A partial class of

that name opens in the VS code window Note that VS automatically adds the required

reference to Microsoft.SqlServer.Serverand its associated usingstatement

Microsoft.SqlServer.Servercontains the SqlProcedureattribute required for turning

ordinary methods into SQLCLR stored procedures

Change your autogenerated method name from StoredProcedurestoGetProductReviews

Next, if you’re not working in VS, you need to decorate this method with the

SqlProcedureattribute

Attributes and the Implementation Contract

If you’ve never used attributes, you can think of them as metadata that tells callers,

usually through reflection, that the decorated element (known as the target) meets some

criterion All the managed objects you create in this chapter require certain attributes to

be applied; otherwise, they cannot be used in a SQL Server context

The classes you build must also implement particular methods and/or method signatures

to be built and deployed successfully to SQL Server This is known as fulfilling the

imple-mentation contract For stored procedures, fulfilling this contract requires that your method

be marked static Its return type must be one of the following: void,Int32,

Nullable<Int32>,orSqlInt32 Its input parameters and their types are up to you, but

keep in mind that these must be convertible from a T-SQL context to a NET context

These are the only contract requirements to be filled for stored procedures

NOTE

It makes sense that these methods must be marked staticbecause they are called

by the CLR host via the class’s type object, rather than via an object instance (that is,

AssemblyName.ClassName.StaticMethodName(Parameters) ).

Object-oriented (OO) purists might suggest that this way of creating managed SQL Server

objects could have been done in a more OO-friendly way if the contract to be filled

required overriding the methods of an abstract class or implementing interfaces The static

requirement, however, currently makes this impossible because static members are not

inherited and cannot be used to implement interface members

Trang 8

The constructor for the SqlProcedureattribute is overloaded to either take zero parameters

or take one parameter that is actually a list of named parameters (Having a list of named

parameters in the attribute signature is common to most of the attributes used in this

chapter, although the choice of named parameter pairs varies from attribute to attribute.)

For theSqlStoredProcedureAttribute, only one named parameter exists:Name You use

Namewhen you want to name the method one thing but have the name it generates for

use in a T-SQL context to be another name

The code in Listing 46.1 illustrates the use of a named parameter in this attribute and

contains a simple example of how to generate a set of rows using SQLCLR

LISTING 46.1 A Managed Stored Procedure That Generates a Set of Rows

[SqlProcedure(Name = “clr_GetProductManuals”)]

public static void GetProductManuals()

{

using (SqlConnection ContextConnection =

new SqlConnection(“context connection=true”))

{

SqlDataRecord record =

new SqlDataRecord(

new SqlMetaData[]

{

new SqlMetaData(“ProductModelId”, SqlDbType.Int),

new SqlMetaData(“Manual”, SqlDbType.Xml)

}

);

SqlContext.Pipe.SendResultsStart(record);

using (SqlCommand Command = new SqlCommand())

{

Command.CommandText =

@”SELECT TOP 10 ProductModelId, Instructions FROM Production.ProductModel

WHERE Instructions IS NOT NULL”;

Command.Connection = ContextConnection;

ContextConnection.Open();

using (SqlDataReader reader = Command.ExecuteReader())

{

while (reader.Read()) {

Trang 9

CHAPTER 46 SQLCLR: Developing SQL Server Objects in NET

int ProductModelId = reader.GetInt32(0);

SqlXml ManualXml = reader.GetSqlXml(1);

record.SetInt32(0, ProductModelId);

record.SetSqlXml(1, ManualXml);

SqlContext.Pipe.SendResultsRow(record);

} }

SqlContext.Pipe.SendResultsEnd();

}

}

}

Although this example does not require it, if your SQLCLR code needs to access server

resources (such as files), it would be necessary to change your assembly’s permission set

from the default ofSAFEtoEXTERNAL_ACCESS To do to this in VS, right-click your project

in Solution Explorer and select Properties Then, on the left side of the window, select the

Database tab (Note that the Database tab is the place where VS stores a connection string

matching your database reference You can change that here as well.) Under the Permission

Level drop-down, change the value from Safe to External and save the project You can also

type in the name of the SQL Server login (under Assembly Owner), which will be specified

for theAUTHORIZATIONparameter ofCREATE ASSEMBLYduring deployment by VS

The idea behind the code in Listing 46.1 is that, given a set of rows from

Production.ProductModel, the procedure generates a result set of only those products that

have a reference manual Let’s examine the new objects in this code

The Context Connection

In our managed procedure, we use a special ADO.NET connection string (”context

connection=true”), known as the context connection string, to connect to the session of

SQL Server under which our managed stored procedure is currently executing (that is,

once the assembly has been deployed and is running in a T-SQL context)

Objects in Microsoft.SqlServer.Server

Our managed procedure also uses some specialized objects to send data to SQL Server

through the active connection:

SqlContext—This represents the server execution context for the managed routine

You can think of it as the line of communication between the NET and SQL Server

environments

SqlContext.PipeSqlContextholds the crucial Pipeproperty, used to send

SqlDataRecordobjects or text messages to the method’s caller, which, by the way,

may be either another managed routine (via ADO.NET) or any T-SQL user code

Trang 10

SqlDataRecord—This is an abstraction that represents a record in any given table

The schema of columns for a SqlDataRecordobject is created by using SqlMetaData

objects, as shown in Listing 46.1

SqlMetaData—An array of SqlMetaDataobjects is passed to the constructor of each

SqlDataRecord Each SqlMetaDataobject defines the name, type, precision, scale,

and so forth for its target column via its overloaded constructors

Returning to the code in Listing 46.1, before looping through ourSqlDataReaderobject

(reader), we callPipe.SendResultsStart, passing aSqlDataRecordobject whose

struc-ture matches our desired output This tells SQL Server that our procedure is about to

send rows (to the caller) having a specific structure

Looping through the reader (using while (reader.Read())), we select the values to be

returned To do this, we use the Set[DataTypeName]methods on our SqlDataRecordobject

calledrecord When our values are all set, we call

SqlContext.Pipe.SendResultsRow(record)to return these data

After the code has finished sending data to the client, it cleans up by calling

Pipe.SendResultsEnd Note that the Pipeobject also has an ExecuteAndSendmethod that

takes a SqlCommandparameter, executes it, and sends all the results back to the caller in

one fell swoop In addition, you can query the status of the Pipeobject by checking its

IsSendingResultsBoolean property You can even send an informational text message

(similar to T-SQL’s printfunction) to the caller, using Pipe.Send(”Text”).Send()is

over-loaded to accept a SqlDataRecordobject or a SqlDataReaderobject that contains the data

to be returned

Building and Deploying the Assembly

At this point, you can build the VS project and then choose the new Deploy command

from VS’s Build menu In this step, VS generates the T-SQL DDL scripts needed to upload

our assembly to SQL Server and then add our managed stored procedure to the

AdventureWorks2008database

You’ve already seen the CREATE ASSEMBLYDDL that VS uses For now, let’s assume that

you’ve already uploaded the assembly once In this scenario, you need to execute the

following T-SQL to replace that assembly with a newly compiled version of the same:

ALTER ASSEMBLY AssemblyName

[AUTHORIZATION LoginName]

FROM StringPathToAssemblyDll | BinaryDataValue

[PERMISSION_SET = (SAFE | EXTERNAL_ACCESS | UNSAFE) ]

You can also use ALTER ASSEMBLYto upload your C# class files so that when you’re

debug-ging any exceptions you get source code line numbers in the stack dump (seamlessly

reported by SQL Server’s built-in error reporting mechanism) Here’s an example:

ALTER ASSEMBLY AssemblyName ADD FILE FROM FilePath

Ngày đăng: 05/07/2014, 02:20