Tải bản đầy đủ (.pdf) (10 trang)

Microsoft SQL Server 2008 R2 Unleashed- P98 doc

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (395.59 KB, 10 trang )

ptg
914
CHAPTER 28 Creating and Managing Stored Procedures
2009-06-15 19:39:21.570 spid30s Loading ‘Sales.SalesOrderDetail’ into data
cache
2009-06-15 19:39:22.040 spid30s Loading ‘Sales.CurrencyRate’ into data cache
2009-06-15 19:39:22.120 spid30s Loading ‘Sales.Customer’ into data cache
2009-06-15 19:39:22.420 spid30s Loading ‘Sales.SalesOrderHeader’ into data cache
2009-06-15 19:39:23.170 spid30s Loading ‘Sales.CustomerAddress’ into data
cache
2009-06-15 19:39:23.290 spid30s Loading ‘Sales.SalesOrderHeaderSalesReason’
into data cache
2009-06-15 19:39:23.340 spid30s Loading ‘Sales.SalesPerson’ into data cache
2009-06-15 19:39:23.360 spid30s Loading ‘Sales.SalesPersonQuotaHistory’ into
data cache
2009-06-15 19:39:23.380 spid30s Loading ‘Sales.SalesReason’ into data cache
2009-06-15 19:39:23.380 spid30s Loading ‘Sales.Individual’ into data cache
2009-06-15 19:39:23.950 spid30s Loading ‘Sales.SalesTaxRate’ into data cache
2009-06-15 19:39:23.970 spid30s Loading ‘Sales.SalesTerritory’ into data cache
2009-06-15 19:39:24.000 spid30s Loading ‘Sales.SalesTerritoryHistory’ into
data cache
2009-06-15 19:39:24.060 spid30s Loading ‘Purchasing.ShipMethod’ into data
cache
2009-06-15 19:39:24.090 spid30s Loading ‘Sales.ShoppingCartItem’ into data
cache
2009-06-15 19:39:24.100 spid30s Loading ‘Sales.SpecialOffer’ into data cache
2009-06-15 19:39:24.110 spid30s Loading ‘Sales.SpecialOfferProduct’ into data
cache
If you want to disable the automatic execution of all startup procedures, you can use
sp_configure to disable the scan for startup procs configuration option. Setting this
option to 0 disables the running of startup procedures on subsequent SQL Server restarts.


If SQL Server is not currently running and you want to skip running the startup proce-
dures, you can specify Trace Flag 4022 as a startup parameter. You can set the trace flag for
a SQL Server instance by using the SQL Server Configuration Manager. In SQL Server
Configuration Manager, perform the following steps:
1. Click on SQL Server 2008 Services.
2. In the right pane, right-click the SQL Server instance you want to set the trace flag
for and select Properties.
3. Go to the Advanced tab and select the Startup Parameters box.
4. Click the expand arrow to the right of the input field to expand the entire field.
5. Place your cursor at the end of the value and type a semicolon (;).
6. Type -T4022 (see Figure 28.10).
7. Click OK.
Download from www.wowebook.com
ptg
915
Summary
28
Also, if you start SQL Server with minimal configuration (by using the -f flag), the
startup stored procedures are not executed.
Summary
Stored procedures are among the premier features of Microsoft SQL Server. They provide a
number of benefits over using ad hoc SQL, including faster performance; restricted, func-
tion-based access to tables; protection of application code from database changes; and the
ability to simplify complex tasks into a simple stored procedure call.
In the next chapter, you learn how to expand the capabilities of your T-SQL code by creat-
ing and using user-defined functions developed in T-SQL.
FIGURE 28.10 Setting Trace Flag 4022 to prevent startup procedures from executing.
Download from www.wowebook.com
ptg
This page intentionally left blank

Download from www.wowebook.com
ptg
CHAPTER 29
Creating and Managing
User-Defined Functions
IN THIS CHAPTER
. What’s New in SQL Server
2008
. Why Use User-Defined
Functions?
. Types of User-Defined
Functions
. Creating and Managing
User-Defined Functions
. Rewriting Stored Procedures as
Functions
. Creating and Using CLR
Functions
SQL Server provides a number of predefined functions that
are built in to the T-SQL language. The supplied functions
help extend the capabilities of T-SQL, providing the ability
to perform string manipulation, mathematic calculations,
data type conversions, and so on within T-SQL code.
Although SQL Server provides a reasonably extensive set of
functions, you might sometimes wish you had available a
function that is not provided. You could create a stored
procedure to perform custom processing, but you can’t use
the result of a stored procedure in a
WHERE clause or as a
column in a SELECT list. For this type of situation, SQL

