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

Microsoft SQL Server 2008 R2 Unleashed- P100 ppt

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 (432.13 KB, 10 trang )

ptg
934
CHAPTER 29 Creating and Managing User-Defined Functions
FIGURE 29.4 Creating a new function template in SSMS.
Listing 29.2 shows an example of a new function template.
LISTING 29.2 An Example of Custom Function Template
=========================================
SQL Server 2008 Unleashed Sample
Create scalar-valued function template
=========================================
USE <database_name, sysname, bigpubs2008>
GO
IF OBJECT_ID (N’<schema_nm, sysname, dbo>.<func_nm, sysname, fn_myfunc>’)
IS NOT NULL
DROP FUNCTION <schema_nm, sysname, dbo>.<func_nm, sysname, fn_myfunc>
GO
CREATE FUNCTION <schema_nm, sysname, dbo>.<func_nm, sysname, fn_myfunc>
(<parameter1, sysname, @param1> <parameter1_datatype,, int>,
<parameter2, sysname, @param2> <parameter2_datatype,, int>,
<parameter3, sysname, @param3> <parameter3_datatype,, int>)
RETURNS <return_value_datatype,,int>
WITH EXECUTE AS CALLER
AS
place the body of the function here
Download from www.wowebook.com
ptg
935
Creating and Managing User-Defined Functions
29
BEGIN
DECLARE <variable1, sysname, @var1> <variable1_datatype,, int>,


<variable2, sysname, @var2> <variable2_datatype,, int>
select <variable1, sysname, @var1> = isnull(<parameter1, sysname, @param1> )
<T-SQL_Body,,>
RETURN <variable1, sysname, @var1>
END
GO
After you define a custom function template, you can use it as you do the built-in
templates. You can double-click it or right-click and select Open, and SSMS opens a new
query window with a new function creation script based on the custom template. If you
use the default values for the template parameters, after the parameter substitution, your
CREATE FUNCTION script should look like the one in Listing 29.3.
LISTING 29.3 An Example of a CREATE FUNCTION Script Generated from a Custom
Function Template
=========================================
SQL Server 2008 Unleashed Sample
Create scalar-valued function template
=========================================
USE bigpubs2008
GO
IF OBJECT_ID (N’dbo.fn_myfunction’) IS NOT NULL
DROP FUNCTION dbo.fn_myfunction
GO
CREATE FUNCTION dbo.fn_myfunction
(@param1 int,
@param2 int,
@param3 int)
RETURNS int
WITH EXECUTE AS CALLER
AS
place the body of the function here

BEGIN
DECLARE @var1 int,
@var2 int
Download from www.wowebook.com
ptg
936
CHAPTER 29 Creating and Managing User-Defined Functions
select @var1 = isnull(@param1 )
RETURN @var1
END
GO
Viewing and Modifying User-Defined Functions
Besides using T-SQL commands to create functions, you can also use them to view and
modify functions. You can get information by using the provided system procedures and
queries against the INFORMATION_SCHEMA.routines view. The following sections describe
these methods.
Using T-SQL to View Functions
To view the source code for a user-defined function, you can use the sp_helptext procedure:
use bigpubs2008
go
exec sp_helptext getonlydate
go
Text

CREATE FUNCTION getonlydate ()
RETURNS datetime
AS
BEGIN RETURN (select convert(datetime, convert(date, getdate())))
END
NOTE

To display t he source code for the fu nctions clear ly, configure th e SSMS quer y w indow
to display results as text rather than in the grid by pressing Ctrl+T.
In addition to sp_helptext, you can write queries against the
INFORMATION_SCHEMA.routines view to display the source code for a function:
SELECT routine_definition
from INFORMATION_SCHEMA.routines
where routine_name = ‘getonlydate’
and specific_schema = ‘dbo’
Download from www.wowebook.com
ptg
937
Creating and Managing User-Defined Functions
29
and specific_catalog = ‘bigpubs2008’
routine_definition

