O F F I C I A L
M I C R O S O F T
6232B
L E A R N I N G
P R O D U C T
Implementing a Microsoft® SQL Server® 2008 R2 Database
Volume 2
ii
Implementing a Microsoft® SQL Server® 2008 R2 Database
Information in this document, including URL and other Internet Web site references, is subject to change without notice. Unless otherwise noted, the example companies, organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious, and no association with any real company, organization, product, domain name, e-mail address, logo, person, place or event is intended or should be inferred. Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation. Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property. The names of manufacturers, products, or URLs are provided for informational purposes only and Microsoft makes no representations and warranties, either expressed, implied, or statutory, regarding these manufacturers or the use of the products with any Microsoft technologies. The inclusion of a manufacturer or product does not imply endorsement of Microsoft of the manufacturer or product. Links may be provided to third party sites. Such sites are not under the control of Microsoft and Microsoft is not responsible for the contents of any linked site or any link contained in a linked site, or any changes or updates to such sites. Microsoft is not responsible for webcasting or any other form of transmission received from any linked site. Microsoft is providing these links to you only as a convenience, and the inclusion of any link does not imply endorsement of Microsoft of the site or the products contained therein. © 2011 Microsoft Corporation. All rights reserved. Microsoft, and Windows are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries. All other trademarks are property of their respective owners.
Product Number: 6232B Part Number: X17-52971 Released: 03/2011
MICROSOFT LICENSE TERMS OFFICIAL MICROSOFT LEARNING PRODUCTS - TRAINER EDITION – Pre-Release and Final Release Versions These license terms are an agreement between Microsoft Corporation and you. Please read them. They apply to the Licensed Content named above, which includes the media on which you received it, if any. The terms also apply to any Microsoft
updates,
supplements,
Internet-based services, and
support services
for this Licensed Content, unless other terms accompany those items. If so, those terms apply. By using the Licensed Content, you accept these terms. If you do not accept them, do not use the Licensed Content. If you comply with these license terms, you have the rights below.
1. DEFINITIONS. a. “Academic Materials” means the printed or electronic documentation such as manuals, workbooks, white papers, press releases, datasheets, and FAQs which may be included in the Licensed Content. b. “Authorized Learning Center(s)” means a Microsoft Certified Partner for Learning Solutions location, an IT Academy location, or such other entity as Microsoft may designate from time to time. c. “Authorized Training Session(s)” means those training sessions authorized by Microsoft and conducted at or through Authorized Learning Centers by a Trainer providing training to Students solely on Official Microsoft Learning Products (formerly known as Microsoft Official Curriculum or “MOC”) and Microsoft Dynamics Learning Products (formerly know as Microsoft Business Solutions Courseware). Each Authorized Training Session will provide training on the subject matter of one (1) Course. d. “Course” means one of the courses using Licensed Content offered by an Authorized Learning Center during an Authorized Training Session, each of which provides training on a particular Microsoft technology subject matter. e. “Device(s)” means a single computer, device, workstation, terminal, or other digital electronic or analog device. f.
“Licensed Content” means the materials accompanying these license terms. The Licensed Content may include, but is not limited to, the following elements: (i) Trainer Content, (ii) Student Content, (iii) classroom setup guide, and (iv) Software. There are different and separate components of the Licensed Content for each Course.
g.
“Software” means the Virtual Machines and Virtual Hard Disks, or other software applications that may be included with the Licensed Content.
h. “Student(s)” means a student duly enrolled for an Authorized Training Session at your location. i.
“Student Content” means the learning materials accompanying these license terms that are for use by Students and Trainers during an Authorized Training Session. Student Content may include labs, simulations, and courseware files for a Course.
j.
“Trainer(s)” means a) a person who is duly certified by Microsoft as a Microsoft Certified Trainer and b) such other individual as authorized in writing by Microsoft and has been engaged by an Authorized Learning Center to teach or instruct an Authorized Training Session to Students on its behalf.
k. “Trainer Content” means the materials accompanying these license terms that are for use by Trainers and Students, as applicable, solely during an Authorized Training Session. Trainer Content may include Virtual Machines, Virtual Hard Disks, Microsoft PowerPoint files, instructor notes, and demonstration guides and script files for a Course. l.
“Virtual Hard Disks” means Microsoft Software that is comprised of virtualized hard disks (such as a base virtual hard disk or differencing disks) for a Virtual Machine that can be loaded onto a single computer or other device in order to allow end-users to run multiple operating systems concurrently. For the purposes of these license terms, Virtual Hard Disks will be considered “Trainer Content”.
m. “Virtual Machine” means a virtualized computing experience, created and accessed using Microsoft Virtual PC or Microsoft Virtual Server software that consists of a virtualized hardware environment, one or more Virtual Hard Disks,
and a configuration file setting the parameters of the virtualized hardware environment (e.g., RAM). For the purposes of these license terms, Virtual Hard Disks will be considered “Trainer Content”.
n.
“you” means the Authorized Learning Center or Trainer, as applicable, that has agreed to these license terms.
2. OVERVIEW. Licensed Content. The Licensed Content includes Software, Academic Materials (online and electronic), Trainer Content, Student Content, classroom setup guide, and associated media. License Model. The Licensed Content is licensed on a per copy per Authorized Learning Center location or per Trainer basis.
3. INSTALLATION AND USE RIGHTS. a. Authorized Learning Centers and Trainers: For each Authorized Training Session, you may: i.
either install individual copies of the relevant Licensed Content on classroom Devices only for use by Students enrolled in and the Trainer delivering the Authorized Training Session, provided that the number of copies in use does not exceed the number of Students enrolled in and the Trainer delivering the Authorized Training Session, OR
ii. install one copy of the relevant Licensed Content on a network server only for access by classroom Devices and only for use by Students enrolled in and the Trainer delivering the Authorized Training Session, provided that the number of Devices accessing the Licensed Content on such server does not exceed the number of Students enrolled in and the Trainer delivering the Authorized Training Session. iii. and allow the Students enrolled in and the Trainer delivering the Authorized Training Session to use the Licensed Content that you install in accordance with (ii) or (ii) above during such Authorized Training Session in accordance with these license terms. i.
Separation of Components. The components of the Licensed Content are licensed as a single unit. You may not separate the components and install them on different Devices.
ii. Third Party Programs. The Licensed Content may contain third party programs. These license terms will apply to the use of those third party programs, unless other terms accompany those programs.
b. Trainers: i.
Trainers may Use the Licensed Content that you install or that is installed by an Authorized Learning Center on a classroom Device to deliver an Authorized Training Session.
ii. Trainers may also Use a copy of the Licensed Content as follows:
A. Licensed Device. The licensed Device is the Device on which you Use the Licensed Content. You may install and Use one copy of the Licensed Content on the licensed Device solely for your own personal training Use and for preparation of an Authorized Training Session. B. Portable Device. You may install another copy on a portable device solely for your own personal training Use and for preparation of an Authorized Training Session. 4. PRE-RELEASE VERSIONS. If this is a pre-release (“beta”) version, in addition to the other provisions in this agreement, these terms also apply: a. Pre-Release Licensed Content. This Licensed Content is a pre-release version. It may not contain the same information and/or work the way a final version of the Licensed Content will. We may change it for the final, commercial version. We also may not release a commercial version. You will clearly and conspicuously inform any Students who participate in each Authorized Training Session of the foregoing; and, that you or Microsoft are under no obligation to provide them with any further content, including but not limited to the final released version of the Licensed Content for the Course. b. Feedback. If you agree to give feedback about the Licensed Content to Microsoft, you give to Microsoft, without charge, the right to use, share and commercialize your feedback in any way and for any purpose. You also give to third parties, without charge, any patent rights needed for their products, technologies and services to use or interface with any specific parts of a Microsoft software, Licensed Content, or service that includes the feedback. You will not give feedback that is subject to a license that requires Microsoft to license its software or documentation to third parties because we include your feedback in them. These rights survive this agreement. c. Confidential Information. The Licensed Content, including any viewer, user interface, features and documentation that may be included with the Licensed Content, is confidential and proprietary to Microsoft and its suppliers.
i.
Use. For five years after installation of the Licensed Content or its commercial release, whichever is first, you may not disclose confidential information to third parties. You may disclose confidential information only to your employees and consultants who need to know the information. You must have written agreements with them that protect the confidential information at least as much as this agreement.
ii.
Survival. Your duty to protect confidential information survives this agreement.
iii. Exclusions. You may disclose confidential information in response to a judicial or governmental order. You must first give written notice to Microsoft to allow it to seek a protective order or otherwise protect the information. Confidential information does not include information that
becomes publicly known through no wrongful act;
you received from a third party who did not breach confidentiality obligations to Microsoft or its suppliers; or
you developed independently.
d.
Term. The term of this agreement for pre-release versions is (i) the date which Microsoft informs you is the end date for using the beta version, or (ii) the commercial release of the final release version of the Licensed Content, whichever is first (“beta term”).
e.
Use. You will cease using all copies of the beta version upon expiration or termination of the beta term, and will destroy all copies of same in the possession or under your control and/or in the possession or under the control of any Trainers who have received copies of the pre-released version.
f.
Copies. Microsoft will inform Authorized Learning Centers if they may make copies of the beta version (in either print and/or CD version) and distribute such copies to Students and/or Trainers. If Microsoft allows such distribution, you will follow any additional terms that Microsoft provides to you for such copies and distribution.
5. ADDITIONAL LICENSING REQUIREMENTS AND/OR USE RIGHTS. a. Authorized Learning Centers and Trainers: i.
Software.
ii. Virtual Hard Disks. The Licensed Content may contain versions of Microsoft XP, Microsoft Windows Vista, Windows Server 2003, Windows Server 2008, and Windows 2000 Advanced Server and/or other Microsoft products which are provided in Virtual Hard Disks. A. If the Virtual Hard Disks and the labs are launched through the Microsoft Learning Lab Launcher, then these terms apply: Time-Sensitive Software. If the Software is not reset, it will stop running based upon the time indicated on the install of the Virtual Machines (between 30 and 500 days after you install it). You will not receive notice before it stops running. You may not be able to access data used or information saved with the Virtual Machines when it stops running and may be forced to reset these Virtual Machines to their original state. You must remove the Software from the Devices at the end of each Authorized Training Session and reinstall and launch it prior to the beginning of the next Authorized Training Session. B. If the Virtual Hard Disks require a product key to launch, then these terms apply: Microsoft will deactivate the operating system associated with each Virtual Hard Disk. Before installing any Virtual Hard Disks on classroom Devices for use during an Authorized Training Session, you will obtain from Microsoft a product key for the operating system software for the Virtual Hard Disks and will activate such Software with Microsoft using such product key. C. These terms apply to all Virtual Machines and Virtual Hard Disks: You may only use the Virtual Machines and Virtual Hard Disks if you comply with the terms and conditions of this agreement and the following security requirements: o
You may not install Virtual Machines and Virtual Hard Disks on portable Devices or Devices that are accessible to other networks.
o
You must remove Virtual Machines and Virtual Hard Disks from all classroom Devices at the end of each Authorized Training Session, except those held at Microsoft Certified Partners for Learning Solutions locations.
o
You must remove the differencing drive portions of the Virtual Hard Disks from all classroom Devices at the end of each Authorized Training Session at Microsoft Certified Partners for Learning Solutions locations.
o
You will ensure that the Virtual Machines and Virtual Hard Disks are not copied or downloaded from Devices on which you installed them.
o
You will strictly comply with all Microsoft instructions relating to installation, use, activation and deactivation, and security of Virtual Machines and Virtual Hard Disks.
o
You may not modify the Virtual Machines and Virtual Hard Disks or any contents thereof.
o
You may not reproduce or redistribute the Virtual Machines or Virtual Hard Disks.
ii. Classroom Setup Guide. You will assure any Licensed Content installed for use during an Authorized Training Session will be done in accordance with the classroom set-up guide for the Course. iii. Media Elements and Templates. You may allow Trainers and Students to use images, clip art, animations, sounds, music, shapes, video clips and templates provided with the Licensed Content solely in an Authorized Training Session. If Trainers have their own copy of the Licensed Content, they may use Media Elements for their personal training use. iv. iv Evaluation Software. Any Software that is included in the Student Content designated as “Evaluation Software” may be used by Students solely for their personal training outside of the Authorized Training Session.
b. Trainers Only: i.
Use of PowerPoint Slide Deck Templates . The Trainer Content may include Microsoft PowerPoint slide decks. Trainers may use, copy and modify the PowerPoint slide decks only for providing an Authorized Training Session. If you elect to exercise the foregoing, you will agree or ensure Trainer agrees: (a) that modification of the slide decks will not constitute creation of obscene or scandalous works, as defined by federal law at the time the work is created; and (b) to comply with all other terms and conditions of this agreement.
ii. Use of Instructional Components in Trainer Content. For each Authorized Training Session, Trainers may customize and reproduce, in accordance with the MCT Agreement, those portions of the Licensed Content that are logically associated with instruction of the Authorized Training Session. If you elect to exercise the foregoing rights, you agree or ensure the Trainer agrees: (a) that any of these customizations or reproductions will only be used for providing an Authorized Training Session and (b) to comply with all other terms and conditions of this agreement. iii. Academic Materials. If the Licensed Content contains Academic Materials, you may copy and use the Academic Materials. You may not make any modifications to the Academic Materials and you may not print any book (either electronic or print version) in its entirety. If you reproduce any Academic Materials, you agree that:
The use of the Academic Materials will be only for your personal reference or training use
You will not republish or post the Academic Materials on any network computer or broadcast in any media;
You will include the Academic Material’s original copyright notice, or a copyright notice to Microsoft’s benefit in the format provided below: Form of Notice: © 2010 Reprinted for personal reference use only with permission by Microsoft Corporation. All rights reserved. Microsoft, Windows, and Windows Server are either registered trademarks or trademarks of Microsoft Corporation in the US and/or other countries. Other product and company names mentioned herein may be the trademarks of their respective owners.
6. INTERNET-BASED SERVICES. Microsoft may provide Internet-based services with the Licensed Content. It may change or cancel them at any time. You may not use these services in any way that could harm them or impair anyone else’s use of them. You may not use the services to try to gain unauthorized access to any service, data, account or network by any means. 7. SCOPE OF LICENSE. The Licensed Content is licensed, not sold. This agreement only gives you some rights to use the Licensed Content. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the Licensed Content only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the Licensed Content that only allow you to use it in certain ways. You may not
install more copies of the Licensed Content on classroom Devices than the number of Students and the Trainer in the Authorized Training Session;
allow more classroom Devices to access the server than the number of Students enrolled in and the Trainer delivering the Authorized Training Session if the Licensed Content is installed on a network server;
copy or reproduce the Licensed Content to any server or location for further reproduction or distribution;
disclose the results of any benchmark tests of the Licensed Content to any third party without Microsoft’s prior written approval;
work around any technical limitations in the Licensed Content;
reverse engineer, decompile or disassemble the Licensed Content, except and only to the extent that applicable law expressly permits, despite this limitation;
make more copies of the Licensed Content than specified in this agreement or allowed by applicable law, despite this limitation;
publish the Licensed Content for others to copy;
transfer the Licensed Content, in whole or in part, to a third party;
access or use any Licensed Content for which you (i) are not providing a Course and/or (ii) have not been authorized by Microsoft to access and use;
rent, lease or lend the Licensed Content; or
use the Licensed Content for commercial hosting services or general business purposes.
Rights to access the server software that may be included with the Licensed Content, including the Virtual Hard Disks does not give you any right to implement Microsoft patents or other Microsoft intellectual property in software or devices that may access the server.
8. EXPORT RESTRICTIONS. The Licensed Content is subject to United States export laws and regulations. You must comply with all domestic and international export laws and regulations that apply to the Licensed Content. These laws include restrictions on destinations, end users and end use. For additional information, see www.microsoft.com/exporting. 9. NOT FOR RESALE SOFTWARE/LICENSED CONTENT. You may not sell software or Licensed Content marked as “NFR” or “Not for Resale.” 10. ACADEMIC EDITION. You must be a “Qualified Educational User” to use Licensed Content marked as “Academic Edition” or “AE.” If you do not know whether you are a Qualified Educational User, visit www.microsoft.com/education or contact the Microsoft affiliate serving your country. 11. TERMINATION. Without prejudice to any other rights, Microsoft may terminate this agreement if you fail to comply with the terms and conditions of these license terms. In the event your status as an Authorized Learning Center or Trainer a) expires, b) is voluntarily terminated by you, and/or c) is terminated by Microsoft, this agreement shall automatically terminate. Upon any termination of this agreement, you must destroy all copies of the Licensed Content and all of its component parts. 12. ENTIRE AGREEMENT. This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the Licensed Content and support services. 13. APPLICABLE LAW. a. United States. If you acquired the Licensed Content in the United States, Washington state law governs the interpretation of this agreement and applies to claims for breach of it, regardless of conflict of laws principles. The laws of the state where you live govern all other claims, including claims under state consumer protection laws, unfair competition laws, and in tort. b. Outside the United States. If you acquired the Licensed Content in any other country, the laws of that country apply. 14. LEGAL EFFECT. This agreement describes certain legal rights. You may have other rights under the laws of your country. You may also have rights with respect to the party from whom you acquired the Licensed Content. This agreement does not change your rights under the laws of your country if the laws of your country do not permit it to do so.
15. DISCLAIMER OF WARRANTY. The Licensed Content is licensed “as-is.” You bear the risk of using it. Microsoft gives no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this agreement cannot change. To the extent permitted under your local laws, Microsoft excludes the implied warranties of merchantability, fitness for a particular purpose and noninfringement. 16. LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES. This limitation applies to
anything related to the Licensed Content, software, services, content (including code) on third party Internet sites, or third party programs; and
claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.
It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages. Please note: As this Licensed Content is distributed in Quebec, Canada, some of the clauses in this agreement are provided below in French. Remarque : Ce le contenu sous licence étant distribué au Québec, Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en français. EXONÉRATION DE GARANTIE. Le contenu sous licence visé par une licence est offert « tel quel ». Toute utilisation de ce contenu sous licence est à votre seule risque et péril. Microsoft n’accorde aucune autre garantie expresse. Vous pouvez bénéficier de droits additionnels en vertu du droit local sur la protection dues consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualité marchande, d’adéquation à un usage particulier et d’absence de contrefaçon sont exclues. LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES DOMMAGES. Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages directs uniquement à hauteur de 5,00 $ US. Vous ne pouvez prétendre à aucune indemnisation pour les autres dommages, y compris les dommages spéciaux, indirects ou accessoires et pertes de bénéfices. Cette limitation concerne:
tout ce qui est relié au le contenu sous licence , aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers ; et
les réclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilité stricte, de négligence ou d’une autre faute dans la limite autorisée par la loi en vigueur.
Elle s’applique également, même si Microsoft connaissait ou devrait connaître l’éventualité d’un tel dommage. Si votre pays n’autorise pas l’exclusion ou la limitation de responsabilité pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l’exclusion ci-dessus ne s’appliquera pas à votre égard. EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous pourriez avoir d’autres droits prévus par les lois de votre pays. Le présent contrat ne modifie pas les droits que vous confèrent les lois de votre pays si celles-ci ne le permettent pas.
Implementing a Microsoft® SQL Server® 2008 R2 Database
ix
x
Implementing a Microsoft® SQL Server® 2008 R2 Database
Acknowledgements Microsoft Learning would like to acknowledge and thank the following for their contribution towards developing this title. Their effort at various stages in the development has ensured that you have a good classroom experience.
Greg Low – Lead Developer Dr Greg Low is a SQL Server MVP, an MCT, and a Microsoft Regional Director for Australia. Greg has worked with SQL Server since version 4.2 as an active mentor, consultant, and trainer. He has been an instructor in the Microsoft SQL Server Masters certification program for several years and was one of the first two people to achieve the SQL Server 2008 Master certification. Greg is best known for his SQL Down Under podcast (at www.sqldownunder.com) where he interviews SQL Server MVPs and product team members on topics of interest to the SQL Server community. He is the CEO of SolidQ Australia which is part of Solid Quality Mentors. He is the author of a number whitepapers on the Microsoft MSDN and TechNet web sites and a number of SQL Server related books.
Herbert Albert – SolidQ Technical Reviewer Herbert Albert started his career in 1994. He works as a trainer, consultant, and author focusing on SQL Server technologies. Herbert is a mentor and Managing Director of Solid Quality Mentors Central Europe located in Vienna, Austria. He has several Microsoft certifications including being an MCT since 1997. He is a regular speaker at conferences and is a co-author of the SQL Server 2008 R2 Upgrade Technical Reference Guide and SQL Server 2005 Step-by-Step Applied Techniques. Together with Gianluca Hotz, Herbert writes a regular column at the SolidQ Journal.
Chris Barker – Technical Reviewer Chris Barker is an MCT in New Zealand and currently employed as a staff trainer at Auldhouse, one of New Zealand’s major CPLS training centers in Wellington. He has been programming from the early 1970s—his first program was written in assembly language and debugged in binary (literally)! While focusing training on programming (mostly .NET) and databases (mostly Microsoft SQL Server), Chris has also been an infrastructure trainer and has both Novell and Microsoft networking qualifications.
Mark Hions – Technical Reviewer Mark's passion for computing and skill as a communicator were well suited to his position as an instructor at Honeywell Canada, where he started working with minicomputers, mainframes, and mature students in 1984. He first met Microsoft SQL Server when it ran on OS/2, and has delivered training on every version since. An independent MCT and consultant for many years, he is a highly-rated presenter at TechEd, has designed SQL Server exams for Microsoft, and has delivered deep-dive courses through the Microsoft Partner Channel. Mark is now the Principal SQL Server Instructor and Consultant at DesTech, which is the largest provider of SQL Server training in the Toronto area.
Implementing a Microsoft® SQL Server® 2008 R2 Database
Contents Module 13: Designing and Implementing User-Defined Functions Lesson 1: Overview of Functions
13-3
Lesson 2: Designing and Implementing Scalar Functions
13-7
Lesson 3: Designing and Implementing Table-Valued Functions
13-14
Lesson 4: Implementation Considerations for Functions
13-19
Lesson 5: Alternatives to Functions
13-26
Lab 13: Designing and Implementing User-Defined Functions
13-29
Module 14: Ensuring Data Integrity through Constraints Lesson 1: Enforcing Data Integrity
14-3
Lesson 2: Implementing Domain Integrity
14-10
Lesson 3: Implementing Entity and Referential Integrity
14-18
Lab 14: Ensuring Data Integrity through Constraints
14-28
Module 15: Responding to Data Manipulation via Triggers Lesson 1: Designing DML Triggers
15-3
Lesson 2: Implementing DML Triggers
15-13
Lesson 3: Advanced Trigger Concepts
15-20
Lab 15: Responding to Data Manipulation via Triggers
15-30
Module 16: Implementing Managed Code in SQL Server 2008 R2 Lesson 1: Introduction to SQL CLR Integration
16-3
Lesson 2: Importing and Configuring Assemblies
16-16
Lesson 3: Implementing SQL CLR Integration
16-23
Lab 16: Designing and Implementing Views
16-43
Module 17: Storing XML Data in SQL Server 2008 R2 Lesson 1: Introduction to XML and XML Schemas
17-3
Lesson 2: Storing XML Data and Schemas in SQL Server
17-15
Lesson 3: Implementing the XML Data Type
17-26
Lab 17: Storing XML Data in SQL Server
17-31
Module 18: Querying XML Data in SQL Server Lesson 1: Using the T-SQL FOR XML Statement
18-3
Lesson 2: Getting Started with XQuery
18-15
Lesson 3: Shredding XML
18-25
Lab 18: Querying XML Data in SQL Server
18-34
xi
xii
Implementing a Microsoft® SQL Server® 2008 R2 Database
Module 19: Working with SQL Server® 2008 R2 Spatial Data Lesson 1: Introduction to Spatial Data
19-3
Lesson 2: Working with SQL Server Spatial Data Types
19-13
Lesson 3: Using Spatial Data in Applications
19-27
Lab 19: Working with SQL Server Spatial Data
19-38
Module 20: Working with Full-Text Indexes and Queries Lesson 1: Introduction to Full-Text Indexing
20-3
Lesson 2: Implementing Full-Text Indexes in SQL Server
20-10
Lesson 3: Working with Full-Text Queries
20-21
Lab 20: Working with Full-Text Indexes and Queries
20-33
Lab Answer Keys
Designing and Implementing User-Defined Functions
Module 13 Designing and Implementing User-Defined Functions Contents: Lesson 1: Overview of Functions
13-3
Lesson 2: Designing and Implementing Scalar Functions
13-7
Lesson 3: Designing and Implementing Table-Valued Functions
13-14
Lesson 4: Implementation Considerations for Functions
13-19
Lesson 5: Alternatives to Functions
13-26
Lab 13: Designing and Implementing User-Defined Functions
13-29
13-1
13-2
Implementing a Microsoft® SQL Server® 2008 R2 Database
Module Overview
Functions are routines that are used to encapsulate frequently performed logic. Rather than having to repeat all the function logic, any code that must perform the logic can call the function. In this lesson, you will learn the design and implementation of user-defined functions that enforce business rules or data consistency, or to modify and maintain existing functions written by other developers.
Objectives After completing this lesson, you will be able to: • • • •
Design and implement scalar functions Design and implement table-valued functions Describe implementation considerations for functions Describe alternatives to functions
Designing and Implementing User-Defined Functions
13-3
Lesson 1
Overview of Functions
Functions are routines made up of one or more Transact-SQL statements that can be used to encapsulate code for reuse. A function takes zero or more input parameters and returns either a scalar value or a table. Functions do not support output parameters, but do return results, either a single value or a table. This lesson provides an overview of functions and describes system functions.
Objectives After completing this lesson, you will be able to: • •
Describe different types of functions Use system functions
13-4
Implementing a Microsoft® SQL Server® 2008 R2 Database
Types of Functions
Key Points Most high-level programming languages offer functions as blocks of code that are called by name and which can process input parameters. SQL Server has several types of functions: scalar functions, tablevalued functions, and system functions. Table-valued functions can be created in two ways. These are known as inline functions or multi-statement functions.
Scalar Functions Scalar functions return a single data value of the type defined in a RETURNS clause. An example of a scalar function would be a function that extracts the protocol from a URL. From the string "http://www.microsoft.com", the function would return the string "http".
Inline table-valued functions An inline table-valued function returns a table that is the result of a single SELECT statement. While this is similar to a view, an inline table-valued function is more flexible in that parameters can be passed to the SELECT statement. For example, if a table holds details of sales for an entire country, individual views could be created to return details of sales for particular states within the country. An inline table-valued function could be written, that takes the state code or ID as a parameter. In this way, only a single function would be needed to provide details for all states, rather than separate views for each state.
Multi-statement table-valued functions A multi-statement table-valued function returns a table built by one or more Transact-SQL statements and is similar to a stored procedure. Multi-statement table-valued functions are created for the same reasons as inline table-valued functions, but are used when the logic that the function needs to implement is too complex to be expressed in a single SELECT statement.
Designing and Implementing User-Defined Functions
System Functions System functions are built-in functions provided by SQL Server to help you perform a variety of operations. They cannot be modified. Question: How have you used functions in other programming languages?
13-5
13-6
Implementing a Microsoft® SQL Server® 2008 R2 Database
System Functions
Key Points SQL Server has a wide variety of built-in function that you can use in queries to return data or to perform operations on data.
System Functions Most of the functions are scalar functions and provide the functionality commonly provided by functions in other high-level languages such as operations on data types (including strings and dates and times) and conversions between data types. A library of mathematical and cryptographic functions is provided. Other functions provide details of the configuration of the system and its security. Aggregates such as MIN, MAX, AVG, SUM, and COUNT perform calculations across groups of rows. Many of these functions automatically ignore NULL rows. Ranking functions such as ROW_NUMBER, RANK, DENSE RANK, and NTILE perform windowing operations on rows of data. Question: What would a cryptographic function be used for?
Designing and Implementing User-Defined Functions
13-7
Lesson 2
Designing and Implementing Scalar Functions
You have seen that functions are routines made up of one or more Transact-SQL statements that can be used to encapsulate code for reuse, and that functions can take zero or more input parameters and return either scalar values or a tables. This lesson provides an overview of scalar functions and explains why and how you use them, in addition to the syntax for creating them.
Objectives After completing this lesson, you will be able to: • • • •
Explain a scalar function Create scalar functions Describe data type limitations Explain deterministic and non-deterministic functions
13-8
Implementing a Microsoft® SQL Server® 2008 R2 Database
What Is a Scalar Function?
Key Points You use scalar functions to return information from a database. A scalar function returns a single data value of the type defined in a RETURNS clause.
Scalar Functions Unlike the definition of a stored procedure, where the use of a BEGIN…END that wraps the body of the stored procedure is optional, the body of the function must be defined in a BEGIN…END block. The function body contains the series of Transact-SQL statements that return the value. For example, consider the following function definition: CREATE FUNCTION dbo.ExtractProtocolFromURL ( @URL nvarchar(1000)) RETURNS nvarchar(1000) AS BEGIN RETURN CASE WHEN CHARINDEX(N':',@URL,1) >= 1 THEN SUBSTRING(@URL,1,CHARINDEX(N':',@URL,1) - 1) END; END; GO
Note that the body of the function comprises a single RETURN statement that is wrapped in a BEGIN…END block. This function can be used as an expression wherever a single value could be used: SELECT dbo.ExtractProtocolFromURL(N'http://www.microsoft.com'); GO IF (dbo.ExtractProtocolFromURL(@URL) = N'http') ...
Designing and Implementing User-Defined Functions
13-9
Scalar functions can also be implemented in managed code. Managed code will be discussed in Module 16. The allowable return values for scalar functions differ between functions that are defined in T-SQL and functions that are defined using managed code.
13-10
Implementing a Microsoft® SQL Server® 2008 R2 Database
Creating Scalar Functions
Key Points User-defined functions are created using the CREATE FUNCTION statement, modified using the ALTER FUNCTION statement, and removed using the DROP FUNCTION statement. Even though the body of the function (apart from inline functions) must be wrapped in a BEGIN…END block, the CREATE FUNCTION must be the only statement in the batch.
Scalar User-defined Functions You use scalar functions to return information from a database. A scalar function returns a single data value of the type defined in a RETURNS clause. The body of the function, defined in a BEGIN…END block, contains the series of Transact-SQL statements that return the value.
Guidelines Consider the following guidelines when you create scalar user-defined functions: • •
Make sure that you use two-part naming for the function and for all database objects referenced by the function. Avoid Transact-SQL errors that cause a statement to be canceled and continue with the next statement in the module (such as triggers or stored procedures) because they are treated differently inside a function. In functions, such errors cause the execution of the function to stop.
Side-effects A function that modifies the underlying database is considered to have "side-effects". In SQL Server, functions are not permitted to have side-effects. You may not change data in a database within a function, may not call a stored procedure and may not execute dynamic SQL code.
Designing and Implementing User-Defined Functions
13-11
Deterministic and Non-deterministic Functions
Key Points Both built-in and user-defined functions fall into one of two categories: deterministic and nondeterministic. This distinction is important as it determines where a function can be used.
Deterministic Functions A deterministic function is one that will always return the same result when provided with the same set of input values and for the same database state. Consider the following function definition: CREATE FUNCTION dbo.AddInteger (@FirstValue int, @SecondValue int) RETURNS int AS BEGIN RETURN @FirstValue + @SecondValue; END; GO
Every time the function is called with the same two integer values, it would return exactly the same result.
Non-deterministic Functions A non-deterministic function is one that may return different results for the same set of input values each time it is called, even if the database remains in the same state. Consider the following function: CREATE FUNCTION dbo.CurrentTimeInLondonAsString() RETURNS varchar(40) AS BEGIN RETURN CONVERT(varchar(40),SYSUTCDATETIME(),100); END;
13-12
Implementing a Microsoft® SQL Server® 2008 R2 Database
GO
Each time the function is called, it would return a different value, even though no input parameters are supplied. The OBJECTPROPERTY() function can be used to determine if a function is deterministic or not.
Designing and Implementing User-Defined Functions
13-13
Demonstration 2A: Scalar Functions
Key Points In this demonstration you will see: • • • •
How to create scalar user-defined functions How to query scalar user-defined functions How to determine if a scalar user-defined function is deterministic How to drop scalar user-defined functions
Demonstration Setup 1. 2.
3. 4. 5.
Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_13_PRJ\6232B_13_PRJ.ssmssln and click Open. Open and execute the 00 – Setup.sql script file from within Solution Explorer. Open the 21 – Demonstration 2A.sql script file. Follow the instructions contained within the comments of the script file.
13-14
Implementing a Microsoft® SQL Server® 2008 R2 Database
Lesson 3
Designing and Implementing Table-Valued Functions
In this lesson you will learn how to work with functions that return tables instead of single values. There are two types of table-valued functions (TVFs): inline and multi-statement. Both types of TVF will be covered in this lesson. The ability to return a table of data is important as it allows a function to be used as a source of rows in place of a table in a T-SQL statement. In many cases, this can avoid the need to store data temporarily in tables.
Objectives After completing this lesson, you will be able to: • • •
Describe table-valued functions Describe Inline table-valued functions Describe multi-statement table-valued functions
Designing and Implementing User-Defined Functions
13-15
What are Table-valued Functions?
Key Points Unlike scalar functions, TVFs return a table that can contain many rows of data, each with many columns.
Table-valued Functions There are two ways to create TVFs. Inline TVFs return an output table defined by a RETURN statement that is comprised of a single SELECT statement. If the logic of the function is too complex to include in a single SELECT statement, the function needs to be implemented as a multi-statement TVF. Multi-statement TVFs construct a table within the body of the function and then return the table. They also need to define the schema of the table to be returned. Both types of TVF can be used as the equivalent of parameterized views.
13-16
Implementing a Microsoft® SQL Server® 2008 R2 Database
Inline Table-Valued Functions
Key Points You can use inline functions to achieve the functionality of parameterized views. One of the limitations of a view is that you are not allowed to include a user-provided parameter within the view when you create it.
Inline TVFs In the syntax example shown on the slide, note that the return type is TABLE. The definition of the columns of the table is not shown. You do not explicitly define the schema of the returned table. The output table schema is derived from the SELECT statement that you provide within the RETURN statement. For inline functions, the body of the function is not enclosed in a BEGIN…END block. However, the CREATE FUNCTION statement must be the only statement in the batch. Question: TVFs return rows of data as tables. You have learned that tables do not have a predefined order. Why does the example function in the slide include an ORDER BY clause?
Designing and Implementing User-Defined Functions
13-17
Multi-statement Table-valued Functions
Key Points A multi-statement table-valued function allows for more complexity in how the table to be returned is constructed. You can use user-defined functions that return a table to replace views. This is very useful when the logic required for constructing the return table is more complex than would be possible within the definition of a view.
Multi-statement TVFs A table-valued function (like a stored procedure) can use complex logic and multiple Transact-SQL statements to build a table. In the example on the slide, a function is created that returns a table of dates. For each row, two columns are returned: the position of the date within the range of dates, and the calculated date. As the system does not already include a table of dates, a loop needs to be constructed to calculate the required range of dates. This cannot be implemented in a single SELECT statement unless another object such as a table of numbers, is already present in the database. In each iteration of the loop, an INSERT is performed into the table that is later returned. In the same way that you use a view, you can use a table-valued function in the FROM clause of a Transact-SQL statement. Question: Can you think of a situation where you would need to use a Multi-statement Table-valued Function rather than an Inline Table-valued Function?
13-18
Implementing a Microsoft® SQL Server® 2008 R2 Database
Demonstration 3A: Implementing Table-Valued Functions
Key Points In this demonstration you will see: • • •
How to create a table-valued function How to query a table-valued function How to drop a table-valued function
Demonstration Steps 1.
2. 3.
If Demonstration 2A was not performed: •
Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system.
•
In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_13_PRJ\6232B_13_PRJ.ssmssln and click Open.
•
Open and execute the 00 – Setup.sql script file from within Solution Explorer.
Open the 31 – Demonstration 3A.sql script file. Follow the instructions contained within the comments of the script file.
Question: What are some commonly used SQL Scalar functions that you can think of?
Designing and Implementing User-Defined Functions
13-19
Lesson 4
Implementation Considerations for Functions
While the ability to create functions in T-SQL is very important, there are some key considerations that need to be made when creating functions. In particular, it is important to avoid negative performance impacts through inappropriate use of functions. Performance problems due to such inappropriate usage are very common. This lesson provides guidelines for the implementation of functions and describes how to control their security context.
Objectives After completing this lesson, you will be able to: • • • • •
Describe performance impacts of scalar functions Describe performance impacts of table-valued functions Control execution context Use EXECUTE AS clause Explain guidelines for creating functions
13-20
Implementing a Microsoft® SQL Server® 2008 R2 Database
Performance Impacts of Scalar Functions
Key Points The code for views is incorporated directly into the code for the query that accesses the view. This is not the case for scalar functions.
Common Performance Problems The over-use of scalar functions is a common cause of performance problems in SQL Server systems. In many cases, extracting the code from the function definition and incorporating it directly into the query will resolve the performance issue. You will see an example of this in the next lab.
Designing and Implementing User-Defined Functions
13-21
Performance Impacts of Multi-statement Table-valued Functions
Key Points Whether or not the code for a TVF is incorporated into the query that uses the function depends upon the type of table-valued function. Inline TVFs are directly incorporated into the code of the query that uses them.
Common Performance Problems Multi-statement TVFs are not incorporated into the code of the query that uses them. The inappropriate usage of such TVFs is a common cause of performance issues in SQL Server. The CROSS APPLY operator is used to call a table-valued function for each row in the left-hand table within the query. Designs that require the calling of a TVF for every row in a table can lead to significant performance overhead. You should examine the design to see if there is a way to avoid the need to call the function for each row.
13-22
Implementing a Microsoft® SQL Server® 2008 R2 Database
Controlling Execution Context
Key Points Execution context is determined by the user or login connected to the session, or executing (calling) a module. Execution context establishes the identity against which permissions are checked. The user or login calling a module, such as a stored procedure or function, usually determines execution context. When you use the EXECUTE AS clause to change the execution context so that a code module executes as a user other than the caller, the code is said to “impersonate” the alternative user.
Designing and Implementing User-Defined Functions
13-23
The EXECUTE AS Clause
Key Points The EXECUTE AS clause sets the execution context of a session. You can use the EXECUTE AS clause in a stored procedure or function to set the identity used as the execution context for the stored procedure or function. EXECUTE AS allows you to create procedures that execute code that the user executing the procedure is not permitted to execute, without the need for concerns regarding broken ownership chains or dynamic SQL execution.
13-24
Implementing a Microsoft® SQL Server® 2008 R2 Database
Guidelines for Creating Functions
Key Points Consider the following guidelines when you create user-defined functions: • •
• •
The performance of inline functions is, in many cases, much higher than the performance of multistatement functions. Wherever possible, try to implement functions as inline functions. Avoid building large general purpose functions. Keep functions relatively small and targeted at a specific purpose. This will avoid code complexity but will also increase the opportunities for reusing the functions. Use two-part naming to qualify the name of any database objects referred to within the function and also use two-part naming when choosing the name of the function. Consider the impact of using functions in combination with indexes. In particular, note that a WHERE clause that uses a predicate like: WHERE Function(CustomerID) = Value
is likely to remove the usefulness of an index on CustomerID.
•
Avoid statements that will raise T-SQL errors. Exception handling is not allowed within functions.
Designing and Implementing User-Defined Functions
13-25
Demonstration 4A: Execution Context
Key Points In this demonstration you will see how to alter the execution context of a function.
Demonstration Steps 1.
2. 3.
If Demonstration 2A was not performed: •
Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system.
•
In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_13_PRJ\6232B_13_PRJ.ssmssln and click Open.
•
Open and execute the 00 – Setup.sql script file from within Solution Explorer.
Open the 41 – Demonstration 4A.sql script file. Follow the instructions contained within the comments of the script file.
13-26
Implementing a Microsoft® SQL Server® 2008 R2 Database
Lesson 5
Alternatives to Functions
Functions are only one option for implementing code. This lesson explores situations where other solutions may or may not be appropriate and helps you make decisions about which solution to use.
Objectives After completing this lesson, you will be able to: • •
Compare table-valued functions and stored procedures Compare inline functions and views
Designing and Implementing User-Defined Functions
13-27
Comparing Table-valued Functions and Stored Procedures
Key Points Table-valued functions and stored procedures can often be used to achieve similar outcomes. It is important to realize that not all client applications can call both and so they cannot necessarily be used interchangeably. There are also pros and cons of each approach. While it is possible to access the output rows of a stored procedure with an INSERT EXEC statement, it is easier to consume the output of a function in code than the output of a stored procedure. For example, you cannot execute the following code: SELECT * FROM (EXEC dbo.GetCriticalPathNodes);
The output of a function could be assigned to a variable in code. Stored procedures can modify data in database tables. Functions cannot modify data in database tables. Functions that include such "side-effects" are not permitted. Functions can have significant performance impacts when not inlined and called for each row in a query. Stored procedures can execute dynamic SQL statements. Functions are not permitted to execute dynamic SQL statements. Stored procedures can include detailed exception handling. Functions cannot contain exception handling. Stored procedures can return multiple resultsets from a single stored procedure call. Table-valued functions are able to return a single rowset from a function call. There is no mechanism to permit the return of multiple rowsets from a single function call.
13-28
Implementing a Microsoft® SQL Server® 2008 R2 Database
Comparing Table-valued Functions and Views
Key Points TVFs can provide similar outcomes to views. Views and parameter-less TVFs are usually able to be consumed by most client application that can access tables. Not all such applications can pass parameters to a table-valued function. Views and inline TVFs can be updatable. Multi-statement TVFs are not updatable. Inline TVFs are updatable. Views can have INSTEAD OF triggers associated with them. This is mostly used to provide for updatable views based on multiple base tables. Views and inline table-valued functions are incorporated into surrounding queries. Scalar and multistatement table-valued functions are not incorporated into surrounding queries and often lead to performance issues when used inappropriately.
Designing and Implementing User-Defined Functions
13-29
Lab 13: Designing and Implementing User-Defined Functions
Lab Setup For this lab, you will use the available virtual machine environment. Before you begin the lab, you must complete the following steps: 1. 2. 3.
4.
5. 6. 7.
On the host computer, click Start, point to Administrative Tools, and then click Hyper-V Manager. Maximize the Hyper-V Manager window. In the Virtual Machines list, if the virtual machine 623XB-MIA-DC is not started: •
Right-click 623XB-MIA-DC and click Start.
•
Right-click 623XB-MIA-DC and click Connect.
•
In the Virtual Machine Connection window, wait until the Press CTRL+ALT+DELETE to log on message appears, and then close the Virtual Machine Connection window.
In the Virtual Machines list, if the virtual machine 623XB-MIA-SQL is not started: •
Right-click 623XB-MIA-SQL and click Start.
•
Right-click 623XB-MIA-SQL and click Connect.
•
In the Virtual Machine Connection window, wait until the Press CTRL+ALT+DELETE to log on message appears.
In Virtual Machine Connection window, click on the Revert toolbar icon. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action to complete. In the Virtual Machine Connection window, if the user is not already logged on: •
On the Action menu, click the Ctrl-Alt-Delete menu item.
•
Click Switch User, and then click Other User.
13-30
Implementing a Microsoft® SQL Server® 2008 R2 Database
•
Log on using the following credentials:
i. User name: AdventureWorks\Administrator ii. Password: Pa$$w0rd 8. From the View menu, in the Virtual Machine Connection window, click Full Screen Mode. 9. If the Server Manager window appears, check the Do not show me this console at logon check box and close the Server Manager window. 10. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, and click SQL Server Management Studio. 11. In Connect to Server window, type Proseware in the Server name text box. 12. In the Authentication drop-down list box, select Windows Authentication and click Connect. 13. In the File menu, click Open, and click Project/Solution. 14. In the Open Project window, open the project D:\6232B_Labs\6232B_13_PRJ\6232B_13_PRJ.ssmssln. 15. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.
Lab Scenario The existing marketing application includes some functions. Your manager has requested your assistance in creating a new function for formatting phone numbers. She also needs you to modify an existing function to improve its usability. Finally, if you have time, she would also like you to explore a performance-related problem with another existing function.
Supporting Documentation Function Specifications: Phone Number Function Name: FormatPhoneNumber (created in the dbo schema) Input Parameter: PhoneNumberToFormat nvarchar(16) Return Value: nvarchar(16) Rules to apply in formatting: • • • • • • •
Any phone number beginning with the international dialing code (ie: a + sign), should be left unformatted. Phone numbers that contain 10 digits should be formatted as: (XXX) XXX-XXXX Phone numbers that contain 8 digits should be formatted as: XXXX-XXXX Phone numbers that contain 7 digits should be formatted as: XXX-XXXX Phone numbers that contain 6 digits should be formatted as: XXX-XXX All other characters should be stripped out Phone numbers that have different numbers of digits should have only the digits returned ie: (9234) 2345-2342 should be returned as 923423452342.
Requirements: Comma-Delimited List Function You need to create another version of this function called dbo.IntegerListToTable that takes a commadelimited list of integers and returns a similar table. You need to design, implement and test the function. You can assume that all integers sent to the function will be eight digits or less in length. Problematic Query SELECT dbo.JoinNames(FirstName,MiddleName,LastName) AS FullName
Designing and Implementing User-Defined Functions
FROM Marketing.Prospect ORDER BY FullName;
13-31
13-32
Implementing a Microsoft® SQL Server® 2008 R2 Database
Exercise 1: Formatting Phone Numbers Scenario ScenarioYour manager has noticed that phone numbers that are entered into the database tend to be formatted in different ways by different users. She has asked you to create a function that will be used to format the phone numbers. You need to design, implement and test the function. The main tasks for this exercise are as follows: 1. 2. 3.
Review the requirements. Design and create the function. Test the function.
Task 1: Review the design requirements •
Review the Function Specifications: Phone Number in the supporting documentation.
Task 2: Design and create the function •
Design and create the function for reformatting phone numbers.
Task 3: Test the function •
Execute the FormatPhoneNumber function to ensure function correctly formats the phone number. Results: After this exercise, you should have created a new FormatPhoneNumber function within the dbo schema.
Designing and Implementing User-Defined Functions
13-33
Exercise 2: Modifying an Existing Function Scenario An existing function dbo.StringListToTable takes a comma-delimited list of strings and returns a table. In some application code, this causes issues with data types as the list often contains integers rather than just simple strings. The main tasks for this exercise are as follows: 1. 2. 3. 4.
Review the requirements. Design and create the function. Test the function. Test the function with an alternate delimiter such as the pipe | character.
Task 1: Review the requirements •
Review the requirement for the dbo.IntegerListToTable function in the Supporting Documentation.
Task 2: Design and create the function •
Design and create the dbo.IntegerListToTable function.
Task 3: Test the function •
Execute the dbo.IntegerListToTable function to ensure it returns the correct results.
Task 4: Test the function with an alternate delimiter such as the pipe | character •
Test the dbo.IntegerListToTable function and pass in an alternate delimiter such as the pipe | character. Results: After this exercise, you should have created a new IntegerListToTable function within a dbo schema.
13-34
Implementing a Microsoft® SQL Server® 2008 R2 Database
Challenge Exercise 3: Resolve a Function-related Performance Issue (Only if time permits) Scenario The operations team manager has approached you about a query that is performing badly. You need to investigate it and suggest changes that might improve its performance. The main tasks for this exercise are as follows: 1. 2. 3.
Review the query Design an alternate query Use SET STATISTICS TIME ON to compare the performance of the new and old queries
Task 1: Review the query •
Review the problematic query in the Supporting Documentation.
Task 2: Design an alternate query •
Design the query.
Task 3: Use SET STATISTICS TIME ON to compare the performance of the new and old queries •
Turn SET STATISTICS TIME ON.
•
Use the times returned to test how your new query compares with the original. Results: After this exercise, you should have created an alternate query for the poorly-performing query.
Designing and Implementing User-Defined Functions
13-35
Module Review and Takeaways
Review Questions 1. 2.
When using the EXECUTE AS clause, what privileges should the login or user being impersonated have? When using the EXECUTE AS clause, what privileges should the login or user creating the code have?
Best Practices 1. 2.
Avoid calling multi-statement TVFs for each row of a query. In many cases, you can dramatically improve performance by extracting the code from the query into the surrounding query. Use the WITH EXECUTE AS clause to override the security context of code that needs to perform actions that the user that is executing the code, does not have.
13-36
Implementing a Microsoft® SQL Server® 2008 R2 Database
Ensuring Data Integrity through Constraints
Module 14 Ensuring Data Integrity through Constraints Contents: Lesson 1: Enforcing Data Integrity
14-3
Lesson 2: Implementing Domain Integrity
14-10
Lesson 3: Implementing Entity and Referential Integrity
14-18
Lab 14: Ensuring Data Integrity through Constraints
14-28
14-1
14-2
Implementing a Microsoft® SQL Server® 2008 R2 Database
Module Overview
The quality of data in your database largely determines the usefulness and effectiveness of applications (and people) that rely on it, and it can play a major role in the success or failure of an organization or a business venture. Ensuring data integrity is a critical step in maintaining high-quality data. You should enforce data integrity at all levels of an application from first entry or collection through storage. Microsoft® SQL Server® provides a variety of features that simplify the enforcement of data integrity.
Objectives After completing this module, you will be able to: • • •
Explain the available options for enforcing data integrity and the levels at which they should be applied. Describe how domain integrity can be maintained. Describe how entity and referential integrity can be maintained.
Ensuring Data Integrity through Constraints
14-3
Lesson 1
Enforcing Data Integrity
An important step in database planning is deciding the best way to enforce the integrity of the data. Data integrity refers to the consistency and accuracy of data that is stored in a database.
Objectives After completing this lesson, you will be able to: • • •
Explain how data integrity checks need to apply across different layers of an application. Describe the different types of data integrity. Explain the available options for enforcing data integrity.
14-4
Implementing a Microsoft® SQL Server® 2008 R2 Database
Data Integrity Across Application Layers
Key Points Data integrity can be applied at different levels within an application. There is no right and wrong answer for all situations.
Application Levels Applications are often structured in levels. This is done to keep related functionality together and to improve the maintainability of code and the chance of it being reusable. Common examples of application levels are: • • •
User interface level Middle tier (sometimes referred to as business logic) Data tier
Data integrity could be enforced at each of these levels.
User-Interface Level There are several advantages of enforcing integrity at the user-interface level. The responsiveness to the end user is usually higher as minor errors can be trapped before any calls are made to other layers of code. Error messages are often clearer as the code is more aware of the action taken by the user that caused the error to occur.
Middle Tier Many integrity issues are directly related to business logic requirements. The middle tier is often where the bulk of those requirements exist in code. The middle tier is often also reused by multiple user interfaces. Implementing integrity at this level helps avoid different rules and checks being applied by different user interfaces. At this level, the logic is still quite aware of the functions that cause errors so the error messages returned to the user can still be quite specific.
Ensuring Data Integrity through Constraints
14-5
It is also easy for integrity checks that are only applied in the middle tier to be ineffective due to race conditions. For example, it might seem easy to check that a customer exists and then allow an order to be placed for the customer. Consider, though, the possibility that the customer could be removed by another user between the time that you check for the customer's existence and the time that you record the order.
Data Tier The advantage of implementing integrity at the data tier is that it cannot be bypassed by upper layers. In particular, it is common for the same data to be accessed by multiple applications or even directly through tools such as SQL Server Management Studio. If integrity is not maintained at the data tier level, all applications need to consistently apply all the rules and checks. The challenge of implementing some forms of integrity at the data tier (usually within the database) is that the data tier is often unaware of the user actions that caused an error to occur, so the error messages returned from this layer tend to be very precise in describing the issue but quite cryptic for an end user to understand. They typically need to be retranslated by upper layers of code before being presented to the end users.
Multiple Tiers The correct solution in most situations involves rules and checks being applied at multiple levels. The challenge with this, though, is in maintaining consistency between the rules and checks at different application levels.
14-6
Implementing a Microsoft® SQL Server® 2008 R2 Database
Types of Data Integrity
Key Points There are three basic forms of data integrity commonly enforced in database applications: domain integrity, entity integrity, and referential integrity.
Domain Integrity Domain (or column) integrity specifies a set of data values that are valid for a column and determines whether to allow null values. Domain integrity is often enforced by using validity checking and can be enforced by restricting the data type, format, or range of possible values allowed in a column. For example, assigning a tinyint data type to a column ensures that only values from 0 to 255 can be stored in that column.
Entity Integrity Entity (or table) integrity requires that all rows in a table have a way of being uniquely identified. This is commonly called a primary key value. Whether the primary key value can be changed or whether the whole row can be deleted depends on the level of integrity required between the primary key and any other tables, based on referential integrity.
Referential Integrity Referential integrity ensures that the relationships among the primary keys (in the referenced table) and foreign keys (in the referencing tables) are always maintained. You are not permitted to insert a value in the referencing column that doesn’t exist in the referenced column in the target table. A row in a referenced table cannot be deleted nor can the primary key be changed if a foreign key refers to the row unless a form of cascading action is permitted. You can define referential integrity relationships within the same table or between separate tables. As an example of referential integrity, you may need to ensure that an order cannot be placed for a nonexistent customer.
Ensuring Data Integrity through Constraints
Question: When might more than one type of integrity apply to a scenario?
14-7
14-8
Implementing a Microsoft® SQL Server® 2008 R2 Database
Options for Enforcing Data Integrity
Key Points The table summarizes the mechanisms provided by SQL Server for enforcing data integrity.
Data Types The first option for making sure that data has integrity is to ensure that only the correct type of data is stored. For example, you are not able to place alphabetic characters into a column that has been defined as storing integers. The choice of a data type will also define the permitted range of values that can be stored. For example, the smallint data type only allows values from -32768 to 32767.
Nullability The nullability of a column determines whether or not a value must be present in the column. This is often referred to as to whether a column is mandatory or not.
Default Values If a column is not nullable, then a value must be placed in it whenever a new row is inserted. A default value allows a specific value to be inserted into a column when no value is supplied in the statement that inserted the row.
Constraints Constraints are used to further constrain the allowable values in a column than the limits provided by the data type. For example, a tinyint column can have values from 0 to 255. You might decide to further constrain the column so that only values between 1 and 9 are permitted in the column. Constraints can also be applied at the table level and enforce relationships between the columns of a table. For example, you might have a column that holds an order number but it is not mandatory. You
Ensuring Data Integrity through Constraints
14-9
might then add a constraint which specifies that the column must have a value if the salesperson column also has a value.
Triggers Triggers are procedures (somewhat like stored procedures) that are executed whenever specific events like INSERT or UPDATE occur on a specific object such as a table. In the code for the trigger, you can then enforce even more complex rules for integrity. Triggers are discussed in Module 15.
Objects From Earlier Versions Early versions of SQL Server supported objects called rules and defaults. Note that defaults were a type of object and not the same as default constraints. These were separate objects that were then bound to columns. They were reused across multiple columns. These objects have been deprecated and code that is based on them should be replaced. In general, rules should be replaced by check constraints and defaults should be replaced by default constraints. Question: In your organization, which data integrity features are currently implemented in one of your databases?
14-10
Implementing a Microsoft® SQL Server® 2008 R2 Database
Lesson 2
Implementing Domain Integrity
Domain integrity limits the range and type of values that can be stored in a column. It is usually the most important form of data integrity when first designing a database. If domain integrity is not enforced, processing errors can occur when unexpected or out-of-range values are encountered.
Objectives After completing this lesson, you will be able to: • • • •
Describe how data types can be used to enforce domain integrity. Describe how column nullability can be used to enforce domain integrity. Describe how default constraints can be used to provide default values for columns. Describe how check constraints can be used to enforce domain integrity.
Ensuring Data Integrity through Constraints
14-11
Data Types
Key Points Choosing an appropriate data type for each column is one of the most important decisions you need to take when designing a table as part of a database. Data types can be assigned to a column by one of the following methods: • • •
Using SQL Server system data types Creating alias data types that are based on system data types Creating user-defined data types from data types created in the Microsoft .NET Framework common language runtime
System Data Types System data types are supplied by SQL Server. A large range of data types are available as you have seen in Module 2. Choosing a data type determines both the types of data that can be stored and the range of values that are permitted.
Alias Data Types It is common for consistency problems to occur when tables are designed. This is even more common when the tables are designed by more than a single person. For example, you may have several tables that store the weight of a product that was sold. One column might be defined as decimal(18,3), another column might be defined as decimal(12,2), and another column might be defined as decimal(16,5). For consistency, alias data types allow the creation of a data type called ProductWeight, define it as decimal(18,3), and then use it as the data type of all the columns. This can help lead to more consistent database designs. An additional advantage of alias data types is that code generation utilities can create more consistent code when the utilities have the additional information about the data types that alias data types provide. For example, a user-interface design program could decide to always display and/or prompt for product weights in a specific way.
14-12
Implementing a Microsoft® SQL Server® 2008 R2 Database
User-defined Data Types The addition of managed code to SQL Server as part of SQL Server 2005 onwards brought the ability to create entirely new data types. While alias data types are user-defined, they are still effectively subsets of the existing system data types. User-defined data types created in managed code allow for the design of not only the data that is stored in a data type but the behavior of the data type. For example, you could design a jpeg data type. Besides designing how it would store images, you could decide that it could be updated by calling a predesigned Resize method. Designing user-defined data types is discussed in Module 16.
Ensuring Data Integrity through Constraints
14-13
Column Nullability
Key Points Column nullability determines whether or not a value must be provided for the column. Columns that must have values are often referred to as mandatory columns.
Mandatory Columns An important decision that needs to be made when designing tables is whether or not each column must have a value in every row. A NULL value is one that is unknown. In fact, it is not a value but the lack of a value that makes it NULL. This concept is commonly misunderstood and misused. For example, consider a YTD_Sales column. Even if no sales have been made, the total of the sales for the year is not unknown. It is zero. But consider another related column that is called LastSaleDate. When no sales have been made, there is no logical value that could be placed in this column. Note that database designers will argue as to whether or not a column such as LastSaleDate should even exist as it could be derived from the lack of sales but often such columns are created for pragmatic performance reasons. Another common reason for allowing a column to be NULL is because of the lack of information on what eventually will be placed in the column. In the example shown in the slide, the likely closing date for the opportunity may not be known. This may be determined quite some time after the row was initially inserted.
Storage of NULL Another form of confusion arises about how NULL is stored. A column that is NULL is not the same as a numeric column being zero or a string column containing an empty string. This confusion is further heightened by some other database engines (not current versions of SQL Server) that have no way of storing zero or an empty string as being different to the column being NULL.
14-14
Implementing a Microsoft® SQL Server® 2008 R2 Database
DEFAULT Constraints
Key Points A DEFAULT constraint provides a value for a column when no value is specified in the statement that inserted the row. You can view the existing definition of DEFAULT constraints by querying the sys.default_constraints view.
DEFAULT Constraint At times a column is mandatory, that is, a value must be provided for the column. However, the application or program that is inserting the row might not be providing a value for that column. It may wish to have a rule applied by which the value of the column is automatically generated. DEFAULT constraints are associated with a database column. They are used to provide a default value for the column when no value is supplied by the user. The value is retrieved from the evaluation of an expression and the data type returned by the expression must be compatible with the data type of the column.
NULLable Columns and DEFAULT Constraints If a column is nullable and no value is provided for the column in the statement that inserted the row, the column would be left NULL. If a column is nullable and no value is provided for the column in the statement that inserted the row, and a DEFAULT constraint exists on the column, then the default value will be used. However, if the statement that inserted the row explicitly inserted NULL, then the default value will not be used.
Named Constraints SQL Server does not require you to supply names for constraints that you create. If a name is not supplied, SQL Server will automatically generate a name. However, the names that are generated are not very
Ensuring Data Integrity through Constraints
14-15
intuitive. Therefore, it is generally considered a good idea to provide names for constraints as you create them and to do so in a consistent naming pattern. A good example of why naming constraints is important is that if a column needs to be deleted, you must first remove any constraints associated with the column. Dropping a constraint requires you to provide a name for the constraint you are dropping. Having a consistent naming standard for constraints helps you know what that name is likely to be rather than having to execute a query to find the name. (Locating the name of a query would involve querying the sys.constraints system view).
14-16
Implementing a Microsoft® SQL Server® 2008 R2 Database
CHECK Constraints
Key Points CHECK constraints limit the values that are accepted by a column by controlling the values that can be put in the column.
CHECK Constraints After determining the data type for a column, you may wish to further restrict the values that can be placed into the column. For example, you might decide that a varchar(7) column must be 5 characters long if the first character is the letter A. More commonly, CHECK constraints are used as a form of “sanity” check. For example, you might decide that a salary needs to be within a certain range or a person’s age must be in the range 0 to 150.
Logical Expression CHECK constraints work with any logical (Boolean) expression that can return TRUE, FALSE, or UNKNOWN. Particular care must be given to any expression that could have a NULL return value. CHECK constraints reject values that evaluate to FALSE. This does not include NULL return values. They will not be rejected.
Table-Level CHECK Constraints Apart from checking the value in a particular column, CHECK constraints can be applied at the table level to check the relationship between the values in more than a single column. For example, you could decide that the FromDate column should not have a larger value than the ToDate column in the same row.
Ensuring Data Integrity through Constraints
14-17
Demonstration 2A: Data and Domain Integrity
Key Points In this demonstration you will see how to enforce data and domain integrity.
Demonstration Setup 1. 2.
3. 4. 5.
Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_14_PRJ\6232B_14_PRJ.ssmssln and click Open. Open and execute the 00 – Setup.sql script file from within Solution Explorer. Open the 21 – Demonstration 2A.sql script file. Follow the instructions contained within the comments of the script file.
14-18
Implementing a Microsoft® SQL Server® 2008 R2 Database
Lesson 3
Implementing Entity and Referential Integrity
It is important to be able to uniquely identify rows within tables and to be able to establish relationships across tables. For example, you will need to make sure that a customer can be identified and that the customer exists before you allow an order to be placed for that customer. This can be enforced via a combination of entity and referential integrity.
Objectives After completing this lesson, you will be able to: • • • • •
Explain how primary key constraints are used to enforce entity integrity Describe how unique constraints differ from primary key constraints Explain how foreign key constraints are used to enforce referential integrity Describe how table relationships can be maintained while deleting or updating data through cascading relationships Explain the common considerations for constraint checking
Ensuring Data Integrity through Constraints
14-19
PRIMARY KEY Constraints
Key Points Primary key constraints are used to uniquely identify each row in a table. They must be unique and not NULL. They may involve multiple columns. SQL Server will internally create an index to support the PRIMARY KEY constraint.
PRIMARY KEY Constraints In database terminology, the term “candidate key” is used to describe the column or combination of columns that are required to be able to uniquely identify a row of data within a table. None of the columns that are part of a candidate key are permitted to be nullable. A PRIMARY KEY is a candidate key that has been chosen as the primary way to identify each row in a table. For example, in the example shown in the slide, the OpportunityID column has been chosen as the PRIMARY KEY. As was described with other types of constraints, even though a name is not required when defining a PRIMARY KEY constraint, it is desirable to choose a name for the constraint rather than allowing SQL Server to do so.
Natural vs. Surrogate Keys A near religious debate exists in the database community about the use of natural vs. surrogate keys. A natural key is formed from one or more columns that exist in the data within the table. For example, you might identify a product by its description, size, and color. A surrogate key is a value that is unrelated to the data. For example, you might give a customer a number. Surrogate keys are often chosen as they are typically smaller than natural keys (which in some situations can help with performance) and because it can be very difficult to locate appropriate natural keys.
14-20
Implementing a Microsoft® SQL Server® 2008 R2 Database
For example, consider a Person table. What attributes of a person you might need to combine before you could uniquely identify that person. Further, which of these attributes will never change? Ideally, primary keys for tables should not change values over time. Question: In the example table shown in the slide, if the table did not have the OpportunityID column, what combinations of columns would be needed to create a candidate key?
Ensuring Data Integrity through Constraints
14-21
UNIQUE Constraints
Key Points A UNIQUE constraint indicates that the column or combination of columns is unique. One row can be NULL. SQL Server will internally create an index to support the UNIQUE constraint.
UNIQUE Constraints A UNIQUE constraint is used to ensure that more than one row does not have a single value. For example, in Spain, all Spanish citizens over the age of 14 are issued with a national identity document called a DNI (Documento Nacional de Identidad). It is a unique number in the format 99999999-X where 9 is a digit and X is a letter used as a checksum of the digits. People from other countries that need a Spanish identification number are given an NIE (Numero de Indentificacion de Extranjeros) with a slightly different format X-99999999-X. If you were storing a tax identifier for employees in Spain, you would store one of these values, you would include a CHECK constraint to make sure the value is in one of the two valid formats and you would have a UNIQUE constraint on the column that stores these values. Note that this may be unrelated to the fact that the table has another unique identifier such as an EmployeeID that is used as a primary key for the table. As was described with other types of constraints, even though a name is not required when defining a UNIQUE constraint, it is desirable to choose a name for the constraint rather than allowing SQL Server to do so.
NULL and UNIQUE While it is possible for a value that is required to be unique to be NULL, this is only permitted for a single row. In practice, this means that nullable unique columns are rare.
14-22
Implementing a Microsoft® SQL Server® 2008 R2 Database
FOREIGN KEY Constraints
Key Points A FOREIGN KEY constraint is used to establish a link between the data in tables and can be used to enforce the relationship.
FOREIGN KEY Constraints As mentioned earlier, you might want to make sure that a customer exists before you allow an order to be entered for the customer. This can be enforced in this form of integrity (referred to as referential integrity) with FOREIGN KEY constraints. A FOREIGN KEY constraint must refer to either a PRIMARY KEY or a UNIQUE constraint in the target table if the value in the referencing table is not NULL. Note that you cannot change the length of a column that is defined with a FOREIGN KEY constraint. The target table can be the same table. For example, an employee row might reference a manager that is another row in the same employee table. As described with other types of constraints, even though a name is not required when defining a FOREIGN KEY constraint, it is desirable to choose a name for the constraint rather than allowing SQL Server to do so.
WITH NOCHECK When you add a FOREIGN KEY constraint to a column (or columns) in a table, SQL Server will check the data already in the column to make sure that the reference to the target table is valid. However, if you specify WITH NOCHECK, SQL Server does not apply the check to existing rows and will only check the reference in future when rows are inserted or updated. The NOCHECK option can be applied to other types of constraints as well.
Ensuring Data Integrity through Constraints
14-23
REFERENCES Permission Before you can place a FOREIGN KEY constraint on a table, you must at least have REFERENCES permission on the target table. This avoids the situation where another user could place a reference to one of your tables and then you would be unable to drop or substantially change your own table until that reference was removed by the other user. In terms of security though, keep in mind that providing REFERENCES permission to a user on a table that they do not have SELECT permission on does not totally prevent them from working out what the data in the table is, by a brute force attempt that involves trying all possible values.
14-24
Implementing a Microsoft® SQL Server® 2008 R2 Database
Cascading Referential Integrity
Key Points The FOREIGN KEY constraint includes a CASCADE option that allows any change to a column value that defines a UNIQUE or PRIMARY KEY constraint to propagate the change to any foreign key values that reference it. This action is referred to as cascading referential integrity.
Cascading Referential Integrity By using cascading referential integrity constraints, you can define the actions that SQL Server takes when a user tries to update or delete a key column (or columns) to which a FOREIGN KEY constraint references. The action to be taken is separately defined for UPDATE and DELETE actions and can have four values. NO ACTION is the default. For example, if you attempt to delete a customer and there are orders for the customer, the delete will fail. CASCADE makes the required changes to the referencing tables. If the customer is being deleted, their orders will be deleted as well. If the customer primary key is being updated (note this is undesirable anyway), then the customer key in the orders table will also be updated so that the orders still refer to the correct customer. SET NULL causes the values in the columns in the referencing table to be nullified. For the customer and orders example, this means that the orders would still exist but they would not refer to any customer. SET DEFAULT causes the values in the columns in the referencing table to be set to their default values. This allows for more control than the SET NULL option which always sets the values to NULL.
Cautions While cascading referential integrity is easy to set up, extreme caution should be exercised in using it within database designs.
Ensuring Data Integrity through Constraints
14-25
For example, in the CASCADE option, would it really be okay for the orders for the customer to be removed when you decide to remove a customer, based on business rules? Most organizations might be okay with orders disappearing but might be much less happy to see other objects like invoices disappearing. Also, keep in mind the cascading nature of this situation. When you remove the customer, you remove the orders. But there may be other tables referencing the orders table (such as order details or even invoices). These will be removed as well. Question: Think of a scenario involving data for a human resources department. What types of cascading options would be appropriate for updating or deleting records?
14-26
Implementing a Microsoft® SQL Server® 2008 R2 Database
Considerations for Constraint Checking
Key Points There are a few common considerations that need to be made when working with constraints.
Naming As mentioned earlier in the module, you should specify meaningful names for constraints rather than having SQL Server select a name. SQL Server provides complicated system-generated names. Often, you need to refer to constraints by name. Therefore, it is better to have chosen them yourself and to have applied a consistent naming convention when doing so.
Changing Constraints You can create, alter, or drop constraints without having to drop and recreate the underlying table. Constraints are added, altered, or dropped with the ALTER TABLE statement.
Error Checking in Applications Even though you have specified constraints in your database layer, you may also want to be checking these same references in higher layers of code. Doing so will allow for more responsive systems (that go through less layers of code) and provide more meaningful errors back to users as the code is closer to the business-related logic that led to the errors. The challenge though is in keeping the checks between different layers consistent.
High Performance Data Loading or Updates When performing bulk loading or updates of data, better performance will often be achieved by disabling constraints (CHECK and FOREIGN KEY constraints) while performing the bulk operations and then reenabling them afterwards, rather than having them checked row by row during the bulk operation.
Ensuring Data Integrity through Constraints
14-27
Demonstration 3A: Entity and Referential Integrity
Key Points In this demonstration you will see how to define: •
Entity integrity for tables
•
Referential integrity for tables
•
Cascading referential integrity constraints
Demonstration Steps 1.
2. 3.
If Demonstration 2A was not performed: •
Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system.
•
In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_14_PRJ\6232B_14_PRJ.ssmssln and click Open.
•
Open and execute the 00 – Setup.sql script file from within Solution Explorer.
Open the 31 – Demonstration 3A.sql script file. Follow the instructions contained within the comments of the script file.
14-28
Implementing a Microsoft® SQL Server® 2008 R2 Database
Lab 14: Ensuring Data Integrity through Constraints
Lab Setup For this lab, you will use the available virtual machine environment. Before you begin the lab, you must complete the following steps: 1. 2. 3.
4.
5. 6. 7.
On the host computer, click Start, point to Administrative Tools, and then click Hyper-V Manager. Maximize the Hyper-V Manager window. In the Virtual Machines list, if the virtual machine 623XB-MIA-DC is not started: •
Right-click 623XB-MIA-DC and click Start.
•
Right-click 623XB-MIA-DC and click Connect.
•
In the Virtual Machine Connection window, wait until the Press CTRL+ALT+DELETE to log on message appears, and then close the Virtual Machine Connection window.
In the Virtual Machines list, if the virtual machine 623XB-MIA-SQL is not started: •
Right-click 623XB-MIA-SQL and click Start.
•
Right-click 623XB-MIA-SQL and click Connect.
•
In the Virtual Machine Connection window, wait until the Press CTRL+ALT+DELETE to log on message appears.
In Virtual Machine Connection window, click on the Revert toolbar icon. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action to complete. In the Virtual Machine Connection window, if the user is not already logged on: •
On the Action menu, click the Ctrl-Alt-Delete menu item.
•
Click Switch User, and then click Other User.
•
Log on using the following credentials:
Ensuring Data Integrity through Constraints
14-29
i. User name: AdventureWorks\Administrator ii. Password: Pa$$w0rd 8. From the View menu, in the Virtual Machine Connection window, click Full Screen Mode. 9. If the Server Manager window appears, check the Do not show me this console at logon check box and close the Server Manager window. 10. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, and click SQL Server Management Studio. 11. In Connect to Server window, type Proseware in the Server name text box. 12. In the Authentication drop-down list box, select Windows Authentication and click Connect. 13. In the File menu, click Open, and click Project/Solution. 14. In the Open Project window, open the project D:\6232B_Labs\6232B_14_PRJ\6232B_14_PRJ.ssmssln. 15. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.
Lab Scenario A table named Marketing.Yield has recently been added to the Marketing system in the MarketDev database but has no constraints in place. In this lab, you will implement the required constraints to ensure data integrity and, if you have time, test that constraints work as specified.
Supporting Documentation Table Marketing.Yield Note: Primary key should be a combination of ProspectID and LanguageID and should be a clustered primary key.
Column
Data Type
Mandatory Field
Validation rule
ProspectID
int
Required
Must be a valid prospect
LanguageID
nchar(6)
Required
Must be a valid language
YieldOutcome
int
Required
Default value should be zero if not supplied Must be a value between 0 and 9
RowID
uniqueidentifier
Required
Default value should be a new uniqueidentifier if not supplied Must be unique
LastUpdate
datetime2
Required
Notes
nvarchar(MAX)
Optional
Default value should be SYSDATETIME() if not supplied
14-30
Implementing a Microsoft® SQL Server® 2008 R2 Database
Exercise 1: Constraint Design Scenario You have been provided with the design for a table called Marketing.Yield. You need to alter the table with the appropriate constraints based upon the provided specifications. The main tasks for this exercise are as follows: 1. 2.
Review the supporting documentation Alter the Marketing.Yield table
Task 1: Review the supporting documentation •
Review the table design requirements supplied in the supporting documentation.
Task 2: Alter the Marketing.Yield table •
Work through the list of requirements and alter the table with appropriate constraints based on the requirements. Results: After this exercise, you should have altered the Marketing.Yield table.
Ensuring Data Integrity through Constraints
14-31
Challenge Exercise 2: Test the constraints (Only if time permits) Scenario You should now test each of the constraints that you designed to ensure they work as expected. The main tasks for this exercise are as follows: 1. 2. 3. 4.
Test the default values and data types. Test the primary key. Test the foreign key reference on language. Test the foreign key reference on prospect.
Task 1: Test the default values and data types •
Execute T-SQL statements to ensure that the default values and data types work as expected.
Task 2: Test the primary key •
Execute T-SQL statements to ensure that the primary key reference works as expected.
Task 3: Test the foreign key reference on language •
Execute T-SQL statements to ensure that the foreign key reference on LanguageID works as expected.
Task 4: Test the foreign key reference on prospect •
Execute T-SQL statements to ensure that the foreign key reference on ProspectID works as expected. Results: After this exercise, you should have tested and confirmed that the constraints that are functioning as expected.
14-32
Implementing a Microsoft® SQL Server® 2008 R2 Database
Module Review and Takeaways
Review Questions 1. 2.
Why implement check constraints if an application is already checking the input data? What are some scenarios in which you may want to temporarily disable constraint checking?
Best Practices 1.
When you create a constraint on a column, if you do not specify a name for the constraint, SQL will generate a unique name for the constraint. However, you may want to be sure to always name constraints to adhere to your naming conventions.
Responding to Data Manipulation via Triggers
Module 15 Responding to Data Manipulation via Triggers Contents: Lesson 1: Designing DML Triggers
15-3
Lesson 2: Implementing DML Triggers
15-13
Lesson 3: Advanced Trigger Concepts
15-20
Lab 15: Responding to Data Manipulation via Triggers
15-30
15-1
15-2
Implementing a Microsoft® SQL Server® 2008 R2 Database
Module Overview
Data manipulation language (DML) triggers are a powerful tool that enables you to enforce domain, entity, and referential data integrity and business logic. The enforcement of integrity helps you to build reliable applications. In this lesson, you will learn what DML triggers are and how they enforce data integrity, the different types of triggers available to you, and how to define triggers in your database.
Objectives After completing this module, you will be able to: • • •
Design DML triggers Implement DML triggers Explain advanced DML trigger concepts
Responding to Data Manipulation via Triggers
15-3
Lesson 1
Designing DML Triggers
Before beginning to create DML triggers, it is important to become familiar with how they should be designed, to avoid making common design errors. Several types of DML triggers are available. It is important to know what they do and how they work and it is also important to understand how they differ from DDL triggers. DML triggers need to be able to work with both the previous state of the database and its changed state. You will see how the inserted and deleted virtual tables provide that capability. As DML triggers are often added after applications are built, it is important then to make sure that adding a trigger does not cause errors in the applications that were designed without them being in place. SET NOCOUNT ON helps avoid side effects of triggers.
Objectives After completing this lesson, you will be able to: • • • • •
Describe DML triggers. Explain how AFTER triggers differ from INSTEAD OF triggers and where each should be used. Access both the prior and final states of the database data by using the inserted and deleted virtual tables. Avoid impacting existing applications by using SET NOCOUNT ON. Describe performance-related considerations for triggers.
15-4
Implementing a Microsoft® SQL Server® 2008 R2 Database
What are DML Triggers?
Key Points A DML trigger is a special kind of stored procedure that executes when an INSERT, UPDATE, or DELETE statement modifies the data in a specified table or view. This includes any INSERT, UPDATE, or DELETE statement that form part of a MERGE statement. A trigger can query other tables and can include complex Transact-SQL statements. DDL triggers are similar to DML triggers but DDL triggers fire when DDL events occur. DDL events occur for most CREATE, ALTER or DROP statements in the T-SQL language. Logon triggers are a special form of trigger that fire when a new session is established. There is no concept of a Logoff trigger at present.
Trigger Operation The trigger and the statement that fires it are treated as a single operation, which can be rolled back from within the trigger. The ability to roll back a transaction allows you to undo the effect of a T-SQL statement if the logic in your triggers decides that the statement should not have been executed. If the statement is part of another transaction, that outer transaction is also rolled back. Triggers can cascade changes through related tables in the database; however, in many cases, these changes can be executed more efficiently by using cascading referential integrity constraints.
Complex Logic and Meaningful Error Messages Triggers can guard against malicious or incorrect INSERT, UPDATE, and DELETE operations and enforce other restrictions that are more complex than those defined by using CHECK constraints. For example, a trigger could check referential integrity for one column, only when another column holds a specific value. Unlike CHECK constraints, triggers can reference columns in other tables. For example, a trigger can use a SELECT statement from another table to compare to the inserted or updated data and to perform additional actions, such as modifying the data or displaying a user-defined error message.
Responding to Data Manipulation via Triggers
15-5
Triggers can evaluate the state of a table before and after a data modification and take actions based on that difference. For example, you may wish to check that the balance of a customer's account does not change by more than a certain amount, if the person processing the change is not a manager. Triggers also allow the use of custom error messages for when constraint violations occur. This could make the messages that are passed to end users more meaningful.
Multiple Triggers Multiple triggers of the same type (INSERT, UPDATE, or DELETE) on a table allow multiple different actions to take place in response to the same modification statement. Question: Why would you choose to use a DML trigger instead of a constraint?
15-6
Implementing a Microsoft® SQL Server® 2008 R2 Database
AFTER Triggers vs. INSTEAD OF Triggers
Key Points There are two types of DML triggers: AFTER triggers and INSTEAD OF triggers. The main difference between them relates to when they fire. One fires after the event, the other fires instead of the event. Each type of DML trigger can be implemented in either T-SQL or in managed code. In this module, you will explore how they are designed and implemented using T-SQL. Managed code is described in Module 16: Implementing Managed Code in SQL Server. It is important to realize that even if an UPDATE (or other data modification statement) modifies many rows, the trigger only fires a single time. For that reason, triggers need to be designed to handle multiple rows. This design is different to other database engines where triggers are written to target single rows and are called multiple times when a statement affects multiple rows.
AFTER Triggers AFTER triggers fire after the data modifications that are part of the event that they relate to completes. This means that an INSERT, UPDATE, or DELETE statement executes and modifies the data in the database. After that modification has completed, AFTER triggers associated with that event then fire. Common reasons for implementing AFTER triggers are: •
Providing auditing of the changes that were made.
•
Implementing complex rules involving the relationship between tables.
•
Implementing default values or calculated values within rows.
In many cases, trigger-based code can be replaced by other forms of code. For example, auditing might be provided by SQL Server Audit (discussed in course 6231B – Maintaining a SQL Server 2008 R2 Database). Relationships between tables are more typically implemented via foreign key constraints. Default values and calculated values are typically implemented via DEFAULT constraints and persisted
Responding to Data Manipulation via Triggers
15-7
calculated columns. In some situations though, the complexity of the logic required will make triggers a good solution. If the trigger executes a ROLLBACK statement, the data modification statement that it is associated with will be rolled back. If that statement was part of a larger transaction, that other transaction would be rolled back too.
INSTEAD OF Triggers INSTEAD OF triggers are a special type of trigger that executes alternate code instead of executing the statement that they were fired from. It is important to realize that with an INSTEAD OF trigger, only the code in the trigger is executed. A very common use case for INSTEAD OF triggers is to allow views that are based on multiple base tables to be updatable. Question: Why would the ability to run alternate code help to allow views with multiple base tables to be updatable?
15-8
Implementing a Microsoft® SQL Server® 2008 R2 Database
Inserted and Deleted Virtual Tables
Key Points When designing a trigger, it is important to be able to make decisions based on what changes have been made to the data. To arrive at effective decisions, access is needed to details of both the unmodified and modified versions of the data. DML triggers provide this via a pair of virtual tables called inserted and deleted. These virtual tables are often then joined to the modified table data as part of the logic within the trigger.
inserted Virtual Table After an INSERT operation, the inserted virtual table holds details of the rows just inserted. The underlying table also has those rows in it. After an UPDATE operation, the inserted virtual table holds details of the modified versions of the rows. The underlying table also has those rows in the modified form.
deleted Virtual Table After a DELETE operation, the deleted virtual table holds details of the rows just deleted. The underlying table no longer contains those rows. After an UPDATE operation, the deleted virtual table holds details of the rows prior to the modification being made. The underlying table holds the modified versions.
INSTEAD OF Triggers and the inserted and deleted Virtual Tables When an INSERT, DELETE, or UPDATE statement is attempted and an INSTEAD OF trigger is associated with the event on the table, the inserted and deleted virtual tables hold details of the modifications that need to be made but have not yet been made.
Responding to Data Manipulation via Triggers
15-9
Scope of inserted and deleted The inserted and deleted virtual tables are only available during the execution of the trigger code and are scoped directly to the trigger code. This means that if the trigger code was to execute a stored procedure, that stored procedure would not have access to the inserted and deleted virtual tables.
15-10
Implementing a Microsoft® SQL Server® 2008 R2 Database
SET NOCOUNT ON
Key Points When adding a trigger to a table, it is important to avoid breaking any existing applications that are accessing the table unless the intended purpose of the trigger is to avoid misbehaving applications from making inappropriate data changes. It is common for application programs to issue data modification statements and to check the returned count of the number of rows affected. This is often done as part of an optimistic concurrency check. For example, consider the following code: UPDATE Customer SET Customer.FullName = @NewName, Customer.Address = @NewAddress WHERE Customer.CustomerID = @CustomerID AND Customer.Concurrency = @Concurrency;
In this case, the column Concurrency is a rowversion data type column. The application was designed so that the update only occurs if the Concurrency column has not been altered. With rowversion columns, every modification to the row causes a change in the rowversion column. When the application intends to modify a single row, it issues an UPDATE statement for that row. The application then checks the count of updated rows that is returned by SQL Server. When the application sees that only a single row has been modified, the application knows that only the row it intended to change was changed. It also knows that no other user had modified the row since the application read the data. A common mistake when adding triggers is that if the trigger also causes row modifications (for example, writes an audit row into an audit table), that count is returned in addition to the expected count. This situation can be avoided by the SET NOCOUNT ON statement. Most triggers should include this statement.
Responding to Data Manipulation via Triggers
15-11
Returning Rowsets While it is possible to include a SELECT statement within a trigger and for it to return rows, the creation of this type of side-effect is discouraged. In future versions of SQL Server, the ability to do this is likely to be removed. In SQL Server 2008 R2, there is a configuration setting ‘disallow results from triggers’ which when set to 1, will disallow this capability.
15-12
Implementing a Microsoft® SQL Server® 2008 R2 Database
Trigger Performance Considerations
Key Points In general, constraints are preferred to triggers for performance reasons. Triggers are also complex to debug as the actions they perform are not visible directly in the code that causes them to fire. Triggers also increase the time taken for data modification transactions as they add extra steps that SQL Server needs to process during these operations.
Constraints vs. Triggers When an AFTER trigger decides to disallow a data modification, it does so by executing a ROLLBACK statement. This causes the entire work done by the statement to then be undone by the ROLLBACK. Higher performance is obtained by avoiding the data modification ever occurring. Constraints are checked before any data modification is attempted and so often provide much higher performance than is possible with triggers, particularly in ROLLBACK situations. Constraints are used when the checks that need to be performed are relatively simple. Triggers allow complex logic to be checked.
RowVersions and tempdb Since SQL Server 2005, trigger performance has been improved when compared to earlier versions. In earlier versions, the inserted and deleted virtual tables were essentially like a view above the data in the transaction log. The data in these tables needed to be reconstructed when it was required. From SQL Server 2005 onwards, a special rowversion table was provided in the tempdb database. This special table holds copies of the data in the inserted and deleted virtual tables for the duration of the trigger. This design improved the performance of triggers but means that excessive usage of triggers could cause performance issues within the tempdb database.
Responding to Data Manipulation via Triggers
Lesson 2
Implementing DML Triggers
Lesson 1 provided information on designing DML triggers. It is now important to consider how to implement the designs that have been created.
Objectives After completing this lesson, you will be able to: • • •
Implement AFTER INSERT triggers. Implement AFTER DELETE triggers. Implement AFTER UPDATE triggers.
15-13
15-14
Implementing a Microsoft® SQL Server® 2008 R2 Database
AFTER INSERT Triggers
Key Points An INSERT trigger is a trigger that executes whenever an INSERT statement enters data into a table or a view on which the trigger is configured. The action of the INSERT statement is completed before the trigger fires.
AFTER INSERT Trigger Actions When an AFTER INSERT trigger fires, new rows are added to both the base table and to the inserted virtual table. The inserted virtual table holds a copy of the rows that have been inserted into the base table. The trigger can examine the inserted virtual table to determine whether or how the trigger actions should be executed.
Multi-Row Inserts In the example shown, insertions to the table Sales.Opportunity are being audited to a table called Sales.OpportunityAudit. Note that the trigger processes all inserted rows at once. A common error when designing AFTER INSERT triggers is to write them with the assumption that only a single row is being inserted. Question: When would you use an INSERT trigger?
Responding to Data Manipulation via Triggers
15-15
Demonstration 2A: AFTER INSERT Triggers
Key Points In this demonstration you will see how to: •
Create an AFTER INSERT trigger
•
Test the trigger action
•
Drop the trigger
Demonstration Steps 1. 2.
3. 4. 5.
Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_15_PRJ\6232B_15_PRJ.ssmssln and click Open. Open and execute the 00 – Setup.sql script file from within Solution Explorer. Open the 21 – Demonstration 2A.sql script file. Follow the instructions contained within the comments of the script file.
15-16
Implementing a Microsoft® SQL Server® 2008 R2 Database
AFTER DELETE Triggers
Key Points A DELETE trigger is a trigger that executes whenever a DELETE statement deletes data from a table or view on which the trigger is configured. The action of the DELETE statement is completed before the trigger fires.
AFTER DELETE Trigger Actions When an AFTER DELETE trigger fires, rows are removed from the base table and added to the deleted virtual table. The deleted virtual table holds a copy of the rows that have been deleted from the base table. The trigger can examine the deleted virtual table to determine whether or how the trigger actions should be executed.
Multi-Row Deletes In the example shown, rows in the Product.Product table are being flagged as discontinued if the product category row they are associated with in the Product.Category table is deleted. Note that the trigger processes all deleted rows at once. A common error when designing AFTER DELETE triggers is to write them with the assumption that only a single row is being deleted.
TRUNCATE TABLE When rows are deleted from a table using a DELETE statement, any AFTER DELETE triggers are fired when the deletion is completed. TRUNCATE TABLE is an administrative option that removes all rows from a table. It needs additional permissions above those required for deleting rows. It does not fire any AFTER DELETE triggers associated with the table. Question: What performance and archival considerations should you think about when planning how to handle deleted records?
Responding to Data Manipulation via Triggers
15-17
Demonstration 2B: AFTER DELETE Triggers
Key Points In this demonstration you will see how to: •
Create an AFTER DELETE trigger
•
Test the trigger
•
Drop the trigger
Demonstration Steps 1.
2. 3.
If Demonstration 2A was not performed: •
Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system.
•
In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_15_PRJ\6232B_15_PRJ.ssmssln and click Open.
•
Open and execute the 00 – Setup.sql script file from within Solution Explorer.
Open the 22 – Demonstration 2B.sql script file. Follow the instructions contained within the comments of the script file.
15-18
Implementing a Microsoft® SQL Server® 2008 R2 Database
AFTER UPDATE Triggers
Key Points An UPDATE trigger is a trigger that executes whenever an UPDATE statement modified data in a table or a view on which the trigger is configured. The action of the UPDATE statement is completed before the trigger fires.
AFTER UPDATE Trigger Actions When an AFTER UPDATE trigger fires, update actions are treated as a set of deletions of how the rows were and insertions of how the rows now are. Rows that are to be modified in the base table are copied to the deleted virtual table and the updated versions of the rows are copied to the inserted virtual table. The inserted virtual table holds a copy of the rows in their modified state, the same as how the rows appear now in the base table. The trigger can examine both the inserted and deleted virtual tables to determine whether and how the trigger actions should be executed.
Multi-Row Updates In the example shown, the table Product.ProductReview contains a column called ModifiedDate. The trigger is being used to ensure that as changes are made to the Product.ProductReview table that the value in this column always reflects when any changes last happened. Note that the trigger processes all updated rows at once. A common error when designing AFTER UPDATE triggers is to write them with the assumption that only a single row is being updated. Question: When would you imagine you might use an UPDATE trigger in your own coding?
Responding to Data Manipulation via Triggers
15-19
Demonstration 2C: AFTER UPDATE Triggers
Key Points In this demonstration you will see how to: •
Create an AFTER UPDATE trigger
•
Test the trigger
•
Query the sys.triggers view
Demonstration Steps 1.
2. 3.
If Demonstration 2A was not performed: •
Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system.
•
In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_15_PRJ\6232B_15_PRJ.ssmssln and click Open.
•
Open and execute the 00 – Setup.sql script file from within Solution Explorer.
Open the 23 – Demonstration 2C.sql script file. Follow the instructions contained within the comments of the script file.
15-20
Implementing a Microsoft® SQL Server® 2008 R2 Database
Lesson 3
Advanced Trigger Concepts
In Lessons 1 and 2, you have learned to design and implement DML AFTER triggers. There are additional areas of complexity related to triggers that also need to be understood to make effective use of them. It is also important to understand where to use triggers and where to consider alternatives to triggers. Provide a brief introduction to this lesson in normal text. A module must have at least two lessons.
Objectives After completing this lesson, you will be able to: • • • • • •
Implement INSTEAD OF DML triggers. Explain how nested triggers work and how configurations might affect their operation. Explain additional considerations for recursive triggers that is triggers that include actions that cause the same trigger to fire again. Use the UPDATE function to build logic based on the columns being updated. Describe the limited control that can be exerted over the order that triggers fire in when multiple triggers are defined for the same event on the same object. Explain the alternatives to using triggers.
Responding to Data Manipulation via Triggers
15-21
INSTEAD OF Triggers
Key Points INSTEAD OF triggers cause the execution of alternate code instead of executing the statement that they were fired from.
INSTEAD OF vs BEFORE Triggers Some other database engines provide BEFORE triggers. In those databases, the action in the BEFORE trigger happens before the data modification statement which also occurs. SQL Server INSTEAD OF triggers are different from the BEFORE triggers that you may have come across in other database engines. It is important to realize that with an INSTEAD OF trigger as implemented in SQL Server, only the code in the trigger is executed. The original operation that caused the trigger to fire is not executed.
Updatable Views A very common use case for INSTEAD OF triggers is to allow views that are based on multiple base tables to be updatable. INSTEAD OF triggers can be defined on views with one or more base tables, where they can extend the types of updates a view can support. This trigger executes instead of the original triggering action. INSTEAD OF triggers increase the variety of types of updates that you can perform against a view. Each table or view is limited to one INSTEAD OF trigger for each triggering action (INSERT, UPDATE, or DELETE). You can specify an INSTEAD OF trigger on both tables and views. You cannot create an INSTEAD OF trigger on views that have the WITH CHECK OPTION defined. Question: What sort of situations would lead you to need to execute different statements to the data modification statements requested?
15-22
Implementing a Microsoft® SQL Server® 2008 R2 Database
Demonstration 3A: INSTEAD OF Triggers
Key Points In this demonstration you will see how to: •
Create an INSTEAD OF trigger
•
Test the trigger
Demonstration Steps 1.
2. 3.
If Demonstration 2A was not performed: •
Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system.
•
In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_15_PRJ\6232B_15_PRJ.ssmssln and click Open.
•
Open and execute the 00 – Setup.sql script file from within Solution Explorer.
Open the 31 – Demonstration 3A.sql script file. Follow the instructions contained within the comments of the script file.
Question: Why does the DELETE succeed when INSERT and UPDATE fail?
Responding to Data Manipulation via Triggers
15-23
How Nested Triggers Work
Key Points Triggers can contain UPDATE, INSERT, or DELETE statements. When these statements on one table cause triggers on another table to fire, the triggers are considered to be nested.
Nested Triggers Triggers are often used for auditing purposes. Nested triggers are essential for full auditing to occur. Otherwise, actions would occur on tables without being audited. It is possible to control whether or not nested trigger actions are permitted. By default, these actions are permitted via a configuration option at the server level. A failure at any level of a set of nested triggers cancels the entire original statement, and all data modifications are rolled back. A nested trigger will not fire twice in the same trigger transaction; a trigger does not call itself in response to a second update to the same table within the trigger.
Complexity of Debugging It was mentioned in an earlier lesson that debugging triggers can be difficult. Nested and recursive triggers are particularly difficult to debug. One common method that is used during debugging is to include PRINT statements within the trigger code bodies so that you can determine where a failure occurred. Question: How might nested triggers work in an Employee database?
15-24
Implementing a Microsoft® SQL Server® 2008 R2 Database
Considerations for Recursive Triggers
Key Points A recursive trigger is a trigger that performs an action that causes the same trigger to fire again either directly or indirectly. Any trigger can contain an UPDATE, INSERT, or DELETE statement that affects the same table or another table. With the recursive trigger option enabled, a trigger that changes data in a table can activate itself again, in a recursive execution.
Direct Recursion Direct recursion occurs when a trigger fires and performs an action on the same table that causes the same trigger to fire again. For example, an application updates table T1, which causes trigger Trig1 to fire. Trig1 updates table T1 again, which causes trigger Trig1 to fire again.
Indirect Recursion Indirect recursion occurs when a trigger fires and performs an action that causes another trigger to fire (in the same or a different table), and subsequently causes an update to occur on the original table. This, then, causes the original trigger to fire again. For example, an application updates table T2, which causes trigger Trig2 to fire. Trig2 updates table T3, which causes trigger Trig3 to fire. Trig3 in turn updates table T2, which causes Trig2 to fire again. If a trigger modifies a table that causes another trigger to fire, and the second trigger modifies the original table, the original trigger will fire recursively. To prevent indirect recursion of this sort, turn off the nested triggers option. You can use the RECURSIVE_TRIGGERS database option to enable or disable direct recursion in triggers. Question: Think of a database containing genealogy data. How might a recursive trigger be used when a relationship between two people is corrected (such as from child and parent to grandchild and grandparent, with an intermediate generation inserted)?
Responding to Data Manipulation via Triggers
15-25
UPDATE Function
Key Points It is a common requirement to build logic that only takes action if particular columns are being updated.
UPDATE Function The UPDATE function should not be confused with the UPDATE statement. The UPDATE function allows detection of whether or not a particular column is being updated in the action of an UPDATE statement. For example, you might wish to take a particular action only when the Size of a product changes. The column is referenced by the name of the column.
Change of Value Note that this function does not indicate if the value is actually changing. It only indicates if the column is part of the list of columns in the SET clause of the UPDATE statement. To detect if the value in a column is actually being changed to a different value, the inserted and deleted virtual tables need to be interrogated.
COLUMNS_UPDATED Function SQL Server also provides a function called COLUMNS_UPDATED. This function returns a bitmap that indicates which columns are being updated. The values in the bitmap depend upon the positional information for the columns. Hard-coding that sort of information in the code within a trigger is generally not considered good coding practice as it affects the readability (and hence the maintainability) of your code.
15-26
Implementing a Microsoft® SQL Server® 2008 R2 Database
Trigger Firing Order
Key Points It is possible to assign multiple triggers to a single event on a single object. Only limited control is available over the firing order of these triggers.
sp_settriggerorder Developers often seek to control the firing order of multiple triggers defined for a single event on a single object. For example, a developer might create three AFTER INSERT triggers on the same table, each implementing different business rules or administrative tasks. In general, code within one trigger should not depend upon the order of execution of other triggers. Limited control of firing order is available through the sp_settriggerorder system stored procedure. It allows you to specify which trigger fires first and which trigger fires last, from a set of triggers that all apply to the same event on the same object. The value for the @order parameter is either First, Last, or None. None is the default action. An error will occur if the First and Last triggers both refer to the same trigger. The value for the @stmttype parameter is INSERT, UPDATE, or DELETE for DML triggers.
Responding to Data Manipulation via Triggers
15-27
Alternatives to Using Triggers
Key Points Triggers allow for complex logic and are sometimes necessary. Triggers are often though, used in situations where other alternatives would be preferable.
Checking Values Triggers could be used to check that values in columns are valid or within given ranges. In general, CHECK constraints should be used for this instead of triggers as they are checked before the data modification is attempted. If the trigger is being used to check the correlation of values across multiple columns within the table, in general table-level CHECK constraints should be created instead.
Defaults Triggers can be used to provide default values for columns when no values have been provided in INSERT statements. DEFAULT constraints should generally be used for this instead.
Foreign Keys Triggers can be used to check the relationship between tables. In general, FOREIGN KEY constraints should be used for this.
Computed Columns Triggers can be used to maintain the value in one column based on the value in other columns. In general, computed columns or persisted computed columns should be used for this.
Pre-calculating Aggregates Triggers can be used to maintain pre-calculated aggregates in one table, based on the values in rows in another table. In general, indexed views should be used to provide this functionality.
15-28
Implementing a Microsoft® SQL Server® 2008 R2 Database
Constraint Use Is Not Always Possible While general guidelines are provided here, replacing the triggers with these alternatives is not always possible. For example, the logic required when checking values might be too complex for a CHECK constraint. As another example, a FOREIGN KEY cannot be contained on a column that is also used for other purposes. Consider a column that holds an employee number only if another column holds the value ‘E’. While this typically indicates a poor database design, triggers can be used to ensure this sort of relationship.
Responding to Data Manipulation via Triggers
15-29
Demonstration 3B: Replacing Triggers with Computed Columns
Key Points In this demonstration you will see how a trigger could be replaced by a computed column.
Demonstration Steps 1.
2. 3.
If Demonstration 2A was not performed: •
Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system.
•
In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_15_PRJ\6232B_15_PRJ.ssmssln and click Open.
•
Open and execute the 00 – Setup.sql script file from within Solution Explorer.
Open the 32 – Demonstration 3B.sql script file. Follow the instructions contained within the comments of the script file.
15-30
Implementing a Microsoft® SQL Server® 2008 R2 Database
Lab 15: Responding to Data Manipulation via Triggers
Lab Setup For this lab, you will use the available virtual machine environment. Before you begin the lab, you must complete the following steps: 1. 2. 3.
4.
5. 6. 7.
On the host computer, click Start, point to Administrative Tools, and then click Hyper-V Manager. Maximize the Hyper-V Manager window. In the Virtual Machines list, if the virtual machine 623XB-MIA-DC is not started: •
Right-click 623XB-MIA-DC and click Start.
•
Right-click 623XB-MIA-DC and click Connect.
•
In the Virtual Machine Connection window, wait until the Press CTRL+ALT+DELETE to log on message appears, and then close the Virtual Machine Connection window.
In the Virtual Machines list, if the virtual machine 623XB-MIA-SQL is not started: •
Right-click 623XB-MIA-SQL and click Start.
•
Right-click 623XB-MIA-SQL and click Connect.
•
In the Virtual Machine Connection window, wait until the Press CTRL+ALT+DELETE to log on message appears.
In Virtual Machine Connection window, click on the Revert toolbar icon. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action to complete. In the Virtual Machine Connection window, if the user is not already logged on: •
On the Action menu, click the Ctrl-Alt-Delete menu item.
•
Click Switch User, and then click Other User.
Responding to Data Manipulation via Triggers
•
Log on using the following credentials: I. II.
8. 9. 10. 11. 12. 13. 14. 15.
15-31
User name: AdventureWorks\Administrator Password: Pa$$w0rd
From the View menu, in the Virtual Machine Connection window, click Full Screen Mode. If the Server Manager window appears, check the Do not show me this console at logon check box and close the Server Manager window. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, and click SQL Server Management Studio. In Connect to Server window, type Proseware in the Server name text box. In the Authentication drop-down list box, select Windows Authentication and click Connect. In the File menu, click Open, and click Project/Solution. In the Open Project window, open the project D:\6232B_Labs\6232B_15_PRJ\6232B_15_PRJ.ssmssln. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.
Lab Scenario You are required to audit any changes to data in a table that hold sensitive balance data. You have decided to implement this via DML triggers as the requirements in this case are not provided for directly by the SQL Server Audit mechanism.`
Supporting Documentation The Marketing.CampaignAudit table is used to hold audit entries. When inserting rows into this table, the data required in each column is as shown in the following table: Column
Data Type
Value to Insert
CampaignAuditID
int
IDENTITY
AuditTime
datetime2
SYSDATETIME()
ModifyingUser
sysname
ORIGINAL_LOGIN()
RemainingBalance
decimal(18,2)
RemainingBalance after update
15-32
Implementing a Microsoft® SQL Server® 2008 R2 Database
Exercise 1: Creating and Testing the Audit Trigger Scenario The Marketing.CampaignBalance table includes a column called RemainingBalance. Any time an update is made to the table, if either the existing balance or the new balance is greater than 10000, an entry needs to be written to the audit table Marketing.CampaignAudit. Note: Inserts or Deletes to the table do not need to be audited. Details of the current user can be taken from the function ORIGINAL_LOGIN(). The main tasks for this exercise are as follows: 1. 2. 3.
Review the supporting documentation and existing system. Design a trigger to meet the requirements as stated in the scenario for this exercise. Write code to test the behavior of the trigger.
Task 1: Review the supporting documentation and existing system •
Review the existing structure of the Marketing.CampaignAudit table and the values required in each column, based on the supporting documentation.
•
Review the existing structure of the Marketing.CampaignBalance table.
Task 2: Design a trigger to meet the requirements as stated in the scenario for this exercise •
Design and create a trigger that meets the needs identified in Task 1.
Task 3: Write code to test the behavior of the trigger •
Execute data modification statements designed to test that the trigger is working as expected.
Results: After this exercise, you should have created a new trigger. Tests should have shown that it is working as expected.
Responding to Data Manipulation via Triggers
15-33
Challenge Exercise 2: Improve the Audit Trigger (Only if time permits) Scenario Now that the trigger that was created in Exercise 1 has been deployed to production, the operations team is complaining that too many entries are being audited. Many accounts have more than 10000 as a balance and minor movements of money are causing audit entries. You need to modify the trigger so that only changes in the balance of more than 10000 are audited instead. The main tasks for this exercise are as follows: 1. 2. 3.
Modify the trigger based on the updated requirements. Delete all rows from the Marketing.CampaignAudit table. Test the modified trigger.
Task 1: Modify the trigger based on the updated requirements •
Review the design of the existing trigger and decide what modifications need to be made to it.
•
Use an ALTER TRIGGER statement to change the existing trigger so that it will meet the updated requirements.
Task 2: Delete all rows from the Marketing.CampaignAudit table •
Execute a DELETE statement to remove all existing rows from the Marketing.CampaignAudit table.
Task 3: Test the modified trigger •
Execute data modification statements designed to test that the trigger is working as expected.
Results: After this exercise, you should have altered the trigger. Tests should show it is now working as expected.
15-34
Implementing a Microsoft® SQL Server® 2008 R2 Database
Module Review and Takeaways
Review Questions 1.
2. 3.
List the module review questions here. Note that the numbers in the numbered list are not auto generated. You will need to enter the numbers manually. Refer to the template instructions for further help. How do constraints and triggers differ regarding timing of execution? Why would you use the UPDATE function rather than the COLUMNS_UPDATED function when designing a trigger?
Best Practices 1.
2.
In many business scenarios, it makes sense to mark records as deleted with a status column and use a trigger or stored procedure to update an audit trail table. The changes can then be audited, the data is not lost, and the IT staff can perform purges or archival of the deleted records. Avoid using triggers in situations where constraints could be used instead.
Implementing Managed Code in SQL Server 2008 R2
Module 16 Implementing Managed Code in SQL Server 2008 R2 Contents: Lesson 1: Introduction to SQL CLR Integration
16-3
Lesson 2: Importing and Configuring Assemblies
16-16
Lesson 3: Implementing SQL CLR Integration
16-23
Lab 16: Designing and Implementing Views
16-43
16-1
16-2
Implementing a Microsoft® SQL Server® 2008 R2 Database
Module Overview
As a database professional, you are asked to create databases and related objects to meet business needs. Most of the requirements can be met by using Transact-SQL. However, there are times when the requirements go beyond the abilities of Transact-SQL. These requirements may include functionality such as: •
Complex/compound data types like currency values that include culture information, complex numbers, dates that include calendar system, or storing entire arrays of values in a single column.
•
Accessing image files on the operating system and reading them or copying them into the database.
•
Adding logic that verifies data such as available quantities within a database transaction and completing or rolling back the transaction based on specific criteria.
These requirements are examples of requirements that can be met using SQL Server CLR Integration. Integrated code is used to create user-defined functions, stored procedures, aggregates, types, and triggers. These objects can be developed using any .NET language and can be highly specialized. In this module, you will learn about using CLR integrated code to create user- defined database objects that are managed by the .NET Framework.
Objectives After completing this module, you will be able to: • • •
Explain the importance of SQL Server CLR Integration. Import and configure assemblies. Implement objects that have been created within .NET assemblies.
Implementing Managed Code in SQL Server 2008 R2
16-3
Lesson 1
Introduction to SQL CLR Integration
Amongst database professionals, there is a constant desire to extend the built-in functionality of SQL Server. For example, you might wish to add a new aggregate to the existing list of aggregates supplied by SQL Server. There is no right or wrong method to extend the product. Particular methods are more or less suited to particular needs and situations. SQL Server CLR Integration is one method for extending SQL Server. It is important to understand SQL Server CLR integration and its appropriate use cases.
Objectives After completing this lesson, you will be able to: • • • • • •
Explain the ways that SQL Server can be extended. Describe the .NET Framework. Describe the .NET Common Language Runtime environment. Explain the need for managed code in SQL Server. Explain the situations where T-SQL use is inappropriate. Choose appropriate use cases for managed code in SQL Server.
16-4
Implementing a Microsoft® SQL Server® 2008 R2 Database
Options for Extending SQL Server
Key Points Many SQL Server components have mechanisms that allow their functionality to be extended. Previous mechanisms for extending the Database Engine such as the use of extended stored procedures are limited in both effectiveness and safety. Managed code is a safer alternative.
Component Extensibility Many applications can be created with the “out of the box” tools and functionality provided with SQL Server. The ability to reuse previously developed functionality though, helps to produce higher quality outcomes. It is then desirable to package that reusable functionality as an extension of the SQL Server product. Many SQL Server components are extensible. As an example, SQL Server Reporting Services allows for the creation of: • • • • • •
Rendering extensions Security extensions Data processing extensions Delivery extensions Custom code External assemblies
Database Engine Extensibility Traditionally, extending the Database Engine has been achieved by creating extended stored procedures. These are specially-crafted procedures that are written in C++ and are complex to code. More concerning though is that when they are operating, they are executing directly within the process space of the SQL Server engine. That is not a safe place to be executing code as minor errors could cause failure or instability of the Database Engine itself. The ability to create extended stored procedures is now deprecated.
Implementing Managed Code in SQL Server 2008 R2
Managed Code Managed code is code written to operate within the .NET Framework. There seems to be a concern amongst database administrators about running managed code within the Database Engine but it is important to realize that even the most unsafe managed code that you write is always safer than any extended stored procedure code. Question: Are there any aspects of the Database Engine that you would like to extend?
16-5
16-6
Implementing a Microsoft® SQL Server® 2008 R2 Database
Introduction to the .NET Framework
Key Points The .NET Framework is the foundation for developing Microsoft® Windows® applications and services including Microsoft SQL Server®. The .NET Framework offers the developer tools that make application and service development easier and provides a good basis for code to extend SQL Server.
Win32 and Win64 APIs The Windows operating system evolved over a period of many years. The programming interfaces to the operating system are commonly referred to as the Win32 and Win64 Application Programming Interfaces (APIs). These interfaces also evolved over the same period. In general, they are complex and inconsistent in the way they are designed, largely due to their evolution over time rather than being designed with a single set of guidelines at one time.
.NET Framework The .NET framework is a layer of software that sits above the Win32 and Win64 APIs and abstracts away the underlying complexity. This framework is written in a consistent fashion to a tightly-written set of design guidelines. Many people describe it as appearing to have been “written by one brain”. It is not specific to any one programming language and also contains many thousands of prebuilt and pretested objects. These objects are collectively referred to as the .NET Framework Class Libraries. These capabilities make the .NET Framework a good base for building code to extend SQL Server.
Implementing Managed Code in SQL Server 2008 R2
16-7
.NET Common Language Runtime
Key Points The .NET Common Language Runtime (CLR) is the layer in the .NET Framework that allows you to create programs and procedures in any .NET language and deploy it for use. The resulting resources are referred to as managed code. It is important to distinguish the CLR from the Common Language Specification or CLS.
.NET Common Language Runtime The CLR Integration feature within Microsoft® SQL Server® allows you to use .NET assemblies to customize your SQL databases. The .NET CLR offers: • • •
Access to existing managed code. Security features to ensure managed code will not compromise the server. The ability to create new resources using .NET languages like Microsoft Visual C#® and Microsoft Visual Basic .NET.
Memory Management A key problem that arose in development directly against the Win32 and Win64 APIs related to memory management. In older Component Object Model (COM) programming that was used with these APIs, releasing memory when it was no longer needed was based on reference counting. The idea was that the following sequence of events would occur: • • • •
Object A creates Object B When Object B is created, it notes that it has one reference to itself. Object C might then acquire a reference to Object B as well. Object B then notes that it has two references to itself. Object C releases its reference. Object B then notes that it has only a single reference to itself.
16-8
Implementing a Microsoft® SQL Server® 2008 R2 Database
•
Object A then releases its reference as well. Object B then notes that it now has no references to itself so it proceeds to destroy itself.
The problem with this scheme is that it is easy to create situations where memory is lost. For a simple example, consider circular references. If two objects have references to each other but no other object has any reference to either of them, they can both sit in memory forever as long as they have a reference to each other. This then causes a leak (or loss) of the memory consumed by those objects. Over time, creation of such situations could cause the loss of all available memory on the system. This sort of memory management scheme would not be suitable within the Database Engine. The .NET Framework includes a sophisticated memory management system known as Garbage Collection that is designed to avoid any chance of such memory leaks. Instead of objects needing to count references, the CLR periodically checks which objects are "reachable" and disposes of the other objects.
Run Time Management Another common problem with Win32 and Win64 code relates to what is known as type safety. When a function or procedure is called, all that is known to the caller is the address in memory of the function. The caller assembles a list of any required parameters, places them in an area called the stack, and jumps to the memory address of the function. Problems arise when the design of the function and/or its parameters change and the calling code is not updated. The function can then end up referring to memory locations that do not exist. The .NET CLR is designed to avoid such problems. As an example, as well as providing details of the address of a function, it provides details of what is called the signature of a function. This specifies the data types of each of the parameters and the order that they need to be in. The CLR will not allow a function to be called with the wrong number or types of parameters. This is referred to as "type safety".
Hosting the CLR The CLR is also designed to be hostable. This means that it can itself be operated within other programming environments. With SQL Server CLR integration, SQL Server becomes the host for the CLR. From the point of view of the CLR, it is as though the CLR thinks that SQL Server is the operating system. This allows SQL Server to exert great control over how the CLR operates, in terms of performance, security, and stability.
CLS Many people get confused between the CLR and the CLS. As mentioned earlier, the CLS is the Common Language Specification. It specifies the rules that languages must conform to, so that interoperability between languages is possible. For example, even though it is possible to create a method in C# called SayHello and another method called Sayhello, these methods could not be called from another language that was not case sensitive. The CLS states that you should not create these two methods, to avoid interoperability problems.
Implementing Managed Code in SQL Server 2008 R2
16-9
Why Use Managed Code in SQL Server?
Key Points Managed code allows SQL Server to access thousands of available .NET libraries and assemblies created by third parties as well as those you develop. A rich development environment (Visual Studio) is provided for building managed code. Many objects can be created in either T-SQL or managed code but managed code also allows for the creation of new types of objects that cannot be created in T-SQL.
Why Use Managed Code in SQL Server? In the last topic, the critical nature of type safety was discussed. For efficient development though, you also need to achieve a high degree of code reuse. The .NET Framework offers a large set of libraries each of which contains a large set of prewritten (and pretested) objects (typically referred to as classes) that can easily be used directly in SQL Server via SQL Server CLR Integration. For example, the Regular Expression (RegEx) library in the .NET Framework is very powerful and can be utilized within SQL Server by the use of SQL Server CLR Integration. The inclusion of managed code in SQL Server also allows for much easier access to external resources and in some cases provides higher performance. While advances in error handling in T-SQL have been made in recent years, the error handling provided by the T-SQL language still is well short of the type of error handling typically provided in higher-level languages. Writing managed code allows advantage to be taken of these more extensive error handling capabilities.
Alternative to T-SQL Objects Many objects that can be created in T-SQL can also be created in managed code. This includes the following set of objects: • • •
Scalar user-defined functions Table-valued user-defined functions Stored procedures
16-10
Implementing a Microsoft® SQL Server® 2008 R2 Database
• •
DML triggers DDL triggers
New Object Types In managed code, you can also construct types of objects that cannot be constructed in T-SQL. These include the following set of objects: • •
User-defined data types User-defined aggregates
Implementing Managed Code in SQL Server 2008 R2
16-11
T-SQL vs. Managed Code
Key Points There is no right or wrong answer for all situations when considering if an object should be created in TSQL or in managed code.
T-SQL T-SQL is the primary method for manipulating data within databases. It is designed for direct data access and offers high performance, particularly when working against very large sets of data. T-SQL is not, though, a fully-fledged high-level programming language. T-SQL has no object-oriented capabilities. For example, you cannot create a stored procedure that takes a parameter of data type animal and pass a parameter of data type cat to it. T-SQL is not designed for tasks such as intensive calculations or string handling and its objects are designed in a single flat namespace. SQL Server system objects almost all reside in a single sys schema. You cannot create a T-SQL schema within another T-SQL schema. Managed code provides the ability to create a hierarchy of namespaces. T-SQL does offer a useful set of built-in functions.
Managed Code Managed code provides full object-oriented capabilities. It is important to realize though that this only applies within the managed code itself. T-SQL code does not support the object-oriented capabilities. Managed code works well in situations requiring intensive calculations (such as encryption) or string handling.
General Rules Two good general rules apply when making a choice between T-SQL and Managed Code: •
The more data-oriented the need is, the more likely it is that T-SQL will be the better answer.
16-12
Implementing a Microsoft® SQL Server® 2008 R2 Database
•
The more calculation, string-oriented, or external-access-oriented the need is, the more likely it is that managed code will be the better answer.
Implementing Managed Code in SQL Server 2008 R2
16-13
Appropriate Database Object use in Managed Code
Key Points In the last topic, you saw some general rules for choosing between T-SQL and managed code. You need to consider how these rules would map to database objects in SQL Server. It is important to again mention though that there is no right or wrong answer in all situations.
Scalar User-defined Functions (UDFs) Scalar UDFs written in T-SQL are well-known for causing performance problems in SQL Server environments. Managed code is often a good option for implementing scalar UDFs as long as the function does not depend on heavy data access.
Table-valued UDFs The more data-related these functions are, the more they are likely to be best implemented in T-SQL. A common use case for managed code in table-valued UDFs is for functions that need to access external resources such as the filesystem, environment variables, registry, etc.
Stored Procedures Stored procedures have traditionally been written in T-SQL. Most stored procedures should continue to be written in T-SQL. There are very few good use cases for managed code in stored procedures. The exceptions to this are stored procedures that need to access external resources or perform complex calculations. There should be consideration, however, about whether code that performs these tasks should be implemented within SQL Server at all.
DML Triggers Almost all DML triggers are heavily-oriented towards data access and are written in T-SQL. There are very few valid use cases for implementing DML triggers in managed code.
16-14
Implementing a Microsoft® SQL Server® 2008 R2 Database
DDL Triggers DDL triggers are again often data-oriented. Some DDL triggers though need to do extensive XML processing, particularly based on the XML EVENTDATA structure passed to these triggers by SQL Server. The more that extensive XML processing is required, the more likely the DDL trigger would be best implemented in managed code. Managed code would also be a better option if the DDL trigger needed to access external resources but this is rarely a good idea within any form of trigger.
User-defined Aggregates T-SQL offers no concept of user-defined aggregates. These need to be implemented in managed code.
User-defined Data Types T-SQL offers the ability to create alias data types but these are not really new data types. They are more like subsets (or subclasses) of existing built-in data types. Managed code offers the ability to create entirely new data types and determine not only what data needs to be stored but also the behavior of the data type.
Implementing Managed Code in SQL Server 2008 R2
16-15
Demonstration 1A: Appropriate Use Cases for Managed Code and T-SQL
Key Points In this demonstration you will see examples of code that is not ideally implemented in T-SQL.
Demonstration Steps 1. 2.
3. 4. 5. 6. 7.
Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_16_PRJ\6232B_16_PRJ.ssmssln and click Open. Open and execute the 00 – Setup.sql script file from within Solution Explorer. Open the 11 – Demonstration 1A Example 1.txt file. Open the 12 – Demonstration 1A Example 2.txt file. Open the 13 – Demonstration 1A Example 3.txt file. Open the 14 – Demonstration 1A Example 4.txt file.
Question: Can you suggest ways that you could use T-SQL code that would be better as managed code? Question: Can you suggest ways that you could use managed code that would be better as T-SQL?
16-16
Implementing a Microsoft® SQL Server® 2008 R2 Database
Lesson 2
Importing and Configuring Assemblies
Assemblies are the unit of both deployment and security in the .NET Framework. Managed code in SQL Server resides within assemblies. Before you can start to work with managed code in SQL Server, you need to learn about assemblies and how they can be imported into SQL Server and secured.
Objectives After completing this lesson, you will be able to: • • •
Explain what an assembly is. Detail the permission sets that are available for securing assemblies. Import an assembly.
Implementing Managed Code in SQL Server 2008 R2
16-17
What is an Assembly?
Key Points Assemblies are the unit of both deployment and security in the .NET Framework. They contain the code that will be executed, are self-describing, and may contain resources.
Structure of an Assembly Prior to managed code, executable files (.exe files) and dynamic link libraries (.dll files) contained only executable code. Executable code is produced by compilers by converting instructions in higher-level languages into the binary codes required for execution by the computer’s processor. Managed code assemblies have a specific structure. As well as executable code, they contain a manifest. This manifest provides a list of contents of the assembly and of the programming interfaces provided by the assembly. This allows other code to interrogate an assembly to determine both what it contains and what it can do. As an example, SQL Server is able to gain a great deal of understanding of an assembly by reading this manifest when cataloging an assembly. Assemblies can contain other resources such as icons. These are also listed in the manifest. Assemblies can be structured as either .exe files or as .dll files. The only difference between the two is that .exe files also include an area called the portable execution header (PE header) that is used by the operating system to find out where the executing code of a .exe file starts. SQL Server will only import .dll files and will refuse to import .exe files.
Deployment and Security Assemblies are the unit of managed code that is deployed. As they are created external to SQL Server, it is possible to share assemblies between SQL Server and business applications. Assemblies also form a boundary at which security is applied. In the next topic, you will see how this security is configured.
16-18
Implementing a Microsoft® SQL Server® 2008 R2 Database
Assembly Permission Sets
Key Points Using the CLR offers several levels of trust that can be set within policies for the machine and host on which the assembly runs. There are three SQL Server permission sets that allow the administrator to control the server's exposure to security and integrity risks: SAFE, EXTERNAL_ACCESS, and UNSAFE. Regardless of what the code in an assembly attempts to do, the permitted actions are determined by the permission set on the assembly that contains the code.
SAFE SAFE should be regarded by administrators as really meaning what the name says. It is a particularly limited permission set but does allow access to the SQL Server database that it is cataloged in via a special type of connection known as a context connection. Administrators should be comfortable with the cataloging of SAFE assemblies. SAFE is the default permission set.
EXTERNAL_ACCESS EXTERNAL_ACCESS is the permission set required before code in an assembly can access local and network resources, environment variables, and the registry of the server. This permission set is still quite safe and is typically used when any form of external access is required. Administrators should be fairly comfortable with the cataloging of EXTERNAL_ACCESS assemblies, once a justification for the external access requirements is made.
UNSAFE UNSAFE is the unrestricted permission set. It should be rarely used for general development. UNSAFE is required for code that calls external unmanaged code or code that holds state across function calls, etc. Administrators should only allow the cataloging of UNSAFE assemblies in situations that have been very carefully considered and justified.
Implementing Managed Code in SQL Server 2008 R2
16-19
Setup for EXTERNAL_ACCESS and UNSAFE The EXTERNAL_ACCESS and UNSAFE permission sets require further configuration before they can be used. A level of trust needs to be established. There are two ways to do this: •
•
The database can be flagged as TRUSTWORTHY (via the ALTER DATABASE SET TRUSTWORTHY ON statement). In general, this is not recommended without an understanding of what changes this makes to the database security environment. An asymmetric key is created from the assembly file cataloged in the master database, then a login mapping to that key is created, and finally the login is granted the EXTERNAL ACCESS ASSEMBLY permission on the assembly. While this is the recommended method of granting permission to use EXTERNAL_ACCESS or UNSAFE permission sets, setting this up is an advanced topic beyond the scope of this course.
Question: Which permission set should be rarely allowed?
16-20
Implementing a Microsoft® SQL Server® 2008 R2 Database
Importing an Assembly
Key Points Before the code in an assembly can be used within SQL Server, the assembly must be cataloged within a database.
CREATE ASSEMBLY The CREATE ASSEMBLY statement is used to catalog an assembly within the current database. SQL Server assigns the assembly a permission set based on the WITH PERMISSON_SET clause in the CREATE ASSEMBLY statement. If no permission set is explicitly requested, the assembly will be cataloged as a SAFE assembly and the code within the assembly will only be able to execute tasks permitted by the SAFE permission set. Before any code in a user-created assembly can be executed, the ‘clr enabled’ option must be set to 1 (enabled) at the database level. An assembly and the objects within it can still be cataloged even if this option is disabled. It only prevents code execution. Once the assembly is cataloged in the database, the contents of the assembly are contained within the database and the file that it was cataloged from is no longer needed by SQL Server. After it is cataloged, an assembly will be loaded from within the database when required, not from the filesystem.
Assembly Path There are three locations that an assembly can be cataloged from: •
A .dll file on a local drive. The drive may not be a mapped drive.
•
A .dll file from a UNC path. (A UNC path is of the form \\SERVER\Share\PathToFile\File.dll).
•
A binary string containing the contents of the .dll file.
It might at first seem odd to consider cataloging an assembly from a binary string but this is how Visual Studio catalogs assemblies if you deploy an assembly directly from Visual Studio. Visual Studio cannot make the assumption that you have access to the filesystem of the server. You might be working with an
Implementing Managed Code in SQL Server 2008 R2
16-21
instance of SQL Server or a database that is hosted by a hosting company and have no access to the filesystem of the server at all. Cataloging an assembly from a binary string allows you to stream an assembly to the server within the CREATE ASSEMBLY statement. It is worth noting that if you later generate a script for the database, any contained assemblies will also be scripted as binary strings.
16-22
Implementing a Microsoft® SQL Server® 2008 R2 Database
Demonstration 2A: Importing and Configuring an Assembly
Key Points In this demonstration you will see: •
How to catalog an assembly
•
How to view system catalog information about loaded assemblies
•
How to script an assembly
Demonstration Steps 1.
2. 3.
If Demonstration 1A was not performed: •
Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system.
•
In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_16_PRJ\6232B_16_PRJ.ssmssln and click Open.
•
Open and execute the 00 – Setup.sql script file from within Solution Explorer.
Open the 21 – Demonstration 2A.sql script file. Follow the instructions contained within the comments of the script file.
Question: Of the three trust levels, the UNSAFE level is the least protected. What situations can you think of that would warrant the risk of using this trust level? Question: Is it wise to set a company policy to never use this level? (Why or why not?)
Implementing Managed Code in SQL Server 2008 R2
16-23
Lesson 3
Implementing SQL CLR Integration
Once an assembly has been cataloged, there is a need to also catalog any objects within it. This will make the objects visible within SQL Server so that they can be called from within T-SQL code.
Objectives After completing this lesson, you will be able to: • • • • • • • •
Explain how appropriate attribute usage is important when creating assemblies. Implement scalar user-defined functions that have been written in managed code. Implement table-valued user-defined functions that have been written in managed code. Implement stored procedures that have been written in managed code. Implement stored procedures that have been written in managed code and that require access to external resources. Implement triggers that have been written in managed code. Implement user-defined aggregates that have been written in managed code. Implement user-defined data types that have been written in managed code.
16-24
Implementing a Microsoft® SQL Server® 2008 R2 Database
Attribute Usage
Key Points Attributes are metadata that is included within code and is used to describe that code. When implementing managed code within SQL Server, attributes are used for deployment, performance, and correctness reasons.
Attributes If you have not written any managed code, the concept of attributes may be unfamiliar to you. Attributes are metadata (or data about data) used to describe functions, methods, and classes. Attributes do not form a part of the logic of the objects but describe aspects of them. As an example, consider an attribute that records the name of the author of a method. This does not change how the method operates but could be useful information for anyone using the method. The .NET Framework also has a special set of logic called Reflection that allows one set of managed code to interrogate details of another set of managed code. Attributes are returned as part of this process. This is how SQL Server accesses the attributes that you associate with your code.
Deployment The first reason that attributes are helpful is for deployment. Adding a SqlFunction attribute to a managed code method tells Visual Studio (or other code used for deployment) that the method should be cataloged as a function within SQL Server. Adding an attribute to a method is also referred to as “adorning” the method with the attribute. If you do not add a SqlFunction attribute to a method, you can still manually catalog the method as a function in SQL Server. The limitation is that automated deployment systems will not know to do so. You might wonder why SQL Server doesn’t just automatically catalog all methods as functions when cataloging an assembly. Methods can be used for more than just functions and some methods are only used within the assembly and are not intended to be used by code that utilizes the functionality provided by the assembly.
Implementing Managed Code in SQL Server 2008 R2
16-25
Performance The second reason why attributes are helpful relates to performance. Consider the DataAccess property of the SqlFunction attribute as shown in the slide. This property tells SQL Server that no data context needs to be provided to this method. It does not access data from the database. This makes the function quicker to execute and reduces its memory requirements. As another example of how an attribute can help with performance, consider an attribute that tells SQL Server that a method call always returns NULL if the parameter passed to the method is NULL. In that case, SQL Server knows it doesn’t need to call the method at all if the value is NULL.
Correctness The final reason for using attributes is for correctness. If a new Circle data type is created, it might provide a method called Shrink. SQL Server needs to know that if this method is called, the internal state of the user-defined data type will be changed when the method returns. This helps SQL Server know how the method can be used. For example, SQL Server would then know that the method could be called in the SET clause of an UPDATE statement. It would also prevent SQL Server from allowing the method to be called in a SELECT list or WHERE clause in a SELECT statement.
16-26
Implementing a Microsoft® SQL Server® 2008 R2 Database
Scalar User-defined Functions
Key Points Scalar user-defined functions are a common use case for managed code and often offer a higherperforming alternative to their equivalent T-SQL functions.
CREATE FUNCTION The CREATE FUNCTION statement is used to catalog a scalar user-defined function that has been written in managed code. In the statement, you need to provide the details of the returned data type and a path to the method within the assembly. Note that the name that a function is called within SQL Server does not have to match the name that the method is called within the assembly. However, it is considered good practice to have these matched with each other to avoid confusion. The auto-deployment attribute related to this is the SqlFunction attribute.
EXTERNAL NAME When cataloging the function, the EXTERNAL NAME clause is used to point to where the method exists within the assembly. This normally consists of a three part name: •
The first part of the name refers to the alias for the assembly that was used in the CREATE ASSEMBLY statement
•
The second part of the name must contain the namespace that contains the method. In the example shown, the name UserDefinedFunctions is a class. However, the UserDefinedFunctions class itself could be contained within another namespace. If that other namespace was called CompanyFunctions, the second part of the name would need to be specified as [CompanyFunctions.UserDefinedFunctions].
•
The third part of the name refers to the method within the class.
Implementing Managed Code in SQL Server 2008 R2
16-27
Note that even if the code has been built in a case-insensitive language like Visual Basic and the database collation is set to case insensitive, the path provided in the EXTERNAL NAME clause is case sensitive.
16-28
Implementing a Microsoft® SQL Server® 2008 R2 Database
Table-valued User-defined Functions
Key Points Table-valued functions (TVFs) are cataloged in a similar way to scalar functions but need to include the definition of the returned table.
CREATE FUNCTION The CREATE FUNCTION statement is also used to catalog TVFs written in managed code. The return data type, however, must be TABLE. After the data type, you need to provide the definition of the schema of the table. In the example shown in the slide, the table consists of two columns, both of integer data type.
Deployment Attribute The definition of TVFs provides an example of why the properties of an attribute are useful. First, the SqlFunction attribute indicates that the method should be cataloged as a function. The properties of the attribute indicate: •
That the function does not require access to database data.
•
The name of the FillRow method (Do not be concerned with the FillRowMethodName method at this point. While it must be present, it relates to the internal design of the function).
•
The schema for the returned table. An automated deployment system (such as the one provided in Visual Studio) needs to know the format of the returned table to be able to automatically catalog this function in SQL Server.
Parameter Naming The names chosen for the parameter in T-SQL do not need to match the names used in the managed code. For example, the function in the slide example could have been cataloged in the following way: CREATE FUNCTION dbo.RangeOfIntegers (@StartValue int, @EndValue int) RETURNS TABLE (PositionInList int, IntegerValue int)
Implementing Managed Code in SQL Server 2008 R2
16-29
AS EXTERNAL NAME SQLCLR6232B.UserDefinedFunctions.RangeOfIntegers;
However, you should create T-SQL parameters with the same name as the parameters in the managed code unless there is a compelling reason to make them different. An example of this would be a parameter name that was used in managed code that was not a valid parameter name in T-SQL. Even in this situation, a better option would be to change the parameter names in the managed code wherever possible. Question: How could a TVF be used with environment variables?
16-30
Implementing a Microsoft® SQL Server® 2008 R2 Database
Demonstration 3A: User-defined Functions
Key Points In this demonstration you will see how to: •
Catalog a scalar function built in managed code.
•
Test the scalar function.
•
Catalog a table-valued function built in managed code.
•
Test the table-valued function.
•
Use the table-valued function to find gaps in data.
Demonstration Steps 1.
2. 3.
If Demonstration 1A was not performed: •
Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system.
•
In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_16_PRJ\6232B_16_PRJ.ssmssln and click Open.
•
Open and execute the 00 – Setup.sql script file from within Solution Explorer.
•
Open the 21 – Demonstration 2A.sql script file and execute steps 1 to 3.
Open the 31 – Demonstration 3A.sql script file. Follow the instructions contained within the comments of the script file.
Implementing Managed Code in SQL Server 2008 R2
16-31
Stored Procedures – T-SQL Replacement
Key Points Stored procedures can also be written in managed code. Most stored procedures written at present tend to be very data-access oriented. As such, replacing a T-SQL stored procedure with a managed code stored procedure is unlikely to be useful.
CREATE PROCEDURE The CREATE PROCEDURE statement is used to catalog a stored procedure written in managed code. The relevant deployment attribute is the SqlProcedure attribute. This attribute tells Visual Studio (or other deployment utility) that the method should be cataloged as a stored procedure. Parameters that need to be passed to the stored procedure should be listed in the same way they are listed for a T-SQL stored procedure definition. The EXTERNAL NAME clause works identically the same way as is used for cataloging scalar user-defined functions.
SqlPipe Stored procedures written in managed code support both input and output parameters as per their T-SQL equivalent procedures. Like stored procedures written in T-SQL, stored procedures written in managed code need a way to return rows of data. The SqlPipe object is used within the stored procedure code to achieve this data. Rows of data can be returned by this object. If you call the Send method of the SqlPipe object and pass a string value to it, the outcome is the same as if you had issued a PRINT statement in a T-SQL based stored procedure. You will see the values returned in the Messages tab within SQL Server Management Studio. You can see the SqlPipe object used in the following code:
16-32
Implementing a Microsoft® SQL Server® 2008 R2 Database
public partial class StoredProcedures { [SqlProcedure] public static void ProductsByColor(SqlString Color) { SqlConnection conn = new SqlConnection("context connection=true"); SqlCommand command = conn.CreateCommand(); SqlPipe outputPipe = SqlContext.Pipe; outputPipe.Send("Hello. It's now " + DateTime.Now.ToLongTimeString() + " at the server.");
};
}
if (Color.IsNull) { command.CommandText = "SELECT * FROM Production.Product " + "WHERE (Color IS NULL) ORDER BY ProductID"; } else { command.CommandText = "SELECT * FROM Production.Product " + "WHERE (Color = @Color) ORDER BY ProductID"; command.Parameters.Add( new SqlParameter("@Color", Color.Value)); } conn.Open(); outputPipe.Send(command.ExecuteReader()); conn.Close();
Implementing Managed Code in SQL Server 2008 R2
16-33
Stored Procedures – External Access
Key Points In the previous topic, you learned how simple it is to replace T-SQL stored procedures that perform data access with stored procedures written in managed code. You also learned how unlikely it is for stored procedure written in managed code to be useful. This is because the appropriate use cases for stored procedures written in managed code are more likely to involve access to external resources.
EXTERNAL_ACCESS Permission Set A stored procedure that accepts data to be written to an operating system file would be a more useful example of implementing stored procedures in managed code. The stored procedure would create the file and write the data to it. Access to the filesystem requires EXTERNAL_ACCESS permission when the assembly that contains the method is cataloged.
Avoid the Need for Many Extended Stored Procedures The use of managed code in stored procedures also removes the need for the use of many extended stored procedures. xp_cmdshell is an example of an extended stored procedure that is disabled by default in SQL Server, yet many applications require it to be enabled. This lets the applications perform operations at the filesystem level. Enabling xp_cmdshell is undesirable from a security perspective and managed code provides alternate ways to implement this required functionality in a much safer form. Question: What would be a good use case for stored procedures in managed code?
16-34
Implementing a Microsoft® SQL Server® 2008 R2 Database
Triggers
Key Points Both DML and DDL triggers can be implemented from within managed code.
CREATE TRIGGER The CREATE TRIGGER statement is used to catalog methods in managed code assemblies as triggers. The relevant deployment attribute is SqlTrigger. The SqlTrigger attribute properties that are most useful are: •
Name – this indicates the name that the trigger will be called when deployed
•
Target – the name of the object that the trigger will be attached to
•
Event – the event (or events) that the trigger will fire on
Access to Modifications As with triggers written in T-SQL, triggers written in managed code are able to access the details of the changes being made or the commands that have been executed. Within DML triggers, access is provided to the inserted and deleted virtual tables in exactly the same way as in DML triggers written in T-SQL. Similarly, within DDL triggers access is provided to the XML EVENTDATA structure.
SqlTriggerContext A DML trigger can be associated with multiple events on an object. Within the code of a DML trigger, you may need to know which event has caused the trigger to fire. The SqlTriggerContext class can be used to build logic based on the event that caused the trigger to fire.
Implementing Managed Code in SQL Server 2008 R2
16-35
Demonstration 3B: Stored Procedures and Triggers
Key Points In this demonstration you will see how to: •
Catalog a stored procedure written in managed code
•
Test the stored procedure
•
Catalog a trigger written in managed code
•
Test the trigger
Demonstration Steps 1.
2. 3.
If Demonstration 1A was not performed: •
Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system.
•
In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_16_PRJ\6232B_16_PRJ.ssmssln and click Open.
•
Open and execute the 00 – Setup.sql script file from within Solution Explorer.
•
Open the 21 – Demonstration 2A.sql script file and execute steps 1 to 3.
Open the 32 – Demonstration 3B.sql script file. Follow the instructions contained within the comments of the script file.
16-36
Implementing a Microsoft® SQL Server® 2008 R2 Database
User-defined Aggregates
Key Points User-defined aggregates (UDAGGs) are an entirely new type of object for SQL Server and cannot be created in T-SQL. The ability to create aggregates allows you to provide additional aggregates that are not provided by the built-in set of aggregates. For example, you might decide that you need a MEDIAN aggregate but SQL Server does not supply one by default. Another good use case for creating aggregates occurs when migrating code from another database engine that offers different aggregates or aggregates other than those provided by SQL Server. Aggregates could also be created to operate on data types that are not supported by built-in aggregates, including user-defined data types.
CREATE AGGREGATE The CREATE AGGREGATE statement is used to catalog UDAGGs written in managed code. The relevant deployment attribute is SqlUserDefinedAggregate. Note that the path to a struct or class will be a two part name as shown in the EXTERNAL NAME clause on the slide.
Serializable SQL Server needs to be able to store interim results while calculating the value of an aggregate. In managed code, the ability to save an object as a stream of data is called “serializing” the object. UDAGGs need to be Serializable. In managed code, they can be implemented as either classes or structs (data structures). Most UDAGGs would be implemented as structs rather than as classes, as structs are easier to implement. The property Format.Native shown in the slide example is indicating that the struct will be serialized using the standard serialization mechanisms built-in to the .NET Framework. The built-in serialization can only be used with simple data types. For more complex data types, user-defined serialization needs to be added.
Attribute Properties A few more useful attribute properties are shown in the example.
Implementing Managed Code in SQL Server 2008 R2
16-37
•
IsInvariantToDuplicates – this tells SQL Server that the result of the aggregate is the same even if it doesn’t see the values from every row. It only needs to see unique values. To visualize this, consider which rows the built-in MAX or MIN aggregates need to process and how this compares to which rows the built-in COUNT aggregate needs to see.
•
IsInvariantToNulls – this tells SQL Server that the result of the aggregate is unaffected by seeing rows that do not have a value in the relevant column.
•
IsNullIfEmpty – this tells SQL Server that if no rows at all need to be processed that the aggregate does not need to be called at all as the result will be NULL anyway.
•
Name – this tells Visual Studio (or the deployment utility) what name the aggregate should have when cataloged.
Note that this is not a complete list of all the possible properties, just the most useful ones. Question: Can you think of another common mathematical aggregate that would be useful in SQL Server?
16-38
Implementing a Microsoft® SQL Server® 2008 R2 Database
User-defined Data Types
Key Points The ability to create user-defined data types (UDDTs) in managed code allows you to extend the data type system available from within SQL Server. There is no T-SQL equivalent method of doing this. Userdefined data types allow for the determination not only what data is stored, but also how the data type behaves.
CREATE TYPE The CREATE TYPE statement is used to catalog UDDTs. The data type will be defined as a class in a managed code assembly. Similar to user-defined aggregates, data types need to be Serializable as SQL Server needs to be able to store them. The deployment attribute is SqlUserDefinedType.
System CLR Data Types The geometry, geography, and hierarchyid system data types are in fact system CLR data types. Their operation is unrelated to the ‘clr enabled’ configuration setting at the SQL Server instance level. The 'clr enabled' option only applies to user-created managed code.
Accessing Properties and Methods The properties of an instance of a managed code data type are accessed via: InstanceOfTheType.Property eg: @Shape.STArea
The methods of an instance of a managed code data type are accessed via: InstanceOfTyeType.Method() eg: @Shape.STDistance(@OtherShape)
Managed code data types might also include functionality that is useful without creating an object of the data type first. This allows you to expose functions from within a data type somewhat like a code library. The methods of the managed code data type itself are accessed via:
Implementing Managed Code in SQL Server 2008 R2
TypeName::Method() eg: GEOMETRY::STGeomFromText(‘POINT (12 15)’)
16-39
16-40
Implementing a Microsoft® SQL Server® 2008 R2 Database
Considerations for User-defined Data Types
Key Points UDDTs are not directly comparable but their properties are.
Comparing Managed Code Data Types With the built-in set of system data types, a variety of operations are defined for each data type. For example, you can compare two integers or strings. User-defined data types cannot be compared using operations such as > (greater than) or < (less than). This means they cannot be sorted, used in a SELECT DISTINCT clause, or directly indexed. The one exception to this is that binary comparisons are permitted when the IsByteOrdered property of the SqlUserDefinedDataType attribute is set to true. Even in this situation, only a simple binary comparison is performed. The individual properties of a data type are comparable. For example, two geometry data types cannot be compared via code as shown below: IF (@Shape1 < @Shape2) BEGIN
However, the properties of the two data types can be compared as shown below: IF (@Shape1.X < @Shape2.X) BEGIN
Indexing User-defined Data Type Properties While you cannot create indexes on user-defined data types, some system managed code data types have special indexes. For example, the geometry and geography data types can be indexed by a special type of index known as a spatial index.
Implementing Managed Code in SQL Server 2008 R2
16-41
For UDDTs, there is no method for creating new types of index to support them. What you can do is create a persisted calculated column in the same table and use it to “promote” the properties of the UDDT into standard relational columns. These columns can then be indexed.
Operator Overloading In object-oriented programming, it is possible to define or change the operators that operate on the object. User-defined data types do not offer this capability. For example, a customized meaning for a > (greater than) operator cannot be defined.
16-42
Implementing a Microsoft® SQL Server® 2008 R2 Database
Demonstration 3C: Aggregates and User- defined Data Types
Key Points In this demonstration, you will see how to: •
Catalog a user-defined aggregate
•
Test a user-defined aggregate
•
Catalog a user-defined data type
•
Test a user-defined data type
•
Create a table using a user-defined data type
Demonstration Steps 1.
2. 3.
If Demonstration 1A was not performed: •
Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system.
•
In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_16_PRJ\6232B_16_PRJ.ssmssln and click Open.
•
Open and execute the 00 – Setup.sql script file from within Solution Explorer.
•
Open the 21 – Demonstration 2A.sql script file and execute steps 1 to 3.
Open the 33 – Demonstration 3C.sql script file. Follow the instructions contained within the comments of the script file.
Implementing Managed Code in SQL Server 2008 R2
16-43
Lab 16: Implementing Managed Code in SQL Server
Lab Setup For this lab, you will use the available virtual machine environment. Before you begin the lab, you must complete the following steps: 1. 2. 3.
4.
5. 6. 7.
On the host computer, click Start, point to Administrative Tools, and then click Hyper-V Manager. Maximize the Hyper-V Manager window. In the Virtual Machines list, if the virtual machine 623XB-MIA-DC is not started: •
Right-click 623XB-MIA-DC and click Start.
•
Right-click 623XB-MIA-DC and click Connect.
•
In the Virtual Machine Connection window, wait until the Press CTRL+ALT+DELETE to log on message appears, and then close the Virtual Machine Connection window.
In the Virtual Machines list, if the virtual machine 623XB-MIA-SQL is not started: •
Right-click 623XB-MIA-SQL and click Start.
•
Right-click 623XB-MIA-SQL and click Connect.
•
In the Virtual Machine Connection window, wait until the Press CTRL+ALT+DELETE to log on message appears.
In Virtual Machine Connection window, click on the Revert toolbar icon. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action to complete. In the Virtual Machine Connection window, if the user is not already logged on: •
On the Action menu, click the Ctrl-Alt-Delete menu item.
•
Click Switch User, and then click Other User.
16-44
Implementing a Microsoft® SQL Server® 2008 R2 Database
•
Log on using the following credentials: i. ii.
8. 9. 10. 11. 12. 13. 14. 15.
User name: AdventureWorks\Administrator Password: Pa$$w0rd
From the View menu, in the Virtual Machine Connection window, click Full Screen Mode. If the Server Manager window appears, check the Do not show me this console at logon check box and close the Server Manager window. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, and click SQL Server Management Studio. In Connect to Server window, type Proseware in the Server name text box. In the Authentication drop-down list box, select Windows Authentication and click Connect. In the File menu, click Open, and click Project/Solution. In the Open Project window, open the project D:\6232B_Labs\6232B_16_PRJ\6232B_16_PRJ.ssmssln. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.
Lab Scenario You are concerned that one of your company developers has decided to implement almost all of her logic in SQL CLR assemblies. You will determine if this is appropriate. Also in this lab, you will implement and test a supplied .NET assembly. You will also investigate all installed assemblies on the system.
Supporting Documentation The following list details the proposed functionality being considered for managed code. Proposed SQLCLR Functionality Table-valued function that returns a list of files in a particular folder. Function that formats phone numbers as strings. Trigger that records balance movements with a value of more than 1000. Stored procedure that writes an XML file for a given XML parameter. Function that counts rows in a table. A new Customer data type.
Implementing Managed Code in SQL Server 2008 R2
16-45
Exercise 1: Assess Proposed CLR Code Scenario You need to assess a list of proposed functions and determine which functions should or should not be implemented via SQL CLR logic. The main tasks for this exercise are as follows: 1. 2.
Review the supporting documentation For each object listed, determine if implementing it in managed code is appropriate or not.
Task 1: Review the supporting documentation 1.
Review the proposed list of managed code objects
Task 2: For each object listed, determine if implementing it in managed code is appropriate or not 1.
Work through the list of proposed objects and for each object, decide if it should or should not be implemented in managed code and why.
Results: After this exercise, you should have created a list of which objects should and should not be implemented in managed code and the reasons for your decision.
16-46
Implementing a Microsoft® SQL Server® 2008 R2 Database
Exercise 2: Implement a CLR Assembly Scenario You have been provided with an existing .NET assembly. You will implement it within SQL Server. The main tasks for this exercise are as follows: 1. 2. 3.
Ensure the database is configured appropriately to support an EXTERNAL_ACCESS assembly. Catalog the assembly and the functions contained within it. Test the functions contained within the assembly.
Task 1: Ensure the database is configured appropriately to support an EXTERNAL_ACCESS assembly 1.
Ensure that SQL CLR integration is enabled for the SQL Server instance.
2.
Flag the MarketDev database as trustworthy.
Task 2: Catalog the assembly and the functions contained within it 1.
Use CREATE ASSEMBLY to catalog the supplied sample assembly as alias SQLCLRDemo. The path to the assembly is D:\6232B_Labs\6232B_16_PRJ\6232B_16_PRJ\SQLCLRDemo.DLL.
2.
Query the sys.assemblies and sys.assembly_files system views to confirm the details of how the assembly has been cataloged.
3.
Use the CREATE FUNCTION statement to catalog the function dbo.IsValidEmailAddress. It takes a parameter named @email of type nvarchar(4000) and returns a bit. It is found in the assembly at path: SQLCLRDemo.[SQLCLRDemo.CLRDemoClass].IsValidEmailAddress.
4.
Use the CREATE FUNCTION statement to catalog the function dbo.FormatAustralianPhoneNumber. It takes a single parameter @PhoneNumber of type nvarchar(4000). It returns nvarchar(4000). It is found in the assembly at path: SQLCLRDemo.[SQLCLRDemo.CLRDemoClass].FormatAustralianPhoneNumber.
5.
Use the CREATE FUNCTION statement to catalog the function dbo.FolderList. It takes two parameter @RequiredPath of type nvarchar(4000) and @FileMask of type nvarchar(4000). It returns a table of filenames, with one column called FileName of type nvarchar(4000). It is found in the assembly at path: SQLCLRDemo.[SQLCLRDemo.CLRDemoClass].FolderList.
Task 3: Test the functions contained within the assembly 1.
Execute the following T-SQL statements to test the functions that have been cataloged.
SELECT dbo.IsValidEmailAddress('
[email protected]'); GO SELECT dbo.IsValidEmailAddress('test.somewhere.com'); GO SELECT dbo.FormatAustralianPhoneNumber('0419201410'); SELECT dbo.FormatAustralianPhoneNumber('9 87 2 41 23'); SELECT dbo.FormatAustralianPhoneNumber('039 87 2 41 23'); GO SELECT * FROM dbo.FolderList( 'D:\6232B_Labs\6232B_16_PRJ\6232B_16_PRJ','*.txt'); GO
Results: After this exercise, you should have three functions working as expected.
Implementing Managed Code in SQL Server 2008 R2
16-47
Challenge Exercise 3: Implement a CLR User-defined Aggregate and CLR User-defined Data Type (Only if time permits) Scenario The sample assembly also includes a user-defined aggregate and a user-defined data type. You will now catalog and test these objects. The main tasks for this exercise are as follows: 1. 2.
Catalog and test the user-defined aggregate Catalog and test the user-defined data type
Task 1: Catalog and test the user-defined aggregate 1.
Use the CREATE AGGREGATE statement to catalog the user-defined aggregate dbo.AggString.
2.
dbo.AggString takes a single nvarchar(4000) parameter and returns type nvarchar(4000). It is found in the assembly at path: SQLCLRDemo.[SQLCLRDemo.AggString].
3.
Execute the following T-SQL statements to test the operation of the aggregate.
SELECT dbo.AggString(DISTINCT ProductNumber) FROM Marketing.Product WHERE Color = 'Black'; GO
Task 2: Catalog and test the user-defined data type 1.
Use the CREATE TYPE statement to catalog the user-defined data type dbo.zVarChar. It is found in the assembly at path: SQLCLRDemo.[SQLCLRDemo.zVarChar].
2.
Execute T-SQL statements similar to the following to test the operation of the data type. (The exact statements required would depend upon your table design).
CREATE TABLE dbo.TestTable ( RecID int IDENTITY(1,1), TextValue zVarChar ); INSERT INTO dbo.TestTable VALUES('Some GO
compressible
data');
SELECT TextValue.ToString(), TextValue.CompressedLength(), TextValue.CompressionPercentage() FROM dbo.TestTable; GO SELECT AVG(TextValue.CompressionPercentage()) FROM dbo.TestTable; GO DROP TABLE dbo.TestTable; GO
3.
Execute the following T-SQL statements to see how to call a method on the class itself, rather than on an instance of the class. (First, show how to call the method on an instance. Then, show how to call directly on the class so that you can see the difference).
DECLARE @TestString zVarChar; SET @TestString = 'Some compressible PRINT @TestString.CompressedValue();
value';
16-48
Implementing a Microsoft® SQL Server® 2008 R2 Database
GO PRINT zVarChar::Compress( 'Some GO
compressible
value');
Results: After this exercise, you should have cataloged and tested both the user-defined aggregate and the user-defined data type.
Implementing Managed Code in SQL Server 2008 R2
16-49
Module Review and Takeaways
Review Questions 1.
2. 3.
List the module review questions here. Note that the numbers in the numbered list are not auto generated. You will need to enter the numbers manually. Refer to the template instructions for further help. Which types of database objects can be implemented using managed code? What purpose do attributes have in CLR managed code?
Best Practices 1.
2. 3. 4.
The biggest mistake made when deciding between T-SQL and Managed Code is to assume that either one is the correct answer for every situation. Each has benefits and limitations and should be used for the appropriate tasks. Developers should avoid implementing using SQL CLR to implement code that would be better placed on another application tier (such as on a client system). DBAs should avoid refusing to allow SQL CLR code without consideration. As you have seen in this module, there is code that should be implemented in Managed Code rather than in T-SQL. DBAs should set boundaries for developers: • No row-based code that should be set-based T-SQL operations • Limited use of EXTERNAL_ACCESS permissions and only after justification. • Rare use of UNSAFE permissions and only after very serious justifications and testing.
16-50
Implementing a Microsoft® SQL Server® 2008 R2 Database
Storing XML Data in SQL Server 2008 R2
Module 17 Storing XML Data in SQL Server 2008 R2 Contents: Lesson 1: Introduction to XML and XML Schemas
17-3
Lesson 2: Storing XML Data and Schemas in SQL Server
17-15
Lesson 3: Implementing the XML Data Type
17-26
Lab 17: Storing XML Data in SQL Server
17-31
17-1
17-2
Implementing a Microsoft® SQL Server® 2008 R2 Database
Module Overview
Extensible Markup Language (XML) provides rules for encoding documents in a machine-readable form. It has become a very widely adopted standard for representing data structures rather than sending unstructured documents. SQL Server servers often need to use XML to interchange data with other systems and many SQL Server tools provide an XML based interface. SQL Server has extensive handling of XML both for storage and for querying. This module introduces XML and shows how XML data can be stored within SQL Server. The next module will show how XML data can be queried, including by queries written in a language called XQuery.
Objectives After completing this module, you will be able to: • • •
Describe XML and XML schemas Store XML data and associated XML schemas in SQL Server Implement the XML data type within SQL Server
Storing XML Data in SQL Server 2008 R2
Lesson 1
Introduction to XML and XML Schemas
Before covering how to work with XML in SQL Server, it is important to gain an understanding of XML itself and how it is used external to SQL Server. Some core XML-related terminology needs to be understood along with concepts of how the structure of XML can be validated and enforced using schemas. One common problem with the use of XML in SQL Server is a tendency to over-use it. It is important to gain an understanding of the appropriate uses for XML when working with SQL Server.
Objectives After completing this lesson, you will be able to: • • • • •
•
Describe why XML matters in relation to SQL Server Explain core XML concepts Explain the difference between documents and fragments Describe the role of XML namespaces Describe the role of XML schemas Determine appropriate use cases for XML data storage in SQL Server
17-3
17-4
Implementing a Microsoft® SQL Server® 2008 R2 Database
Discussion: XML Usage in SQL Server
Discussion The use of XML within SQL Server is new to many database administrators and database developers. XML has often been seen more as an application developer topic. Question: Why do you imagine that two modules of this course have been dedicated to XML within SQL Server? XML is very useful for data interchange and for storing data with an arbitrary or complex structure. It is common for data arriving into SQL Server to already be in an XML format. It is also common to wish to provide XML-based output from SQL Server. Many aspects and components of SQL Server are now XML-based, including: • • • • • •
SQL Server can store XML data and XML schemas and can validate XML data against an XML schema. DDL triggers return details of the event that caused the trigger to fire via an XML data structure called EVENTDATA. Extended events is a high-performance tracing capability that returns its trace data in XML format. Logon triggers return details through an EVENTDATA structure similar to the one provided by DDL triggers. Service Broker is a transaction based queuing system that is contained within a database. Most data that travels on Service Brokers queues is XML based. Event notifications are used to send details of DDL events via a Service Broker queue. These notifications are XML based.
This means that even database administrators will benefit from a level of understanding of how to work with XML in SQL Server, if they wish to progress to more advanced usage of the product.
Storing XML Data in SQL Server 2008 R2
17-5
Core XML Concepts
Key Points XML is a plain-text, Unicode-based meta-language (a language used to describe language). It can be used to hold both structured and semi-structured data and isn't tied to any particular vendor, language or operating system. It provides access to a wide range of technologies for manipulating, structuring, transforming and querying data.
Data Interchange XML came to prominence as a format for interchanging data between systems. It follows the same basic structure rules as other markup languages (such as HTML) and is used as a self-describing language. Consider the following XML document, which is the same as on the slide: Dare Obasanjo One Microsoft Way Redmond WA 98052
Question: With no knowledge apart from the document above, what would you imagine it contains details of?
17-6
Implementing a Microsoft® SQL Server® 2008 R2 Database
Without any context and information, you can determine that this document holds the details about an order, the customer who placed the order along with the customer's name and address details. This explains why XML is defined as a self-describing language. In formal terminology, this is described as "deriving a schema" from a document.
XML Specifics The two first lines in the example document that start with "?xml" are referred to as processing instructions. These instructions are not a part of the data but determine the details of encoding. The first instruction in the example shows that version "1.0" of the XML specification is being used along with a specific encoding of "iso-8859-1". The second instruction indicates the use of the extensible style sheet (XSL) "orders.xsl" to format the document for display, if displaying the document is necessary. The third line of the example is the "order" element. Note that the document data starts with an opening order element and finishes with a closing order element shown as "". The order element also has an associated attribute named "id". Note: It is important to realize that elements in XML (as in most other markup languages) are casesensitive.
Attribute-centric vs. Element-centric XML There are two basic ways to encode data in XML. The following example shows element-centric XML: Tailspin Toys 12
The following example shows the equivalent data in attribute-centric XML:
Note that if all data for an element is contained in attributes, then a shortcut form of element is available. As an example, the two XML elements below are equivalent:
Question: Do you use XML for exchanging data between your organization and another organization?
Storing XML Data in SQL Server 2008 R2
17-7
Fragments vs. Documents
Key Points Well-formed XML has only one top-level element and element tags are correctly nested within each other. Documents with multiple top-level elements are considered fragments.
Documents vs. Fragments Consider the following XML document:
This provides the details for a single order and would be considered to be a well-formed XML document. Now, consider the following:
This text contains the details of multiple orders. While it is perfectly reasonable XML, it is considered to be a "fragment" of XML rather than a "document". To be called a document, the XML needs to have a single root element as shown in the following:
17-8
Implementing a Microsoft® SQL Server® 2008 R2 Database
Question: How could the XML fragment shown in the slide be converted to an XML document?
Storing XML Data in SQL Server 2008 R2
17-9
XML Namespaces
Key Points An XML namespace is a collection of names that can be used as element or attribute names. It is used to avoid conflicts with other names. Imagine an XML instance that contains references to both a product and an order. Both of these elements could have a child element called "id". Any reference to the "id" element could easily be ambiguous. Namespaces are used to remove that ambiguity.
XML Namespaces An XML namespace is defined using the special attribute "xmlns" and the value of the attribute must be a valid Universal Resource Identifier (URI). As an example, an XML namespace attribute could be: xmlns="http://schemas.microsoft.com/sqlserver/profiles/gml"
Note that specifying an address in a namespace does not necessarily suggest that the URI provided could be used to retrieve the details in any particular format. Many URIs used in namespaces only link to an address where a human-readable description of the namespace is found. Many other URIs do not lead to any real resources at all. The URI is simply used as a unique identifier for the namespace to reduce the possibility of duplicate entries.
Prefixes When declaring a namespace, an alias for the namespace is assigned. In XML terminology, this alias is called a "prefix" because of the way it is used within the remainder of the XML. You can see this in the snippet below from the example shown in the slide: xmlns="urn:AW_NS" xmlns:o="urn:AW_OrderNS"
Two namespaces have been declared. The second namespace has been assigned the prefix "o". The prefix is then used later to identify which namespace any element name is part of as shown below:
17-10
Implementing a Microsoft® SQL Server® 2008 R2 Database
In this snippet, the Order and OrderDetail elements are identified as being part of the "urn:AW_OrderNS" namespace by being prefixed by "o". Question: Why do you imagine that aliases are typically used with namespaces?
Storing XML Data in SQL Server 2008 R2
17-11
XML Schemas
Key Points XML schemas are used to provide rules that determine the specific elements, attributes, and layout that should be permitted within an XML document.
XML Schemas The Worldwide Web Consortium (W3C) defined XML schemas as a more capable replacement for earlier objects called Document Type Definitions (DTDs). An XML schema defines: • • • • • • • •
elements that can appear in a document attributes that can appear in a document which elements are child elements the order of child elements the number of child elements whether an element is empty or can include text data types for elements and attributes default and fixed values for elements and attributes
XML schemas are often also referred to as XML Schema Definitions (XSDs). XSD is also the default file extension used by most products when storing XML schemas in operating system files.
17-12
Implementing a Microsoft® SQL Server® 2008 R2 Database
Appropriate Usage of XML Data Storage in SQL Server
Key Points Given how widely XML has come to be used in application development in higher application tiers, there is a tendency towards the overuse of XML within the database. It is important to consider when it is and when it is not appropriate to use XML within SQL Server.
XML vs. Objects Higher level programming languages that are used for constructing application programs often represent entities such as customers and orders as objects. Many developers see SQL Server as a simple repository for objects, that is, an object-persistence layer. Consider the following table definition: CREATE TABLE dbo.Object ( ObjectID uniqueidentifier PRIMARY KEY, PersistedData xml );
While there is no suggestion that this would make for a good database design, note that this table design could be used to store all objects from an application: customers, orders, payments, etc. all in a single table. Compare this to how tables have been traditionally designed in relational databases. Question: What is the basic problem with using this table design as your entire database design? SQL Server provides the developer with a wide range of choices with a simple XML design at one end of the spectrum and fully normalized relational tables at the other end. It is important to understand that there is no generic right and wrong answer for where in this range of options that a table should be designed.
Appropriate Use Cases There are a number of reasons for storing XML data within SQL Server.
Storing XML Data in SQL Server 2008 R2
•
• •
•
•
•
• •
17-13
You may be dealing with data that is already in XML, such as an order being received electronically from a customer. You may wish to share, query and modify the XML data in an efficient and transacted way. You may need to achieve a level of interoperability between your relational and XML data. Imagine the need to join a customer table with a list of customer IDs that are being sent to you as XML. You may need to use XML formats to achieve cross-domain applications and need to have maximum portability for your data. Other systems that you are communicating with may be based on entirely different technologies and not represent data in the same way as your server. You may not know the structure of your data in advance. It is common to have a mixture of structured and semi-structured data. A table might hold some standard relational columns but also hold some less structured data in XML columns. You may have very sparse data. Imagine a table with thousands of columns where only a few columns or a few rows ever tend to have any data in them. (Sparse column support in SQL Server provides another mechanism for dealing with this situation but it also uses XML in the form of XML column sets. Sparse columns are an advanced topic beyond the scope of this current course). You may need to have order within your data. For example, order detail lines might need to be retained in a specific order. Relational tables and views have no implicit order. XML documents can exhibit a predictable order. You may wish to have SQL Server validate that your XML data meets a particular XML schema before processing it. You may wish to create indexes on your XML data to make it faster to query.
17-14
Implementing a Microsoft® SQL Server® 2008 R2 Database
Demonstration 1A: Introduction to XML and XML Schemas
Key Points In this demonstration you will see how: •
XML is structured
•
Documents differ from fragments
•
XML schemas are structured
Demonstration Steps 1. 2.
3. 4. 5.
Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_17_PRJ\6232B_17_PRJ.ssmssln and click Open. Open and execute the 00 – Setup.sql script file from within Solution Explorer. Open the 11 – Demonstration 1A.sql script file. Follow the instructions contained within the comments of the script file.
Question: What would the likely problem be if NULL elements are simply omitted?
Storing XML Data in SQL Server 2008 R2
17-15
Lesson 2
Storing XML Data and Schemas in SQL Server
After coming to an understanding of XML, schemas and the surrounding terminology, you can now turn your attention to how XML data and schemas can be stored within SQL Server. This is the first step in learning how to process XML effectively within SQL Server. You need to see how the XML data type is used, how to define schema collections that contain XML schemas, how to declare both typed and untyped variables and database columns and how to specify how well-formed the XML data needs to be before it can be stored.
Objectives After completing this lesson, you will be able to: • • • •
Use the XML data type Create XML schema collections Declare variables and database columns as either typed or untyped XML Choose whether XML fragments can be stored rather than entire XML documents
17-16
Implementing a Microsoft® SQL Server® 2008 R2 Database
XML Data Type
Key Points SQL Server 2005 introduced a native data type for storing XML data in SQL Server. It can be used for variables, parameters and columns in databases. SQL Server also exposes a number of methods that can be used for querying or modifying the XML data.
xml Data Type xml is a built-in data type for SQL Server. It is an intrinsic data type, which means that it is not implemented separately via managed code. Variables, parameters and database columns can be declared as xml data type. You can see a variable declared using xml data type in the following code declaration: DECLARE @Settings xml;
Once you have declared a variable of xml data type, by default any well-formed XML can be stored in it. Look at the assignments in the following code block: SET @Settings = '"; SET @Settings = '';
The first assignment would be successful and the second assignment would fail as the value being assigned is not well-formed XML.
Canonical Form It is important to realize that SQL Server stores XML data in an internal format that makes it easier for it to process the XML data when required. It does not store the XML in the same format (including whitespace) as the data was received in. For example, look at the following code block: DECLARE @Settings xml;
Storing XML Data in SQL Server 2008 R2
17-17
SET @Settings = N''; SELECT @Settings;
When executed, the result returned is as follows:
Note that the output returned is logically equivalent to the input but the output is not in exactly the same format as the input. It is referred to as having been returned in a "canonical" or logically-equivalent form.
17-18
Implementing a Microsoft® SQL Server® 2008 R2 Database
XML Schema Collections
Key Points While the xml data type will only store well-formed XML, it is possible to further constrain the stored values by associating the data type with an XML schema collection.
XML Schema Collections In the first lesson, you learned how XML schemas can be used to constrain what can be stored in an XML document. SQL Server does not have an XML schema as a database object; it has an XML SCHEMA COLLECTION object which is an object that holds a collection of XML schemas. When you associate an XML SCHEMA COLLECTION with an XML variable, parameter, or database column, then the XML to be stored in that location needs to conform to at least one of the schemas that is contained in the schema collection.
XML Schemas While they are somewhat legible to humans, XML schemas are designed to be processed by computer systems. Even simple schemas tend to have quite a level of complexity. Fortunately, you do not need to be able to read (or worse write!) such schemas. They are generally created by tools and utilities. SQL Server can also create XML schemas. You will see an example of this in a later lesson. An example of an XML schema is shown on the following page:
Storing XML Data in SQL Server 2008 R2
17-19
Creating an XML Schema Collection An XML schema collection holds one or more schemas. The data being validated must match at least one of the schemas within the collection. You create an XML schema collection with the CREATE XML SCHEMA COLLECTION syntax shown in the following code snippet: CREATE XML SCHEMA COLLECTION SettingsSchemaCollection AS N'