Server 2008 provides user-defined functions.
A user-defined function can return a single scalar value, like
the majority of the built-in functions, or it can return a
result set as a table result, similarly to a table variable.
This chapter takes a look at how to create and manage user-
defined functions as well as when it may be better to
rewrite stored procedures as functions.
What’s New in SQL Server 2008
Not much has really changed with user-defined functions
in SQL Server 2008 from SQL Server 2005. No real new
functionality or features have been added beyond the
ability to specify up to 2,100 parameters instead of 1,024.
User-defined functions can still be created in T-SQL or using
the .NET common language runtime (CLR). Being able to
define functions in the CLR significantly extends what you
can do in user-defined functions by opening up the power
and capabilities of the .NET Framework languages. This
Download from www.wowebook.com
ptg
918
CHAPTER 29 Creating and Managing User-Defined Functions
means you can develop functions in SQL Server that are either impossible or very difficult
to achieve using T-SQL alone. Later in this chapter, in the section “Creating and Using
CLR Functions,” you learn about CLR functions and some general guidelines on when to
use CLR functions versus T-SQL functions.
NOTE
This chapter focuses primarily on creating T-SQL functions. For more information and
examples related to creating and coding examples of CLR functions, see Chapter 46,
“SQLCLR: Developing SQL Server Objects ”
Why Use User-Defined Functions?

The main benefit of user-defined functions is that they mean you are not limited to just
the functions SQL Server provides. You can develop your own functions to meet your
specific needs or to simplify complex SQL code. For example, the getdate() function
returns the current system date and time. It always includes both a date component and
time component, with accuracy down to the milliseconds. What if you wanted to return a
datetime value with just the date and have the time always set to midnight? To do this,
you would have to pass the result from getdate() through some other functions to zero
out the time component. The following is one possible solution:
select convert(datetime, convert(date, getdate()))
Each time you wanted just the date, with the time always set to midnight, you would
have to perform this same conversion operation on the result of the getdate() function.
As an alternative, you could create a user-defined function that performs the operations
on getdate() automatically and always returns the current date, with a time value of
midnight, as in this example:
USE bigpubs2008
go
CREATE FUNCTION getonlydate ()
RETURNS datetime
AS
BEGIN RETURN (select convert(datetime, convert(date, getdate())))
END
GO
You could then use the user-defined function in your SQL code in place of the more
complex conversion operation on the getdate() function each time. Like the built-in
system functions, user-defined functions can be used in SELECT lists, SET clauses of UPDATE
statements, VALUES clauses of INSERT statements, as default values, and so on. For
Download from www.wowebook.com
ptg
919
Why Use User-Defined Functions?

example, the following query uses the user-defined function getonlydate() to return the
current date, with a time of midnight:
select dbo.getonlydate()
The following examples show how you could use the getonlydate() user-defined function
in other statements:
USE bigpubs2008
go
CREATE TABLE Orders (
OrderID int IDENTITY (1, 1) NOT NULL Primary Key,
CustomerID nchar (5) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
EmployeeID int NULL ,
OrderDate datetime NULL default dbo.getonlydate(),
RequiredDate datetime NULL ,
ShippedDate datetime NULL
)
go
insert Orders (CustomerID, EmployeeID, RequiredDate)
values (‘BERGS’, 3, dbo.getonlydate() + 7)
go
update Orders
set ShippedDate = dbo.getonlydate()
where OrderID = 1
go
select OrderDate,
RequiredDate,
ShippedDate
from Orders
where OrderDate = dbo.getonlydate()
go
OrderDate RequiredDate ShippedDate


2008-06-03 00:00:00.000 2008-06-10 00:00:00.000 2008-06-03 00:00:00.000
If you use the getonlydate() function consistently when you want to store only dates
with a time value of midnight, searching against datetime columns is easier because you
don’t have to concern yourself with the time component. For example, if you use
getdate() instead of getonlydate(), you have to account for the time component in your
queries against OrderDate to ensure that you find all records for a particular day:
29
Download from www.wowebook.com
ptg
920
CHAPTER 29 Creating and Managing User-Defined Functions
SELECT OrderDate,
RequiredDate,
ShippedDate
from Orders
where OrderDate >= convert(varchar(10), getdate(), 110)
and OrderDate < convert(varchar(10), getdate() + 1, 110)
From this example, you can see how much using the getonlydate() user-defined function
can simplify your queries.
TIP
Another way to avoid the issues related to storing a time component in your date-val-
ued columns in SQL Server 2008 is to use the new DATE data type instead of
DATETIME. This new data type is discussed in more detail in Chapter 42, “What’s New
for Transact-SQL in SQL Server 2008.”
In addition to functions that return scalar values, you can also define functions that
return table results. You can use functions that return table results anywhere in queries
that a table or view can be used, including joins, subqueries, and so on. The following
examples show how to use a user-defined table-valued function that returns a list of valid
book types:

use bigpubs2008
go
create function valid_book_types()
returns TABLE
as
return (SELECT distinct type from titles)
go
select * from dbo.valid_book_types()
go
insert titles
select * from newtitles
where type in (select * from dbo.valid_book_types())
Essentially, this example reduces a query to a simple function that you can now use
anywhere a table can be referenced.
With a few restrictions—which are covered later in this chapter, in the “Creating and
Managing User-Defined Functions” section—you can write all types of functions in SQL
Server to perform various calculations or routines. For example, you could create a T-SQL
function that returns a valid list of code values, a function to determine the number of
days items are backordered, a function to return the average price of all books, and so on.
Plus, with the capability to create CLR-based functions, you can create significantly more
Download from www.wowebook.com
ptg
921
Types of User-Defined Function s
powerful functions than what can be accomplished using T-SQL alone. Examples of CLR-
based functions include a more robust soundex() function, a function to return the factor-
ial of a number, and an address comparison function. The possibilities are nearly endless.
As you have can see, user-defined functions significantly increase the capabilities and flex-
ibility of T-SQL.
Types of User-Defined Functions