CREATE FUNCTION getonlydate ()
RETURNS datetime
AS
BEGIN RETURN (select convert(datetime, convert(date, getdate())))
END
If you want to display information about the input parameters for a function, you use the
INFORMATION_SCHEMA.parameters view. For scalar functions, the view also displays informa-
tion for the return parameter, which has an ordinal position of 0 and no parameter name:
select substring(parameter_name,1,20) as parameter_name,
substring(data_type, 1, 20) as data_type,
Parameter_mode,
ordinal_position
from INFORMATION_SCHEMA.parameters
where specific_name = ‘striptime’

and specific_schema = ‘dbo’
and specific_catalog = ‘bigpubs2008’
order by ordinal_position
go
parameter_name data_type Parameter_mode ordinal_position

datetime OUT 0
@datetimeval datetime IN 1
If you want to display information about the result columns returned by a table-valued
function, use the INFORMATION_SCHEMA.routine_columns view:
select substring(column_name, 1, 20) as column_name,
substring (data_type, 1, 12)
+ case when character_maximum_length is not null
then ‘(‘ + cast(character_maximum_length as varchar(4)) + ‘)’
else ‘’
end
as datatype,
numeric_precision as ‘precision’,
numeric_scale as scale,
ordinal_position
from INFORMATION_SCHEMA.routine_columns
where table_name = ‘AveragePricebyType’
order by ordinal_position
go
Download from www.wowebook.com
ptg
938
CHAPTER 29 Creating and Managing User-Defined Functions
column_name datatype precision scale ordinal_position


type char(12) NULL NULL 1
avg_price money 19 4 2
In addition, SQL Server provides the OBJECTPROPERTY function, which you can use to get
information about functions. One of the things you can find out is whether a function is a
multistatement table function, an inline function, or a scalar function. The OBJECTPROPERTY
function accepts an object ID and an object property parameter, and it returns the value 1 if
the property is true, 0 if it is false, or NULL if an invalid function ID or property parameter is
specified. The following property parameters are appropriate for functions:
. IsTableFunction—Returns 1 if the function is a table-valued function but not an
inline function.
. IsInlineFunction—Returns 1 if the function is an inline table-valued function.
. IsScalarFunction—Returns 1 if the function is a scalar function.
. IsSchemaBound—Returns 1 if the function was created with the SCHEMABINDING
option.
. IsDeterministic—Returns 1 if the function is deterministic (that is, it always
returns the same result each time it is called with a specific set of input values).
The following example demonstrates a possible use of the OBJECTPROPERTY function with
the INFORMATION_SCHEMA.routines view:
select convert(varchar(10), specific_Schema) as ‘schema’,
convert(varchar(20), specific_name) as ‘function’,
case objectproperty(object_id(specific_name), ‘IsScalarFunction’)
when 1 then ‘Yes’ else ‘No’ end as IsScalar,
case objectproperty(object_id(specific_name), ‘IsTableFunction’)
when 1 then ‘Yes’ else ‘No’ end as IsTable,
case objectproperty(object_id(specific_name), ‘IsInlineFunction’)
when 1 then ‘Yes’ else ‘No’ end as IsInline,
case objectproperty(object_id(specific_name), ‘IsSchemaBound’)
when 1 then ‘Yes’ else ‘No’ end as IsSchemaBnd,
case objectproperty(object_id(specific_name), ‘IsDeterministic’)
when 1 then ‘Yes’ else ‘No’ end as IsDtrmnstc

from information_Schema.routines
where routine_type = ‘FUNCTION’
order by specific_name
go
schema function IsScalar IsTable IsInline IsSchemaBnd IsDtrmnstc

