Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 76 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
76
Dung lượng
445,82 KB
Nội dung
Chapter 9: Special Types of Procedures 363 @@IDLE @@TOTAL_READ @@IO_BUSY @@TOTAL_WRITE @@MAX_CONNECTIONS GETDATE @@PACK_RECEIVED NEWID @@PACK_SENT RAND @@PACKET_ERRORS TEXTPTR Notice that GetDate() is also among the forbidden functions. If you try to use it inside a user-defined function, SQL Server will report an error as shown in Figure 9-5. Figure 9-5. A limitation on use of built-in functions in user-defined functions Encryption As is the case with stored procedures, functions can be encrypted so that nobody can see their source code. The developer just needs to create or alter the function using the With Encryption option. Schema-Binding A new option, With Schemabinding, allows developers to schema-bind a user-defined function to database objects (such as tables, views, and other used-defined functions) that it references. Once the function is schema-bound, it is not possible to make schema changes on underlying objects. All attempts to drop the objects and all attempts to Alter underlying objects (which would change the object schema) will fail. A function can be schema-bound only if all of the following criteria are satisfied: ▼ All user-defined functions and views referenced by the function must already be schema-bound. ■ All database objects that the function references must reside in the same database as the function. References to database objects cannot have server or database qualifiers. Only object owner qualifiers and object identifiers are allowed. ▲ The user who executes the Create (or Alter) Function statement has References permissions on all referenced database objects. Table-Valued User-Defined Functions Since SQL Server 2000 has a table datatype, it is possible to design a user-defined function that returns a table. The primary use of table-valued user-defined functions is similar to the use of views. However, these functions are far more flexible and provide additional functionality. You can use a table-valued user-defined function anywhere you can use a table (or view). In this respect, they implement the functionality of views, but functions can have parameters and 364 SQL Server 2000 Stored Procedure Programming therefore they are dynamic. Views are also limited to a single Select statement. Functions can have one or more Transact-SQL statements inside and in this way implement more complex functionality. That is why functions of this type are often referred to as multi-statement table-valued user-defined functions. Stored procedures can also return a resultset, but the use of such resultsets is somewhat limited. For example, only a resultset returned by a function can be referenced in the From clause of a Select statement. Let’s demonstrate this functionality. The following Select statement references the user-defined function fnDueDays, which returns a list of lease payment due dates. The statement returns a list of remaining payments and due dates: select DD.TermId, DD.DueDate, Inventory.Lease from dbo.fnDueDays('1/1/2000','1/1/2004','monthly') DD, Inventory where InventoryId = 8 and DD.DueDate > GetDate() The result will look like this: TermId DueDate Lease 3 2000-04-01 00:00:00 87.7500 4 2000-05-01 00:00:00 87.7500 5 2000-06-01 00:00:00 87.7500 6 2000-07-01 00:00:00 87.7500 7 2000-08-01 00:00:00 87.7500 Stored procedure prListTerms has functionality similar to the functionality of the DueDates function. But to perform additional filtering of the resultset returned by the stored procedure, the developer would first need to receive the resultset into a temporary table: Create Table #tbl(TermId int, DueDate smalldatetime) Insert Into #Tbl(TermId, DueDate) Exec prListTerms '1/1/2000','1/1/2004','monthly' Select #tbl.TermId, #tbl.DueDate, Inventory.Lease Chapter 9: Special Types of Procedures 365 From #tbl, Inventory Where InventoryId = 8 And #tbl.DueDate > GetDate() Drop Table #tbl This is much more complicated than using the comparable function. Let’s investigate the internals of the fnDueDate function: Create Function fnDueDays return list of due days for the leasing ( @dtsStartDate smalldatetime, @dtsEndDate smalldatetime, @chvLeaseFrequency varchar(20) ) Returns @tblTerms table ( TermID int, DueDate smalldatetime ) As Begin Declare @insTermsCount smallint number of intervals Declare @insTerms smallint number of intervals calculate number of terms Select @insTermsCount = Case @chvLeaseFrequency When 'monthly' then DateDIFF(month, @dtsStartDate, @dtsEndDate) When 'semi-monthly' then 2 * DateDIFF(month, @dtsStartDate, @dtsEndDate) When 'bi-weekly' then DateDIFF(week, @dtsStartDate, @dtsEndDate)/2 When 'weekly' then DateDIFF(week, @dtsStartDate, @dtsEndDate) 366 SQL Server 2000 Stored Procedure Programming When 'quarterly' then DateDIFF(qq, @dtsStartDate, @dtsEndDate) When 'yearly' then DateDIFF(y, @dtsStartDate, @dtsEndDate) End generate list of due dates Set @insTerms = 1 While @insTerms <= @insTermsCount Begin Insert @tblTerms (TermID, DueDate) Values (@insTerms, Convert(smalldatetime, CASE When @chvLeaseFrequency = 'monthly' then DateADD(month,@insTerms, @dtsStartDate) When @chvLeaseFrequency = 'semi-monthly' and @insTerms/2 = Cast(@insTerms as float)/2 then DateADD(month, @insTerms/2, @dtsStartDate) When @chvLeaseFrequency = 'semi-monthly' and @insTerms/2 <> Cast(@insTerms as float)/2 then DateADD(dd, 15, DateADD(month, @insTerms/2, @dtsStartDate)) When @chvLeaseFrequency = 'bi-weekly' then DateADD(week, @insTerms*2, @dtsStartDate) When @chvLeaseFrequency = 'weekly' then DateADD(week, @insTerms, @dtsStartDate) When @chvLeaseFrequency = 'quarterly' then DateADD(qq, @insTerms, @dtsStartDate) When @chvLeaseFrequency = 'yearly' then DateADD(y, @insTerms, @dtsStartDate) End , 105)) Select @insTerms = @insTerms + 1 End Return End Chapter 9: Special Types of Procedures 367 368 SQL Server 2000 Stored Procedure Programming Let me point out to you a few differences between these functions and scalar functions. User-defined functions that return a table have a table variable definition in the Returns clause: Returns @tblTerms table ( TermID int, DueDate smalldatetime ) In the body of the function, there are statements that fill the contents of the table variable: Insert @tblTerms (TermID, DueDate) Values (@insTerms, Convert(smalldatetime, CASE When @chvLeaseFrequency = 'monthly' The Return statement at the end of the function does not specify a value. As soon as it is reached, SQL Server returns the contents of the table variable to the caller: Return End In-Line Table-Valued User-Defined Functions An in-line table-valued user-defined function is a special type of table-valued user-defined function. Its purpose is to implement parameterized views. The syntax of an in-line table-valued user-defined function is a bit different from the syntax of other functions: Chapter 9: Special Types of Procedures 369 Create Function [owner_name.]function_name ( [ {@parameter_name scalar_data_type [= default]} [, n] ] ) Returns Table [With {Encryption|Schemabinding}[, n] ] [As] | Return (select-stmt) You do not have to define the format of the return value. It is enough to specify just the table keyword. An in-line table-valued function does not have the body of a function. A resultset is created by a single Select statement in the Return clause. It is best to demonstrate this feature with an example. The following function returns only a segment of a table based on a role the user belongs to. The idea is that a manager or any other employee can see only equipment from his own department: Create Function fn_DepartmentEquipment ( @chvUserName sysname ) Returns table As Return ( Select InventoryId, Make + ' ' + model Model, Location From Inventory inner join Contact C On Inventory.OwnerId = C.ContactId Inner Join Contact Manager On C.OrgUnitId = Manager.OrgUnitId Inner Join Equipment On Inventory.EquipmentId = Equipment.EquipmentId Inner Join Location On Inventory.LocationId = Location.LocationId Where Manager.UserName = @chvUserName ) Go 370 SQL Server 2000 Stored Procedure Programming You can use this function in any place where a view or table is allowed, such as in a Select statement: Select * From fn_DepartmentEquipment ('tomj') Go Figure 9-6 shows the result of such a statement. Figure 9-6. Using an in-line table-valued user-defined function Chapter 9: Special Types of Procedures 371 Managing User-defined Functions in Enterprise Manager You can access user-defined functions from Enterprise Manager as shown in Figure 9-7. If you double-click a function, SQL Server displays a modal form for editing its properties (that is, code and permissions). This editor is identical to the editor you use to edit stored procedures (see Figure 9-8). Figure 9-7. Managing user-defined functions in Enterprise Manager 372 SQL Server 2000 Stored Procedure Programming If you right-click a function and select New User Defined Function, SQL Server opens a form with a template for creating a new function (see Figure 9-9). Once you have written or changed the function, you can use the Check Syntax button to verify it, then select OK or Apply to compile and save it. You can also create and save a function template. TRIGGERS Triggers are a unique type of procedure. Triggers are very similar to events—a type of procedure in certain programming languages such as Visual Basic. Events in Visual Basic are initiated by the system when certain actions occur (for instance, a form is loaded, a text box receives focus, or a key is pressed). Figure 9-8. Editing user-defined functions [...]... View Restore Log Deny Revoke Disk Init Truncate Table Disk Resize Update Statistics 385 3 86 SQL Server 2000 Stored Procedure Programming These restrictions will not usually cause you any difficulties Triggers in SQL Server 2000 The syntax of triggers in SQL Server 2000 is just a little more complicated than in SQL Server 7.0: Create Trigger trigger_name On {table | view} [With Encryption] { {{For | After... cascading pop-up menus (see Figure 9-10) SQL Server displays a modal form for editing trigger properties This editor is very similar to the editor you use to edit stored procedures (see Figure 9-11) 391 392 SQL Server 2000 Stored Procedure Programming Figure 9-10 Managing triggers in Enterprise Manager Figure 9-11 Editing triggers Chapter 9: Special Types of Procedures SQL Server initially fills the form with... Types of Procedures A function template Triggers are associated with a table in a database and executed by SQL Server when a specific change occurs in the table The change could be the result of the following modification statements: w Insert s Update v Delete SQL Server 7.0 and earlier versions recognized only one type of trigger In SQL Server 2000, this type is called an after trigger SQL Server 2000. .. the new instead-of type 373 374 SQL Server 2000 Stored Procedure Programming Physical Design Let’s look at the simplified syntax for implementing the core functionality of triggers: Create Trigger trigger_name On table {For { [Delete] [,] [Insert] [,] [Update] } As sql_ statement [ n] As a stored procedure, a trigger logically consists of w A header, which is a Transact -SQL statement for creating a trigger... Equipment Where EquipmentId = 77777 SQL Server nonchalantly prints from the trigger: One or more rows are deleted in Equipment table! Full Syntax in SQL Server 7.0 Let’s investigate a complete syntax for triggers in SQL Server 7.0 After triggers in SQL Server 2000 have the same syntax except that the keyword For could be replaced with After Chapter 9: Special Types of Procedures Create Trigger trigger_name... proper way to use them Go Out ASAP Triggers take time to execute If your server is very busy and/or other users are locking resources in the database, execution might take much more time than expected On the other hand, locks that you (or rather SQL Server) have placed in the database while the 395 3 96 SQL Server 2000 Stored Procedure Programming trigger is executing will not be released until the trigger... were updated during the Insert or Update operation Transact -SQL includes two functions that you can use within the trigger \UPDATE and COLUMNS_UPDATED 379 380 SQL Server 2000 Stored Procedure Programming If Update (column) sql_ statement [ n] If (Columns_Updated() {bitwise_operator} updated_bitmask) {comparison_operator} column_bitmask [ n] sql_ statement [ n] We can now modify our previously used trigger... usual options, for instance, Edit and Delete Managing Triggers Using Transact -SQL Statements SQL Server has a rich pallet of system stored procedures for managing triggers from Transact -SQL Listing Triggers To list triggers associated with a table, use the system stored procedure sp_helptrigger: sp_helptrigger 'Order' The server returns the list of triggers associated with the specified table and displays... -trOrderStatus_U dbo 1 0 0 trOrderStatus_U_1 dbo 1 0 0 (2 row(s) affected) Viewing Triggers You can obtain the code for a trigger using the system stored procedure sp_helptext: sp_helptext 'trOrderStatus_U' 393 394 SQL Server 2000 Stored Procedure Programming The server returns the code for the specified trigger: Text CREATE Trigger trOrderStatus_U On dbo.[Order] After... against multiple records You will see more reasons in following paragraphs Inserted and Deleted Virtual Tables SQL Server maintains two temporary virtual tables during the execution of a trigger They are called Deleted and Inserted These tables contain 375 3 76 SQL Server 2000 Stored Procedure Programming all the records inserted or deleted during the operation that fired the trigger You can use this . @insTerms = @insTerms + 1 End Return End Chapter 9: Special Types of Procedures 367 368 SQL Server 2000 Stored Procedure Programming Let me point out to you a few differences between these functions and. 3 2000- 04-01 00:00:00 87.7500 4 2000- 05-01 00:00:00 87.7500 5 2000- 06- 01 00:00:00 87.7500 6 2000- 07-01 00:00:00 87.7500 7 2000- 08-01 00:00:00 87.7500 Stored procedure prListTerms has functionality. @dtsEndDate)/2 When 'weekly' then DateDIFF(week, @dtsStartDate, @dtsEndDate) 366 SQL Server 2000 Stored Procedure Programming When 'quarterly' then DateDIFF(qq, @dtsStartDate, @dtsEndDate) When