SQL Server supports three types of user-defined functions:
. Scalar functions
. Inline table-valued functions
. Multistatement table-valued functions
The next few sections take an in-depth look at the differences between the function types
and how and where you can use them.
Scalar Functions
A scalar function is like the standard built-in functions provided with SQL Server. It
returns a single scalar value that can be used anywhere a constant expression can be used
in a query. (You saw an example of this in the earlier description of the
getonlydate()function.)
A scalar function typically takes one or more arguments and returns a value of a specified
data type. Every T-SQL function must return a result using the RETURN statement. The
value to be returned can be contained in a local variable defined within the function, or
the value can be computed in the RETURN statement. The following two functions are vari-
ations of a function that returns the average price for a specified type of book from the
titles table:
use bigpubs2008
go
CREATE FUNCTION AverageBookPrice(@booktype varchar(12) = ‘%’)
RETURNS money
AS
BEGIN
DECLARE @avg money
SELECT @avg = avg(price)
FROM titles
WHERE type like @booktype
RETURN @avg
END
go

29
Download from www.wowebook.com
ptg
922
CHAPTER 29 Creating and Managing User-Defined Functions
CREATE FUNCTION AverageBookPrice2(@booktype varchar(12) = ‘%’)
RETURNS money
AS
BEGIN
RETURN ( SELECT avg(price)
FROM titles
WHERE type like @booktype)
END
As mentioned earlier in this chapter, a scalar function can be used anywhere a constant
expression can be used. For example, SQL Server doesn’t allow aggregate functions in a
WHERE clause unless they are contained in a subquery. The AvgBookPrice() function lets
you compare against the average price without having to use a subquery:
select title_id, type, price from titles
where price > dbo.AverageBookPrice(‘popular_comp’)
go
title_id type price

PC1035 popular_comp 17.1675
PS2091 psychology 17.0884
When invoking a user-defined scalar function, you must include the schema name. If you
omit the schema name, you get the following error, even if the function is created in your
default schema or exists only in the dbo schema in the database:
select AverageBookPrice(‘popular_comp’)
go
Server: Msg 195, Level 15, State 10, Line 1

‘AverageBookPrice’ is not a recognized function name.
You can return the value from a user-defined scalar function into a local variable in two
ways. You can assign the result to a local variable by using the SET statement or an assign-
ment select, or you can use the EXEC statement. The following commands are functionally
equivalent:
declare @avg1 money,
@avg2 money,
@avg3 money
select @avg1 = dbo.AverageBookPrice(‘popular_comp’)
set @avg2 = dbo.AverageBookPrice(‘popular_comp’)
exec @avg3 = dbo.AverageBookPrice ‘popular_comp’
select @avg1 as avg1, @avg2 as avg2, @avg3 as avg3
go
Download from www.wowebook.com
ptg
923
Types of User-Defined Function s
Warning: Null value is eliminated by an aggregate or other SET operation.
avg1 avg2 avg3

16.0643 16.0643 16.0643
Notice, however, that when you use a function in an EXEC statement, you invoke it simi-
larly to the way you invoke a stored procedure, and you do not use parentheses around
the function parameters. Also, when you invoke a function in the EXEC statement, the
function generates the following warning message: “Warning: Null value is eliminated by
an aggregate or other SET operation.” This warning isn’t generated when the function is
invoked in the SET or SELECT statement. To avoid confusion, you should stick to using the
EXEC statement for stored procedures and invoke scalar functions as you would normally
invoke a SQL Server built-in function.
Table-Valued Functions

A table-valued user-defined function returns a rowset instead of a single scalar value. You
can invoke a table-valued function in the FROM clause of a SELECT statement, just as you
would a table or view. In some situations, a table-valued function can almost be thought
of as a view that accepts parameters, so the result set is determined dynamically. A table-
valued function specifies the keyword TABLE in its RETURNS clause.
Table-valued functions are of two types: inline and multistatement. The two types of table-
valued functions return the same thing, and they are also invoked the same way. The only
real difference between them is the way the function is written to return the rowset. The
next couple sections look at each of these types of table-valued functions.
Inline Table-Valued Functions
An inline table-valued function specifies only the TABLE keyword in the RETURNS clause,
without table definition information. The code inside the function is a single RETURN state-
ment that invokes a SELECT statement. For example, you could create an inline table-
valued function that returns a rowset of all book types and the average price for each type,
where the average price exceeds the value passed into the function:
use bigpubs2008
go
CREATE FUNCTION AveragePricebyType (@price money = 0.0)
RETURNS table
AS
RETURN ( SELECT type, avg(isnull(price, 0)) as avg_price
FROM titles
group by type
having avg(isnull(price, 0)) > @price)
29
Download from www.wowebook.com

×