dbo AverageBookPrice Yes No No No No
Download from www.wowebook.com
ptg
939
Creating and Managing User-Defined Functions
29
dbo AverageBookPrice2 Yes No No No No
dbo AveragePricebyType No Yes Yes No No
dbo AveragePricebyType2 No Yes No Yes Yes
dbo getdateonly Yes No No No No
dbo getonlydate Yes No No No No
dbo striptime Yes No No No No
dbo striptime2 Yes No No No No
Using T-SQL to Modify Functions
You can use the ALTER FUNCTION command to change a function’s definition without
having to drop and re-create it. The syntax for the ALTER FUNCTION command is identical
to the syntax for CREATE FUNCTION, except that you replace the CREATE keyword with the
ALTER keyword. The following example modifies the AveragePricebyType2 function:
ALTER FUNCTION AveragePricebyType2 (@price money = 0.0)
RETURNS @table table (type varchar(12) null, avg_price money null)
with schemabinding
AS
begin
insert @table

SELECT type, avg(price) as avg_price
FROM dbo.titles
group by type
having avg(price) > @price
order by avg(price) desc
return
end
Using the ALTER FUNCTION command has a couple advantages over dropping and re-creat-
ing a function to modify it. The main advantage, as mentioned earlier, is that you don’t
have to drop the function first to make the change. The second advantage is that, because
you don’t have to drop the function, you don’t have to worry about reassigning permis-
sions to the function. To determine whether a function has been altered since it was
created, you can query the LAST_ALTERED column in the INFORMATION_SCHEMA.routines
view for that function.
One limitation of the ALTER FUNCTION command is that you cannot use this command to
change a table-valued function to a scalar function or to change an inline function to a
multistatement function. You have to drop and re-create the function.
Using SSMS to View and Modify Functions
To view or edit a function within SSMS, open the Object Explorer to the database in
which you want to create the function. Then select the Programmability node, right-click
the Functions node, and then select either the Table-Valued Functions folder or the Scalar-
Valued Functions folder. SSMS then displays a list of the functions of that type defined in
that database within the Object Explorer as well as in the Summary window.
Download from www.wowebook.com
ptg
940
CHAPTER 29 Creating and Managing User-Defined Functions
FIGURE 29.5 The Options menu for viewing and editing functions in SSMS.
NOTE
If the function you want to view or edit is not shown in the list, it was probably created

after the list of functions in the Object Explorer was populated. You might need to
refresh the function list in Object Explorer. To do this, you right-click the Functions
folder and choose Refresh.
When you right-click a function name in either the Object Explorer or the Summary
window, you are presented with a number of options for viewing or modifying the func-
tion, as shown in Figure 29.5.
You can view or edit the function properties, view the function dependencies, delete the
function, rename it, modify it, or script the function definition. If you choose to edit the
function by clicking Modify, SSMS opens a new query window with the source code of the
function extracted from the database as an ALTER FUNCTION command. You can edit the
function as needed and execute the code in the query window to modify the function.
There are also options for scripting a function as a CREATE, ALTER, DROP, or SELECT
command to either a new query window, a file, or the Clipboard, as shown in Figure 29.6.
You can also view the function properties by selecting the Properties option from the
context menu. The Properties dialog appears, as shown in Figure 29.7. Unfortunately, except
for the function permissions and extended properties, the properties shown are read-only.
For more information on the features and options for SSMS and for scripting objects, see
Chapter 4, “SQL Server Management Studio.”
Download from www.wowebook.com
ptg
941
Creating and Managing User-Defined Functions
29
FIGURE 29.6 Options for scripting functions in SSMS.
FIGURE 29.7 The Function Properties dialog in SSMS.
Managing User-Defined Function Permissions
When a function is initially created, the only user who has permission to execute the
function is the user who created it. To allow other users to execute a scalar function, you
need to grant EXECUTE permission on the function to the appropriate user(s), group(s), or
Download from www.wowebook.com

ptg
942
CHAPTER 29 Creating and Managing User-Defined Functions
role(s). For a table-valued function, you need to grant SELECT permission to the user(s),
group(s), or role(s) that will need to reference it. The following example grants EXECUTE
permission on the getonlydate() function to everyone and SELECT permission on the
AveragePriceByType function to the database user fred:
GRANT EXECUTE on dbo.getonlydate to public
GRANT SELECT on AveragePricebyType to fred
For more detailed information on granting and revoking permissions, see Chapter 11,
“Security and User Administration.”
In SQL Server 2008, you can also specify the execution context of scalar-valued and multi-
statement, table-valued, user-defined functions. Essentially, this capability allows you to
control which user account is used to validate permissions on objects referenced by the
function, regardless of what user is actually executing the function. This provides
additional flexibility and control in managing permissions for user-defined functions and
the objects they reference. Only EXECUTE or SELECT permissions need to be granted to
users on the function itself; you do not have to grant them explicit permissions on the
referenced objects. Only the user account defined as the execution context for the func-
tion by the EXECUTE AS clause must have the necessary permissions on the objects the
function accesses.
For example, in the following SQL script, the AverageBookPrice2 function is modified to
run within the context of the dbo user. Any user who invokes this function essentially
inherits the permissions of the dbo user on any objects accessed within the scope of the
function temporarily for the execution of the function:
ALTER FUNCTION [dbo].[AverageBookPrice2](@booktype varchar(12) = ‘%’)
RETURNS money
WITH EXECUTE AS ‘dbo’
AS
BEGIN

RETURN ( SELECT avg(price)
FROM titles
WHERE type like @booktype)
END
GO
Rewriting Stored Procedures as Functions
In releases of SQL Server prior to SQL Server 2000, if you wanted to do custom processing
within SQL code, your only real option was to create stored procedures to do things that
often would have worked much better as functions. For example, you couldn’t use the
result set of a stored procedure in a WHERE clause or to return a value as a column in a
select list. Using a stored procedure to perform calculations on columns in a result set
often required using a cursor to step through each row in a result set and pass the column
Download from www.wowebook.com
ptg
943
Rewriting Stored Procedures as Functions
29
values fetched, one at a time, to the stored procedure as parameters. This procedure then
typically returned the computed value via an output parameter, which had to be mapped
to another local variable. Another alternative was to retrieve the initial result set into a
temporary table and then perform additional queries or updates against the temporary
table to modify the column values, which often required multiple passes. Neither of these
methods was an efficient means of processing the data, but prior to SQL Server 2000, few
alternatives existed. If you needed to join against the result set of a stored procedure, you
had to insert the result set into a temporary table first and then join against the tempo-
rary table, as shown in the following code fragment:

insert #results exec result_proc
select * from other_Table
join #results on other_table.pkey = #results.keyfield


Now that SQL Server supports user-defined functions, you might want to consider rewrit-
ing some of your old stored procedures as functions to take advantage of the capabilities of
functions and improve the efficiency of your SQL code. You mainly want to do this in situ-
ations in which you would like to be able to invoke a stored procedure directly from
within a query. If the stored procedure returns a result set, it is a candidate for being
written as a table-valued function. If it returns a scalar value, usually via an output parame-
ter, it is a candidate for being written as a scalar function. However, the following criteria
also are indications that a procedure is a good candidate for being rewritten as a function:
. The procedure logic is expressible in a single SELECT statement; however, it is
written as a stored procedure, rather than a view, because of the need for it to be
parameter driven.
. The stored procedure does not perform update operations on tables, except against
table variables.
. There are no dynamic SQL statements executed via the EXECUTE statement or
sp_executesql.
. The stored procedure returns no more than a single result set.
. If the stored procedure returns a result set, its primary purpose is to build an inter-
mediate result that is typically loaded into a temporary table, which is then queried
in a SELECT statement.
The result_proc stored procedure, used earlier in this section, could possibly be rewritten as
a table-valued function called fn_result(). The preceding code fragment could then be
rewritten as follows:
SELECT *
FROM fn_results() fn
join other_table o.pkey = fn.keyfield
Download from www.wowebook.com

×