You are on page 1of 442

O F F I C I A L

M I C R O S O F T

L E A R N I N G

P R O D U C T

6232B

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. Software means the Virtual Machines and Virtual Hard Disks, or other software applications that may be included with the Licensed Content. 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. 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.

g.

h. Student(s) means a student duly enrolled for an Authorized Training Session at your location. i.

j.

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. Survival. Your duty to protect confidential information survives this agreement.

ii.

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 d. 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.

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). 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. 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.

e.

f.

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 o You may not install Virtual Machines and Virtual Hard Disks on portable Devices or Devices that are accessible to other networks. 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 o o o 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. You will ensure that the Virtual Machines and Virtual Hard Disks are not copied or downloaded from Devices on which you installed them. You will strictly comply with all Microsoft instructions relating to installation, use, activation and deactivation, and security of Virtual Machines and Virtual Hard Disks. You may not modify the Virtual Machines and Virtual Hard Disks or any contents thereof. 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 Materials original copyright notice, or a copyright notice to Microsofts 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 elses 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 Microsofts 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 Qubec, Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en franais. EXONRATION 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 pril. Microsoft naccorde aucune autre garantie expresse. Vous pouv ez bnficier 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, dadquation un usage partic ulier et dabsence de contrefaon sont exclues. LIMITATION DES DOMMAGES-INTRTS 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 prtendre aucune indemnisation pour les autres dommages, y compris les dommages spciaux, indirects ou accessoires et pertes de bnfices. 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 rclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilit stricte, de ngligence ou dune autre faute dans la limite autorise par la loi en vigueur.

Elle sapplique galement, mme si Microsoft connaissait ou devrait connatre lventualit dun tel dommage. Si votre pays nautorise pas lexclusion ou la limitation de responsabilit pour les dommages indirects , accessoires ou de quelque nature que ce soit, il se peut que la limitation ou lexclusion ci-dessus ne sappliquera pas votre gard. EFFET JURIDIQUE. Le prsent contrat dcrit certains droits juridiques. Vous pourriez avoir dautres droits prvus par les lois de votre pays. Le prsent contrat ne modifie pas les droits que vous confrent les lois de votre pays si celles-ci ne le permettent pas.

Implementing a Microsoft SQL Server 2008 R2 Database

ix

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 Zealands major CPLS training centers in Wellington. He has been programming from the early 1970shis 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

xi

Contents
Module 13: Designing and Implementing User-Defined Functions
Lesson 1: Overview of Functions Lesson 2: Designing and Implementing Scalar Functions Lesson 3: Designing and Implementing Table-Valued Functions Lesson 4: Implementation Considerations for Functions Lesson 5: Alternatives to Functions Lab 13: Designing and Implementing User-Defined Functions 13-3 13-7 13-14 13-19 13-26 13-29

Module 14: Ensuring Data Integrity through Constraints


Lesson 1: Enforcing Data Integrity Lesson 2: Implementing Domain Integrity Lesson 3: Implementing Entity and Referential Integrity Lab 14: Ensuring Data Integrity through Constraints 14-3 14-10 14-18 14-28

Module 15: Responding to Data Manipulation via Triggers


Lesson 1: Designing DML Triggers Lesson 2: Implementing DML Triggers Lesson 3: Advanced Trigger Concepts Lab 15: Responding to Data Manipulation via Triggers 15-3 15-13 15-20 15-30

Module 16: Implementing Managed Code in SQL Server 2008 R2


Lesson 1: Introduction to SQL CLR Integration Lesson 2: Importing and Configuring Assemblies Lesson 3: Implementing SQL CLR Integration Lab 16: Designing and Implementing Views 16-3 16-16 16-23 16-43

Module 17: Storing XML Data in SQL Server 2008 R2


Lesson 1: Introduction to XML and XML Schemas Lesson 2: Storing XML Data and Schemas in SQL Server Lesson 3: Implementing the XML Data Type Lab 17: Storing XML Data in SQL Server 17-3 17-15 17-26 17-31

Module 18: Querying XML Data in SQL Server


Lesson 1: Using the T-SQL FOR XML Statement Lesson 2: Getting Started with XQuery Lesson 3: Shredding XML Lab 18: Querying XML Data in SQL Server 18-3 18-15 18-25 18-34

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 Lesson 2: Working with SQL Server Spatial Data Types Lesson 3: Using Spatial Data in Applications Lab 19: Working with SQL Server Spatial Data 19-3 19-13 19-27 19-38

Module 20: Working with Full-Text Indexes and Queries


Lesson 1: Introduction to Full-Text Indexing Lesson 2: Implementing Full-Text Indexes in SQL Server Lesson 3: Working with Full-Text Queries Lab 20: Working with Full-Text Indexes and Queries 20-3 20-10 20-21 20-33

Lab Answer Keys

Designing and Implementing User-Defined Functions

13-1

Module 13
Designing and Implementing User-Defined Functions
Contents:
Lesson 1: Overview of Functions Lesson 2: Designing and Implementing Scalar Functions Lesson 3: Designing and Implementing Table-Valued Functions Lesson 4: Implementation Considerations for Functions Lesson 5: Alternatives to Functions Lab 13: Designing and Implementing User-Defined Functions 13-3 13-7 13-14 13-19 13-26 13-29

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

13-5

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-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 BEGINEND that wraps the body of the stored procedure is optional, the body of the function must be defined in a BEGINEND 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 BEGINEND 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 BEGINEND 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 BEGINEND 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. 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.

3. 4. 5.

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 BEGINEND 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. 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.

2. 3.

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. 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.

2. 3.

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. 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: 4. 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.

5. 6. 7.

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

13-31

FROM Marketing.Prospect ORDER BY FullName;

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

14-1

Module 14
Ensuring Data Integrity through Constraints
Contents:
Lesson 1: Enforcing Data Integrity Lesson 2: Implementing Domain Integrity Lesson 3: Implementing Entity and Referential Integrity Lab 14: Ensuring Data Integrity through Constraints 14-3 14-10 14-18 14-28

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 doesnt 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

14-7

Question: When might more than one type of integrity apply to a scenario?

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 persons 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. 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.

3. 4. 5.

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. 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.

2. 3.

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. 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: 4. 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.

5. 6. 7.

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. Mandatory Field Required Required Required

Column ProspectID LanguageID YieldOutcome

Data Type int nchar(6) int

Validation rule Must be a valid prospect Must be a valid language 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

Default value should be SYSDATETIME() if not supplied

Notes

nvarchar(MAX)

Optional

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

15-1

Module 15
Responding to Data Manipulation via Triggers
Contents:
Lesson 1: Designing DML Triggers Lesson 2: Implementing DML Triggers Lesson 3: Advanced Trigger Concepts Lab 15: Responding to Data Manipulation via Triggers 15-3 15-13 15-20 15-30

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

15-13

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-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. 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.

3. 4. 5.

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. 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.

2. 3.

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. 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.

2. 3.

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. 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.

2. 3.

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. 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.

2. 3.

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. 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: 4. 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.

5. 6. 7.

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

15-31

Log on using the following credentials: I. II. User name: AdventureWorks\Administrator Password: Pa$$w0rd

8. 9. 10. 11. 12. 13. 14. 15.

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 CampaignAuditID AuditTime ModifyingUser RemainingBalance Data Type int datetime2 sysname decimal(18,2) Value to Insert IDENTITY SYSDATETIME() ORIGINAL_LOGIN() 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. 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?

2. 3.

Best Practices
1. 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.

2.

Implementing Managed Code in SQL Server 2008 R2

16-1

Module 16
Implementing Managed Code in SQL Server 2008 R2
Contents:
Lesson 1: Introduction to SQL CLR Integration Lesson 2: Importing and Configuring Assemblies Lesson 3: Implementing SQL CLR Integration Lab 16: Designing and Implementing Views 16-3 16-16 16-23 16-43

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

16-5

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-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. 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.

3. 4. 5. 6. 7.

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 computers 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. 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.

2. 3.

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 doesnt 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 doesnt 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. 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.

2. 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. 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.

2. 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 doesnt 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

16-39

TypeName::Method() eg: GEOMETRY::STGeomFromText(POINT (12 15))

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. 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.

2. 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. 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: 4. 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.

5. 6. 7.

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. User name: AdventureWorks\Administrator Password: Pa$$w0rd

8. 9. 10. 11. 12. 13. 14. 15.

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. 2. Ensure that SQL CLR integration is enabled for the SQL Server instance. Flag the MarketDev database as trustworthy.

Task 2: Catalog the assembly and the functions contained within it


1. 2. 3. 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. Query the sys.assemblies and sys.assembly_files system views to confirm the details of how the assembly has been cataloged. 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. 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. 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.

4.

5.

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('test@somewhere.com'); 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. 2. 3. Use the CREATE AGGREGATE statement to catalog the user-defined aggregate dbo.AggString. dbo.AggString takes a single nvarchar(4000) parameter and returns type nvarchar(4000). It is found in the assembly at path: SQLCLRDemo.[SQLCLRDemo.AggString]. 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. 2. 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]. 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 SELECT TextValue.ToString(), TextValue.CompressedLength(), TextValue.CompressionPercentage() FROM dbo.TestTable; GO SELECT AVG(TextValue.CompressionPercentage()) FROM dbo.TestTable; GO DROP TABLE dbo.TestTable; GO compressible data');

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).
value';

DECLARE @TestString zVarChar; SET @TestString = 'Some compressible PRINT @TestString.CompressedValue();

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. 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?

2. 3.

Best Practices
1. 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.

2. 3. 4.

16-50

Implementing a Microsoft SQL Server 2008 R2 Database

Storing XML Data in SQL Server 2008 R2

17-1

Module 17
Storing XML Data in SQL Server 2008 R2
Contents:
Lesson 1: Introduction to XML and XML Schemas Lesson 2: Storing XML Data and Schemas in SQL Server Lesson 3: Implementing the XML Data Type Lab 17: Storing XML Data in SQL Server 17-3 17-15 17-26 17-31

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

17-3

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-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:
<?xml version="1.0" encoding="iso-8859-1" ?> <?xml-stylesheet href="orders.xsl"?> <order id="ord123456"> <customer id="cust0921"> <first-name>Dare</first-name> <last-name>Obasanjo</last-name> <address> <street>One Microsoft Way</street> <city>Redmond</city> <state>WA</state> <zip>98052</zip> </address> </customer> </order>

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 "</order>". 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:
<Customer> <Name>Tailspin Toys</Name> <Rating>12</ Rating > </Customer>

The following example shows the equivalent data in attribute-centric XML:


<Customer Name="Tailspin Toys" Rating="12"> </Customer>

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:
<Customer Name="Tailspin Toys" Rating="12"></Customer> <Customer Name="Tailspin Toys" Rating="12" />

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:
<order id="ord123456"> <customer id="cust0921" /> </order>

This provides the details for a single order and would be considered to be a well-formed XML document. Now, consider the following:
<order id="ord123456"> <customer id="cust0921" /> </order> <order id="ord123457"> <customer id="cust0925" /> </order>

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:
<orders> <order id="ord123456"> <customer id="cust0921" /> </order> <order id="ord123457"> <customer id="cust0925" />

17-8

Implementing a Microsoft SQL Server 2008 R2 Database

</order> </orders>

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

<o:Order SalesOrderID="43860" Status="5" OrderDate="2001-08-01T00:00:00"> <o:OrderDetail ProductID="761" Quantity="2"/> <o:OrderDetail ProductID="770" Quantity="1"/> </o:Order>

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. 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.

3. 4. 5.

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 = '<Customer Name="Terry"></Customer>"; SET @Settings = '<Customer Name="Terry"><Customer>';

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'<Customer Name="Terry"></Customer>'; 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:
<xsd:schema targetNamespace="urn:schemas-microsoft-com:sql:SqlRowSet1" xmlns:schema="urn:schemas-microsoft-com:sql:SqlRowSet1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes= "http://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified"> <xsd:import namespace= "http://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="http://schemas.microsoft.com/ sqlserver/2004/sqltypes/sqltypes.xsd" />

Storing XML Data in SQL Server 2008 R2

17-19

<xsd:element name="Production.Product"> <xsd:complexType> <xsd:attribute name="ProductID" type="sqltypes:int" use="required" /> <xsd:attribute name="Name" use="required"> <xsd:simpleType sqltypes:sqlTypeAlias= "[AdventureWorks2008R2].[dbo].[Name]"> <xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions= "IgnoreCase IgnoreKanaType IgnoreWidth"> <xsd:maxLength value="50" /> </xsd:restriction> </xsd:simpleType> </xsd:attribute> <xsd:attribute name="Size"> <xsd:simpleType> <xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions= "IgnoreCase IgnoreKanaType IgnoreWidth"> <xsd:maxLength value="5" /> </xsd:restriction> </xsd:simpleType> </xsd:attribute> <xsd:attribute name="Color"> <xsd:simpleType> <xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions= "IgnoreCase IgnoreKanaType IgnoreWidth"> <xsd:maxLength value="15" /> </xsd:restriction> </xsd:simpleType> </xsd:attribute> </xsd:complexType> </xsd:element> </xsd:schema>

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'<?xml version="1.0" ?> <xsd:schema ... </xsd:schema>';

System Views
The details of the existing XML schema collections can be seen by querying the sys.xml_schema_collections system view. The details of the namespaces that are referenced by XML schema collections can be seen by querying the sys.xml_schema_namespaces system view.

17-20

Implementing a Microsoft SQL Server 2008 R2 Database

Like XML, XML schema collections are not stored in the format that you enter them. They are stripped into an internal format. You can get an idea of how they are stored by querying the sys.xml_schema_components system view as shown in the following code:
SELECT cp.* FROM sys.xml_schema_components cp JOIN sys.xml_schema_collections c ON cp.xml_collection_id = c.xml_collection_id WHERE c.name = 'SettingsSchemaCollection';

Storing XML Data in SQL Server 2008 R2

17-21

Untyped vs. Typed XML

Key Points
When storing XML data, you can choose to allow any XML to be stored or you can choose to constrain the available values by associating the XML location with an XML schema collection.

Untyped XML
You may choose to allow any well-formed XML to be stored. One reason is that you might not have a schema for the XML data. Another reason is that you might want to avoid the processing overhead involved in validating the XML against the XML schema collection. For complex schemas, validating the XML can involve substantial work. The following example shows a table being created with an untyped XML column:
CREATE TABLE App.Settings ( SessionID int PRIMARY KEY, WindowSettings xml );

Any well-formed XML could be stored in the WindowSettings column up to the maximum size of a SQL Server XML object which is currently 2GB.

Typed XML
You may wish to have SQL Server validate your data against a schema. You might want to take advantage of storage and query optimizations based on the type information or want to take advantage of this type information during the compilation of your queries. The following example shows the same table being created with a typed XML column:
CREATE TABLE App.Settings ( SessionID int PRIMARY KEY, WindowSettings xml (SettingsSchemaCollection)

17-22

Implementing a Microsoft SQL Server 2008 R2 Database

);

In this case, a schema collection called SettingsSchemaCollection has been defined and SQL Server will not allow data to be stored in the WindowSettings column if it does not meet the requirements of at least one of the XML schemas in the SettingsSchemaCollection. Question: What types of errors could occur if the XML data you were querying did not follow the schema you were expecting?

Storing XML Data in SQL Server 2008 R2

17-23

CONTENT vs. DOCUMENT

Key Points
While specifying typed XML, you can also specify whether entire XML documents must be provided or if XML fragments can be stored.

CONTENT
In the example used in the last topic, a table was defined by this code:
CREATE TABLE App.Settings ( SessionID int PRIMARY KEY, WindowSettings xml (SettingsSchemaCollection) );

This is equivalent to defining the table by the following code as the keyword CONTENT is the default value for typed XML declarations:
CREATE TABLE App.Settings ( SessionID int PRIMARY KEY, WindowSettings xml (CONTENT SettingsSchemaCollection) );

Note the addition of the CONTENT keyword. When CONTENT is specified, XML fragments and entire well-formed XML documents can be stored in the typed XML location.

DOCUMENT
The alternative to the default value of CONTENT is to specify the keyword DOCUMENT as shown in the following code:
CREATE TABLE App.Settings ( SessionID int PRIMARY KEY, WindowSettings xml (DOCUMENT SettingsSchemaCollection)

17-24

Implementing a Microsoft SQL Server 2008 R2 Database

);

In this case, XML fragments would not be able to be stored in the WindowSettings column. Only wellformed XML documents could be stored. For example, a column that is intended to store a customer order can then be presumed to actually hold a customer order and not some other type of XML document.

Storing XML Data in SQL Server 2008 R2

17-25

Demonstration 2A: Typed vs. Untyped XML

Key Points
In this demonstration you will see how to: Create an XML SCHEMA COLLECTION. Use typed XML in a column of a table. Differentiate between CONTENT and DOCUMENT.

Demonstration Steps
1. 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_17_PRJ\6232B_17_PRJ.ssmssln and click Open. Open and execute the 00 Setup.sql script file from within Solution Explorer.

2. 3.

Open the 21 Demonstration 2A.sql script file. Follow the instructions contained within the comments of the script file.

Question: What is the difference between an XML SCHEMA COLLECTION and an XML schema?

17-26

Implementing a Microsoft SQL Server 2008 R2 Database

Lesson 3

Implementing XML Indexes

The final core aspect related to storing XML data in SQL Server is the creation of indexes on the XML columns. These are critical for achieving high performance of XML based queries. There are four types of XML index: a primary index and three types of secondary index. It is important to know how each can be used to achieve the maximum performance gain for your queries.

Objectives
After completing this lesson, you will be able to: Describe the need for XML indexes Explain how each of the four types of XML index can be used

Storing XML Data in SQL Server 2008 R2

17-27

What are XML Indexes?

Key Points
Indexes are used in SQL Server to improve the performance of queries. XML indexes are used to improve the performance of XQuery-based queries. (XQuery will be discussed in the next module)

XML Indexes
Many systems query XML data directly as text. This can be very slow, particularly if the XML data is large. You saw earlier how XML data is not directly stored in a text format in SQL Server. For ease of querying, it is broken into a form of object tree that makes it easier to navigate in memory. Rather than having to create these object trees as required for queries, which is also a relatively slow process, XML indexes can be defined. A XML index is somewhat like a copy of an XML object tree that is saved into the database for rapid reuse. It is important to note that XML indexes can be quite large compared to the underlying XML data. While relational indexes are often much smaller than the tables they are built on, it is not uncommon to see XML indexes that are larger than the underlying data.

17-28

Implementing a Microsoft SQL Server 2008 R2 Database

Types of XML Indexes

Key Points
SQL Server supports four types of XML index: a primary XML index and up to three secondary XML types.

Primary XML Index


The primary XML index basically provides a persisted object tree in an internal format. The tree has been formed from the structure of the XML, is used to speed up access to elements and attributes within the XML and avoids the need to read the entire XML document for each and every query. Before a primary XML index can be created on a table, the table must have a clustered primary key. Based on the App.Settings table that was used as an example earlier, you could create a primary XML index by executing the following code:
CREATE PRIMARY XML INDEX PXML_Settings_WindowSettings ON App.Settings (WindowSettings);

Secondary XML Indexes


Most of the querying benefit comes from primary XML indexes, however, SQL Server also allows for the creation of three types of secondary XML index. These secondary indexes are each designed to speed up a particular type of query. Secondary XML indexes are used to speed up particular types of queries. There are three forms of query that they help with: PATH, VALUE and PROPERTY. A PATH index helps decide if a particular path to an element or attribute is valid. It is typically used with the exist() XQuery method. (XQuery is discussed in the next module). A VALUE index helps obtaining the value of an element or attribute. A PROPERTY index is used when retrieving multiple values via PATH expressions. You will see the use of these queries in the next module. A secondary XML index can only be created once a primary XML index has been established. When creating the secondary XML index, you need to reference the primary XML index:

Storing XML Data in SQL Server 2008 R2

17-29

CREATE XML INDEX IXML_Settings_WindowSettings_Path ON App.Settings (WindowSettings) USING XML INDEX PXML_Settings_WindowSettings FOR PATH;

XML Tooling Support


Note that primary XML indexes can be created in SQL Server Management Studio or via T-SQL commands. In SQL Server 2008 R2, secondary XML indexes can only be created using T-SQL commands. Question: Why does SQL Server support multiple types of secondary XML index?

17-30

Implementing a Microsoft SQL Server 2008 R2 Database

Demonstration 3A: Implementing XML Indexes

Key Points
In this demonstration you will see how to: Create a primary XML index Create a secondary XML index Query the sys.xml_indexes system view Identify the requirement of a clustered primary key on the table by XML indexes

Demonstration Steps
1. 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_17_PRJ\6232B_17_PRJ.ssmssln and click Open. Open and execute the 00 Setup.sql script file from within Solution Explorer.

2. 3.

Open the 31 Demonstration 3A.sql script file. Follow the instructions contained within the comments of the script file.

Question: How does SQL Server enforce the requirement that a primary XML index must be created before a secondary XML index can be created?

Storing XML Data in SQL Server 2008 R2

17-31

Lab 17: Storing XML Data 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. 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: 4. 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.

5. 6. 7.

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.

17-32

Implementing a Microsoft SQL Server 2008 R2 Database

Log on using the following credentials: I. II. User name: AdventureWorks\Administrator Password: Pa$$w0rd

8. 9. 10. 11. 12. 13. 14. 15.

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_17_PRJ\6232B_17_PRJ.ssmssln. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.

Lab Scenario
A new developer in your organization has discovered that SQL Server can store XML directly. He is keen to use this mechanism extensively. In this lab, you will decide on appropriate usage of XML within the documented application. You also have an upcoming project that will require the use of XML data within SQL Server. No members of your current team have experience working with XML data in SQL Server. You need to learn how to process XML data within SQL Server and you have been provided with some sample queries to assist with this learning.

Supporting Documentation Use Cases


Use Cases Requirements Existing XML data that is stored but not processed Storing attributes for a customer Relational data that is being passed through a system but not processed within it Storing attributes that are nested (that is attributes stored within attributes)

Storing XML Data in SQL Server 2008 R2

17-33

Exercise 1: Appropriate Usage of XML Data Storage in SQL Server


Scenario
In this exercise, you will need to assess the list of use cases provided by your new developer and determine which are appropriate for XML storage in SQL Server and which are not. The main tasks for this exercise are as follows: 1. 2. Review the list of Use Cases Determine whether each is appropriate for XML storage

Task 1: Review the list of Use Cases


Review the list of use cases in the supporting documentation

Task 2: Determine whether each is appropriate for XML


Determine whether the use cases are suitable for XML storage Results: After this exercise, you have seen how to analyze requirements and determine on appropriate use cases for XML storage.

17-34

Implementing a Microsoft SQL Server 2008 R2 Database

Exercise 2: Investigate the Storage of XML Data in Variables


Scenario
Before you can begin to work with XML data in your organization, you need to explore how XML data is stored in variables. You have been provided with a set of sample XML queries to assist with this. In this exercise, you will review the effect of executing these queries. The main tasks for this exercise are as follows: 1. Review and execute the queries, and review the results

Task 1: Review and execute the queries, and review the results
Review the queries, execute the queries and determine how the output results relate to the queries. Do this one query at a time for scripts 17.1 to 17.9.

Results: After this exercise, you have seen how XML data is stored in variables.

Storing XML Data in SQL Server 2008 R2

17-35

Exercise 3: Investigate the use of XML Schema Collections


Scenario
For some of the XML processing that you will need to perform in your upcoming project, you will need to validate XML data using XML schemas. In SQL Server, XML schemas are stored in XML schema collections. You need to investigate how these schemas are used. You have been provided with a set of sample queries to assist with this. In this exercise, you will review the effect of executing these queries. The main tasks for this exercise are as follows: 1. Review and execute the queries, and review the results

Task 1: Review and execute the queries, and review the results
Review the queries, execute the queries and note the output. Do this one query at a time for scripts 17.10 and 17.11.

Results: After this exercise, you have seen how to create XML schema collections.

17-36

Implementing a Microsoft SQL Server 2008 R2 Database

Challenge Exercise 4: Investigate the Creation of Database Columns Based on XML (Only if time permits)
Scenario
The final aspect of XML data storage in SQL Server that you will need to understand for your upcoming project is how XML data is stored in tables. You need to investigate how columns of XML data type are used. You have been provided with a set of sample queries to assist with this. In this exercise, you will review the effect of executing these queries. The main tasks for this exercise are as follows: 1. Review and execute the queries, and review the results

Task 1: Review and execute the queries, and review the results
Review the queries, execute the queries and note the results of the queries. Do this one query at a time for scripts 17.12 to 17.20.

Results: After this exercise, you have seen how to create database columns based on the XML data type.

Storing XML Data in SQL Server 2008 R2

17-37

Module Review and Takeaways

Review Questions
1. 2. 3. What is XML? How are NULL elements represented in an XML document? What is the difference between an element and an attribute?

Best Practices
1. 2. 3. 4. Use appropriate data types for your database columns. Do not store all your data in XML columns. Use XML schemas only when required. Validating data against schemas incurs substantial processing overhead. Ensure you have at least basic XML proficiency when working with SQL Server, even if you will be working primarily in database administration. Index XML data stored in database columns. Use the appropriate type of index for the types of queries expected.

17-38

Implementing a Microsoft SQL Server 2008 R2 Database

Querying XML Data in SQL Server

18-1

Module 18
Querying XML Data in SQL Server
Contents:
Lesson 1: Using the T-SQL FOR XML Statement Lesson 2: Getting Started with XQuery Lesson 3: Shredding XML Lab 18: Querying XML Data in SQL Server 18-3 18-15 18-25 18-34

18-2

Implementing a Microsoft SQL Server 2008 R2 Database

Module Overview

In the previous module, you saw how SQL Server can be used to store XML based data and how you can index XML database columns to increase the performance of queries. You now need to see how to query the XML data. The ability to query XML data directly avoids the need to shred it to a relational format before executing SQL queries. To effectively process XML, it is important to be able to query XML data in several ways: returning existing relational data as XML, querying data that is already XML, and shredding XML data into a relational format.

Objectives
After completing this module, you will be able to: Use the T-SQL FOR XML Statement Work with basic XQuery queries Shred XML to a relational form

Querying XML Data in SQL Server

18-3

Lesson 1

Using the T-SQL FOR XML Statement

There is a common requirement to return data that is stored in relational database columns as XML documents. Typically this requirement relates to the need to exchange data with other systems, including those from other organizations. When the FOR XML clause is added to a T-SQL SELECT statement, it causes the output to be returned as XML instead of as a relational recordset. SQL Server provides a number of modes for the FOR XML clause to allow the production of many styles of XML document.

Objectives
After completing this lesson, you will be able to: Explain the role of the FOR XML clause Use RAW Mode Queries Use Auto Mode Queries Use Explicit Mode Queries Use Path Mode Queries Retrieve Nested XML

18-4

Implementing a Microsoft SQL Server 2008 R2 Database

Introducing the FOR XML clause

Key Points
The FOR XML clause is used to extend the T-SQL SELECT statement syntax and causes the statement to return XML instead of rows and columns. It can be configured to return the attributes, elements, and/or schema that are required for client applications.

FOR XML
The FOR XML clause works in one of four modes: RAW mode generates a single <row> element per row in the rowset that is returned by the SELECT statement. AUTO mode generates nesting in the resulting XML based on the way the SELECT statement is specified. You have minimal control over the shape of the XML generated. If you need to produce nested XML, AUTO mode is a better choice than RAW mode. EXPLICIT mode allows more control over the shape of the XML. It can be used when other modes do not provide enough flexibility but does so at the cost of greater complexity. You can mix attributes and elements at will in deciding the shape of the XML. PATH mode together with the nested FOR XML query capability provides much of the flexibility of the EXPLICIT mode in a simpler manner.

Question: Why would sending XML data to a supplier be more useful than sending text files with fixed width columns?

Querying XML Data in SQL Server

18-5

Using RAW Mode Queries

Key Points
RAW mode is the simplest mode to work with in the FOR XML clause. It returns a simple XML representation of the rowset and can optionally specify a row element name and a root element.

FOR XML RAW


Look at the following simple T-SQL query:
SELECT FirstName, LastName, PersonType FROM Person.Person ORDER BY FirstName, LastName;

When executed, it returns the following results:

Now, look at the modified statement after adding the FOR XML clause:
SELECT FirstName, LastName, PersonType FROM Person.Person ORDER BY FirstName, LastName FOR XML RAW;

18-6

Implementing a Microsoft SQL Server 2008 R2 Database

When executed, this returns the following:

Note that one XML element is returned for each row from the rowset, the element has a generic name of "row" and all columns are returned as attributes. In the example on the slide, you can see how to override the generic element name. In that example, the elements have been named "Order" instead. In addition, notice that the results have been returned as an XML fragment rather than an XML document. This is because there is no root element. Also, in the example on the slide, you can see how to automatically add a root element called "Orders".

Element-centric XML
You will notice that in the previous examples that the columns from the rowset have been returned as attributes. This is referred to as "attribute-centric" XML. You can modify this behavior to produce "element-centric" XML by adding the keyword ELEMENTS to the FOR XML clause. You can see this in the following query:
SELECT FirstName, LastName, PersonType FROM Person.Person ORDER BY FirstName, LastName FOR XML RAW, ELEMENTS;

When executed, this query returns the following output:

Note that each column has been returned as a sub-element of the row element.

Querying XML Data in SQL Server

18-7

Using Auto Mode Queries

Key Points
With AUTO mode, by default, each row in the result set is represented as an XML element named after the table (or alias) it was selected from. AUTO mode generates nesting in the resulting XML based on the way the SELECT statement is specified. You have minimal control over the shape of the XML generated. AUTO mode queries are more capable of dealing with nested XML.

FOR XML AUTO


AUTO mode queries are useful if you want to generate simple hierarchies but they provide limited control of the resultant XML. If you need more control over the resultant XML than is provided by AUTO mode queries, you will need to consider using PATH or EXPLICIT modes instead. Look at the following query (which is a modified version of the query that you saw in the last topic):
SELECT FirstName, LastName, PersonType FROM Person.Person ORDER BY FirstName, LastName FOR XML AUTO;

Each table in the FROM clause, from which at least one column is listed in the SELECT clause, is represented as an XML element. The columns listed in the SELECT clause are mapped to attributes or subelements, if the optional ELEMENTS option is specified in the FOR XML clause. You can see the output of this query below:

18-8

Implementing a Microsoft SQL Server 2008 R2 Database

Note how the name of the table is directly used as the element name. For this reason, it is common to provide an alias for the table as shown in the following code:
SELECT FirstName, LastName, PersonType FROM Person.Person AS Person ORDER BY FirstName, LastName FOR XML AUTO;

When executed, it provides the following output:

NULL Columns
Look at the following query:
SELECT ProductID, Name, Color FROM Production.Product AS Product ORDER BY ProductID FOR XML AUTO;

When executed, it produces the following output:

Note that a number of products do not have any color. In the resultant XML, NULL values are not returned as zero length strings, by default they are omitted from the results. While in general this is appropriate, it can cause a specific problem when an XML schema is being derived from an XML document. For example, if someone sent you an XML document with product details, if none of the products happened to have a color, you would assume that there was no color column.

XSINIL
To assist in situations where a schema needs to be derived from a document that contains nullable columns, SQL Server provides an additional option XSINIL that adds an element to the output to indicate that an element exists but that it is currently NULL. Look at the following code:
SELECT ProductID, Name, Color FROM Production.Product AS Product ORDER BY ProductID FOR XML AUTO, ELEMENTS XSINIL;

When executed, it returns the following results:

Querying XML Data in SQL Server

18-9

Note the difference between the rows that have no color and the rows that do have a color.

18-10

Implementing a Microsoft SQL Server 2008 R2 Database

Using Explicit Mode Queries

Key Points
EXPLICIT mode gives you the greatest control over the resulting XML but at the price of query complexity. Many common queries that required EXPLICIT mode in SQL Server 2000 can be implemented using PATH mode (which was introduced in SQL Server 2005 and will be explained later).

FOR XML EXPLICIT


EXPLICIT mode queries define XML fragments as a universal table, which consists of a column for each piece of data that you require, and two additional columns. The additional columns are used to define the metadata for the XML fragment. The Tag column uniquely identifies the XML tag that will be used to represent each row in the results, and the Parent column is used to control the nesting of elements. Each row of data in the universal table represents an element in the resulting XML document. The power of EXPLICIT mode is to mix attributes and elements at will, create wrappers and nested complex properties, create space-separated values (for example, OrderID attribute may have a list of order ID values), and mixed contents. PATH mode, together with the nesting of FOR XML queries and the TYPE clause, gives enough power to replace most of the EXPLICIT mode queries in a simpler, more maintainable way. EXPLICIT mode is rarely needed now and is complicated to write queries for.

Querying XML Data in SQL Server

18-11

Using Path Mode Queries

Key Points
PATH mode provides a simpler way to mix elements and attributes. It can be used in many situations as an easier way to write query than those using EXPLICIT mode.

FOR XML PATH


PATH mode is a simpler way to introduce additional nesting for representing complex properties. In PATH mode, column names or column aliases are treated as XML Path Language (XPath) expressions. (More detail on XPath will be provided later in this module). These expressions indicate how the values are being mapped to XML. Each XPath expression is a relative XPath that provides the item type, such as the attribute, element, and scalar value, and the name and hierarchy of the node that will be generated relative to the row element. The slide provides an example of an XML PATH query. Note that the path to e.BusinessEntityID is shown as "@EmpID". Values starting with an @ symbol in XPath refer to attributes. You can see in the output that the e.BusinessEntityID value has been returned as the EmpID attribute of the row element. The next two columns listed in the example on the slide detail the path to the values. For example, the p.FirstName path is shown as "EmpName/First". This indicates that the p.FirstName value should be output as an element named "First" that is a sub-element of an element named "EmpName", which is itself returned as a sub-element of the row element. You can use FOR XML EXPLICIT mode queries to construct such XML from a rowset, but PATH mode provides a simpler alternative to the potentially time consuming EXPLICIT mode queries. PATH mode, together with the ability to write nested FOR XML queries and the TYPE directive to return xml data type instances, allows you to write queries with less complexity and gives enough power to replace most of the EXPLICIT mode queries in a simpler, more maintainable way. Question: What does an @ symbol relate to in an XQuery?

18-12

Implementing a Microsoft SQL Server 2008 R2 Database

Retrieving Nested XML

Key Points
The TYPE keyword can be used to return FOR XML sub-queries as xml data type rather than as nvarchar data type.

TYPE Keyword
In the previous topics in this lesson, you have seen how FOR XML AUTO queries can return attribute or element centric XML. If this data is returned from a subquery, it needs to be returned as a specific data type. The FOR XML clause was introduced in SQL Server 2000. That version of SQL Server did not have an xml data type. For that reason, sub-queries with FOR XML clauses had no way to return xml. FOR XML subqueries in SQL Server 2000 returned nvarchar data type instead. SQL Server 2005 introduced the xml data type but for backward compatibility, the data type for return values from FOR XML subqueries was not changed to xml. However, a new keyword TYPE was introduced that changes the return data type of FOR XML sub-queries to xml. For example, look at the following query:
SELECT Customer.CustomerID, Customer.TerritoryID, (SELECT SalesOrderID, [Status] FROM Sales.SalesOrderHeader AS soh WHERE Customer.CustomerID = soh.CustomerID FOR XML AUTO) as Orders FROM Sales.Customer as Customer WHERE EXISTS(SELECT 1 FROM Sales.SalesOrderHeader AS soh WHERE soh.CustomerID = Customer.CustomerID) ORDER BY Customer.CustomerID;

When executed in SQL Server Management Studio, this query returns:

Querying XML Data in SQL Server

18-13

Note that the Orders column is not hyperlinked. XML data type columns are hyperlinked in SQL Server Management Studio. Now look at the following modified query:
SELECT Customer.CustomerID, Customer.TerritoryID, (SELECT SalesOrderID, [Status] FROM Sales.SalesOrderHeader AS soh WHERE Customer.CustomerID = soh.CustomerID FOR XML AUTO, TYPE) as Orders FROM Sales.Customer as Customer WHERE EXISTS(SELECT 1 FROM Sales.SalesOrderHeader AS soh WHERE soh.CustomerID = Customer.CustomerID) ORDER BY Customer.CustomerID;

When executed in SQL Server Management Studio, this returns the following results:

Note that the Orders column now is hyperlinked like other xml data type columns. The example on the slide is a common use case where elements and attributes are mixed to define hierarchies in FOR XML. Question: Why is hyperlinking of XML columns in SSMS useful?

18-14

Implementing a Microsoft SQL Server 2008 R2 Database

Demonstration 1A: FOR XML Queries

Key Points
In this demonstration you will see: How to retrieve XML in RAW mode How to retrieve XML in AUTO mode How to retrieve XML in EXPLICIT mode How to retrieve XML in PATH mode How to use TYPE

Demonstration Steps
1. 2. 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_18_PRJ\6232B_18_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.

3. 4. 5.

Question: When should you use EXPLICIT mode in an XQuery?

Querying XML Data in SQL Server

18-15

Lesson 2

Getting Started with XQuery

In Lesson 1, you learned how to query relational data and return it as XML. Sometimes, however, the data is already in XML and you may need to query it directly. You might want to extract part of the XML into another XML document; you might want to retrieve the value of an element or attribute; you might want to check if an element or attribute exists and finally you might want to directly modify the XML. These tasks are provided for by XQuery methods.

Objectives
After completing this lesson, you will be able to: Explain the role of XQuery? Use the Query Method Use the Value Method Use the Exist Method Use the Modify Method

18-16

Implementing a Microsoft SQL Server 2008 R2 Database

What is XQuery?

Key Points
XQuery is a query language that is designed to query XML documents. It also includes elements of other programming languages such as looping constructs.

XQuery
XQuery was developed by a working group within the Worldwide Web Consortium (W3C). It was developed in conjunction with other work in the W3C, in particular the definition of Extensible Style Sheets (XSLT). XSLT makes use of a subset of XQuery known as XPath. XPath is the syntax used to provide an address for specific attributes and elements within an XML document. You saw basic examples of this when looking at FOR XML PATH mode queries in the last lesson. Look at the following XPath expression:
/InvoiceList/Invoice[@InvoiceNo=1000]

This specifies a need to traverse the InvoiceList node (that is the root element as the expression starts with a slash /), then to the Invoice sub-elements (note that there may be more than one of these) and then to access the InvoiceNo attribute. All invoices with invoice number 1000 are then returned. Note that while you may realize that there is unlikely to be more than one invoice with the number 1000, nothing about XML syntax (without a schema) enforces this. One thing that can be hard to get used to with the XPath syntax is that you constantly need to specify that you want the first entry of a particular type, even though logically you may think that it should be obvious that there would only be one. You indicate the first entry in a set by the expression [1]. In XPath, attributes are indicated by the @ prefix. The content of the element itself is referred to by the token text().

Querying XML Data in SQL Server

18-17

FLWOR Expressions
As well as basic path traversal, XPath supports an iterative expression language known as FLWOR and commonly pronounced as though it was spelled "flower". FLWOR stands for "for, let, where, order, and return" which are the basic operations in a FLWOR query. An example of a FLWOR expression is shown in the following XQuery query() method:
SELECT @xmlDoc.query('<OrderedItems> { for $i in /InvoiceList/Invoice/Items/Item return $i } </OrderedItems>');

This query outputs OrderedItems as an element and then within that element, it locates all items on all invoices contained in the XML document and outputs them as sub-elements of the OrderedItems element. Note that becoming proficient at XQuery is an advanced topic beyond the scope of this course. The aim of this lesson is to make you basically aware of what is possible when using XQuery methods. The available XQuery methods are shown in the following table: Method query() value() exist() modify() nodes() Function Returns selected XML data Retrieves a specific value from an element or attribute Checks for the existence of an element or attribute Performs insert, replace or delete operations Shreds XML data to relational format

The nodes() method will be covered in the next lesson that discusses shredding XML to relational data. Question: Why do you think it is important to learn XPath query language?

18-18

Implementing a Microsoft SQL Server 2008 R2 Database

query() Method

Key Points
The query() method is used to extract XML from an existing XML document. The output XML can be a subset of the original XML document or entirely new XML can be generated based on the values contained in the original XML document.

query() Method
The query() method is used to return untyped XML. It takes an XQuery expression that evaluates to a list of XML nodes and allows the users to create output XML based in some way on the fragments it extracts from the input XML. An XQuery expression in SQL Server consists of two sections a prolog and a body. The prolog can contain a namespace declaration. You will see how to do this later in this module. The body of an XQuery expression contains query expressions that define the result of the query. It is important to understand that both the input and output of a query() method are XML. Note that if NULL is passed to a query() method, the result returned by the method is also NULL.

Example of query() Method


Look at the query shown in the slide:
SELECT XmlEvent.query( '<EventSPIDs> { for $e in /EVENT_INSTANCE return <SPID> {number($e/SPID[1])} </SPID> } </EventSPIDs>') FROM dbo.DatabaseLog;

Querying XML Data in SQL Server

18-19

This query tells SQL Server to return one xml value for each row in the dbo.DatabaseLog table. The xml value returned for each row will have a root element called EventSPIDs. For each EVENT_INSTANCE node that is contained in the XmlEvent column within each row, a sub-element named SPID should be returned. The contents of that node will be the value of the first SPID sub-element of the EVENT_INSTANCE node returned as a number. You will see how this works in the following demonstration.

18-20

Implementing a Microsoft SQL Server 2008 R2 Database

value() Method

Key Points
The value() method is useful for extracting scalar values from XML documents as a relational value. This method takes an XQuery expression that identifies a single node and the desired SQL type to be returned. The value of the XML node is returned cast to the specified SQL type.

value() Method
The purpose of the value() method shown in the slide example is to navigate to the ProductModelID attributes of the ProductDescription element. Note the use of the expression [1] to specify that the first of these is retrieved and returned as an integer with the alias Result. Do not be too concerned with the namespace declaration in the example shown in the slide. It is only specified as the example is working with typed XML. You will see more about namespaces later in this module.

Example Output
You can see the output from this query below:

Note again that if NULL is passed to the value() method, NULL will be returned.

Querying XML Data in SQL Server

18-21

exist() Method

Key Points
Use the exist() method to check for the existence of a specified value.

exist() Method
The exist() method allows the user to perform checks on XML documents to determine if the result of an XQuery expression is empty or nonempty. The result of this method is: 1 if the XQuery expression returns a nonempty result 0 if the result is empty, and NULL if the XML instance itself is NULL

For better performance, use the exist() method on the XML data type, whenever possible, instead of the value() method. The exist() method is most helpful when used in a SQL WHERE clause and utilizes XML indexes more effectively than the value() method.

Example Output
The output from the example code in the slide is shown below:

This is a good example of the power of XML methods when used by database administrators. A database log has been used to hold details of all schema changes made to a database. The example query asks SQL Server to return the rows where the type of object affected was a table. You will notice in the output that all events listed are table-related. Question: Why would the exist() method outperform the value() method?

18-22

Implementing a Microsoft SQL Server 2008 R2 Database

modify() Method

Key Points
Data manipulation operations can be performed on an XML instance using the modify() method. The modify() method modifies the contents of an XML document.

modify() Method
You can use the modify() method to alter the content of an xml type variable or column. This method takes an XML data manipulation language (DML) statement to insert, update, or delete nodes from the XML data. The modify() method of the xml data type can only be used in the SET clause of an UPDATE statement. One or more nodes can be inserted, deleted, and updated using the "insert", "delete", and "replace value of" keywords, respectively. Note that unlike the previous methods, an error is returned if NULL is passed to the modify() method.

Supported Actions
The modify() method supports these keywords: Insert adds child nodes to an XML document Replace updates a node in an XML document Delete removes a node from the XML document

Slide Example

In the insert example shown in the slide, a new SalesPerson node with the text() of Bill is inserted into the first position of the first invoice in the list of invoices.

Querying XML Data in SQL Server

18-23

In the replace example shown in the slide, the SalesPerson's name is replaced by Ted.

In the delete example shown in the slide, the SalesPerson sub-element would be removed from the InvoiceList/Invoice path.

18-24

Implementing a Microsoft SQL Server 2008 R2 Database

Demonstration 2A: XQuery Methods in a DDL Trigger

Key Points
In this demonstration you will see how to use XQuery in DDL triggers.

Demonstration Steps
1. 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_18_PRJ\6232B_18_PRJ.ssmssln and click Open. Open and execute the 00 Setup.sql script file from within Solution Explorer.

2. 3.

Open the 21 Demonstration 2A.sql script file. Follow the instructions contained within the comments of the script file.

Question: Suggest an example of where the ability to create triggers on DDL statements would be useful.

Querying XML Data in SQL Server

18-25

Lesson 3

Shredding XML

Another common need that can arise when working with XML data in SQL Server is to be able to extract relational data from within an XML document. For example, you might receive a purchase order from a customer in XML format. You need to parse the XML to retrieve the details of the items that you need to supply. The extraction of relational data from within XML documents is referred to as "shredding" the XML documents. There are two basic ways to do this. SQL Server 2000 supported the creation of an in-memory tree that could then be queried with an OPENXML function. While that is still supported, SQL Server 2005 introduced the XQuery nodes() method which in many cases will be an easier way to shred XML data. Besides covering these in this module, you will also see how T-SQL provides a way of simplifying how namespaces are referred to in queries.

Objectives
After completing this lesson, you will be able to: Describe how to shred XML data Use system stored procedures for creating and managing in-memory node trees extracted from XML documents Use the OPENXML function Work with XML namespaces Use the nodes() method

18-26

Implementing a Microsoft SQL Server 2008 R2 Database

Overview of Shredding XML data

Key Points
The first of the methods for shredding XML data that was mentioned was to query an in-memory tree that represents the XML. The system stored procedure sp_xml_preparedocument can be used to create an in-memory node tree from an XML document that will make querying the XML data faster. This allows you to obtain relational data from within the XML document.

Shredding XML
The process for shredding XML is: 1. 2. 3. 4. 5. An XML document is received from a client application. By calling sp_xml_preparedocument, an in-memory node tree gets created, based on the input XML. The OPENXML table-valued function is then used to query the in-memory node tree and extra relational data. The relational data that has been extracted is normally combined with other relational data as part of standard T-SQL queries. Calling sp_xml_removedocument removes the node tree from memory.

The steps in this process will be explored in the following topics.

Querying XML Data in SQL Server

18-27

Stored Procedures for Managing In-Memory Node Trees

Key Points
Before you can use the OPENXML functionality to navigate over XML documents, you need to create an in-memory node tree. This is done via the sp_xml_preparedocument system stored procedure.

sp_xml_preparedocument
sp_xml_preparedocument is a system stored procedure that takes XML either as the xml data type or as xml stored in the nvarchar data type, creates an in-memory node tree from the XML (to make it easier to navigate), and returns a handle to that node tree. sp_xml_preparedocument reads the XML text provided as input, parses the text by using the Microsoft XML Core Services (MSXML) parser (Msxmlsql.dll), and provides the parsed document in a state ready for consumption. This parsed document is a tree representation of the various nodes in the XML document: elements, attributes, text, comments, and so on. Before calling sp_xml_preparedocument, you need to declare an integer variable to be passed as an output parameter to the procedure call. When the call returns, the variable will then be holding a handle to the node-tree. It is important to realize that the node tree must stay available and unmoved in visible memory because the handle is basically a pointer that needs to remain valid. This means that on 32 bit systems, the node tree will not be able to be stored in AWE memory.

sp_xml_removedocument
sp_xml_removedocument is a system stored procedure that frees the memory occupied by a node tree and invalidates the handle. In SQL Server 2000, sp_xml_preparedocument created a node tree that was session-scoped, that is, the node tree remained in memory until the session ended or until sp_xml_removedocument was called. A common coding error was to forget to call sp_xml_removedocument. Allowing too many node trees to

18-28

Implementing a Microsoft SQL Server 2008 R2 Database

remain in memory was known to cause severe lack of available low-address memory on 32-bit systems. Because of this, a change was made in SQL Server 2005 that made the node trees created by sp_xml_preparedocument to become batch-scoped rather than session-scoped. Even though the tree will be removed at the end of the batch, it is considered good practice to explicitly call sp_xml_removedocument to minimize the use of low-address memory as much as possible. Note that 64-bit systems generally do not have the same memory limitations anyway.

Querying XML Data in SQL Server

18-29

OPENXML

Key Points
OPENXML provides a rowset over in-memory XML documents, which is similar to a table or a view. OPENXML allows access to the XML data as though it is a relational rowset. It does this by providing a rowset view of the internal representation of an XML document.

OPENXML
After you have created an in-memory node tree of an XML document using sp_xml_preparedocument, you can use OPENXML to write queries against the document. For example, you might need to extract a list of products that you need to supply to a customer from an XML-based order that the customer sent to you. OPENXML provides a rowset view of the document, based on the parameters passed to it. The parameters passed to OPENXML are the XML document handle, a rowpattern, which is an XPath expression that maps the nodes of XML data to rows, and an indication of whether or not to use attributes by default rather than elements. Associated with the OPENXML clause is a WITH clause that provides a mapping between the rowset columns and the XML nodes. The ColPattern shown is an optional, generic XPath pattern that describes how the XML nodes should be mapped to the columns. If ColPattern is not specified, the default mapping (attribute-centric or elementcentric mapping as specified by flags) takes place.

18-30

Implementing a Microsoft SQL Server 2008 R2 Database

Working with XML Namespaces

Key Points
In the previous module, you saw how an XML namespace is a collection of names that can be used as element or attribute names in an XML document. The namespace qualifies names uniquely to avoid naming conflicts with other elements with the same name.

Working with XML Namespaces


When calling sp_xml_preparedocument, if you are working with XML that contains embedded namespaces, you can specify an optional parameter that specifies the namespaces used. You can then use the namespace prefixes in the XPath expressions used within OPENXML. In the example on the slide, note how the alias "o" has been assigned to the XML namespace "urn:AW_OrderNS". That alias is then used throughout the document when an element that is defined in that namespace is used.

Querying XML Data in SQL Server

18-31

nodes() Method

Key Points
The nodes() method provides a much easier way to shred XML into relational data than OPENXML and its associated system stored procedures.

nodes() Method
The nodes() method is an XQuery method and is useful when you want to shred an xml data type instance into relational data. It is a table-valued function that allows you to identify nodes that will be mapped into a new row. Every xml data type instance has an implicitly provided context node. For the XML instance stored in a column or a variable, this is the document node. The document node is the implicit node at the top of every xml data type instance. The result of the nodes() method is a rowset that contains logical copies of the original XML instances. In these logical copies, the context node of every row instance is set to one of the nodes identified with the query expression. This enables subsequent queries to navigate relative to these context nodes. It is important to be careful about the query plans generated when using the nodes() method. In particular, no cardinality estimates are available when using this method. This has the potential to lead to poor query plans. In some cases, the cardinality is simply estimated to be a fixed value of 10,000 rows. This might cause an inappropriate query plan to be generated if your XML document contained only a handful of nodes.

CROSS APPLY and Table-valued Function


The nodes() method is a table-valued function that is normally called via the CROSS APPLY or OUTER APPLY operations. APPLY operations cause table-valued functions to be called for each row in the left-hand table of the query. Look at the query from the example in the slide:

18-32

Implementing a Microsoft SQL Server 2008 R2 Database

SELECT EventDetail.value('PostTime[1]','datetime2') AS PostTime, EventDetail.value('SPID[1]', 'int') AS SPID, EventDetail.value('ObjectType[1]','sysname') AS ObjectType, EventDetail.value('ObjectName[1]','sysname') AS ObjectName FROM dbo.DatabaseLog AS dl CROSS APPLY dl.XmlEvent.nodes('/EVENT_INSTANCE') AS EventInfo(EventDetail) ORDER BY PostTime;

In this query, for every row in the dbo.DatabaseLog table, the nodes() method is called on the XmlEvent column from the dbo.DatabaseLog table. When table-valued functions are used in queries like this, an alias must be provided for both the derived table and the columns it contains. In this case, the alias provided to the derived table is EventInfo and the alias provided to the extracted column is EventDetail. One output row is being returned for each node at the level of the XPath expression "/EVENT_INSTANCE". From the returned XML column (EventDetail), a series of columns is generated by calling the value() method. Note that it is called four times for each output row in this example. Also note that the path to the value to be returned and the data type of that value are being specified along with output column aliases. When executed, the above query returns the following output:

Question: When would it make sense to use OPENXML rather than the nodes() method for shredding XML data to relational format?

Querying XML Data in SQL Server

18-33

Demonstration 3A: Shredding XML

Key Points
In this demonstration you will see how to shred XML data using the nodes() method.

Demonstration Steps
1. 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_18_PRJ\6232B_18_PRJ.ssmssln and click Open. Open and execute the 00 Setup.sql script file from within Solution Explorer.

2. 3.

Open the 31 Demonstration 3A.sql script file. Follow the instructions contained within the comments of the script file.

18-34

Implementing a Microsoft SQL Server 2008 R2 Database

Lab 18: Querying XML Data 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. 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: 4. 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.

5. 6. 7.

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.

Querying XML Data in SQL Server

18-35

Log on using the following credentials: i. ii. User name: AdventureWorks\Administrator Password: Pa$$w0rd

8. 9. 10. 11. 12. 13. 14. 15.

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_18_PRJ\6232B_18_PRJ.ssmssln. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.

Lab Scenario
In this lab, you will investigate several ways in which XML data can be used in SQL Server. You will query relational data and return it as XML and also process existing XML data using T-SQL. If you have time, your manager has an additional task for you. A new web service is being added to the marketing system. You need to create a stored procedure that will query data from a table and return it as an XML value.

Supporting Documentation Stored Procedure Specifications


Stored Procedure Input Parameters: Output Parameters: Returned Rows: WebStock.GetAvailableModelsAsXML None None One XML document with attribute-centric XML. Root element is AvailableModels. Row element is AvailableModel. Row contains ProductID, ProductName, ListPrice, Color and SellStartDate (from Marketing.Product) and ProductModelID and ProductModel (from Marketing.ProductModel) for rows where there is a SellStartDate but not yet a SellEndDate. Rows within the XML should be in order of SellStartDate ascending and then ProductName ascending. That is, sort by SellStartDate first and then ProductName within SellStartDate.

Output Order:

18-36

Implementing a Microsoft SQL Server 2008 R2 Database

Stored Procedure: Marketing.UpdateSalesTerritoriesByXML


Stored Procedure Input Parameters: Output Parameters: Returned Rows: Actions: Marketing.UpdateSalesTerritoriesByXML @SalespersonMods xml None None Update the SalesTerritoryID column in the Marketing.Salesperson table based upon the SalesTerritoryID values extracted from the input parameter.

Incoming XML object format:


<SalespersonMods> <SalespersonMod SalespersonID="274"> <Mods> <Mod SalesTerritoryID="3"/> </Mods> </SalespersonMod> <SalespersonMod SalespersonID="278"> <Mods> <Mod SalesTerritoryID="4"/> </Mods> </SalespersonMod> </SalespersonMods>

Querying XML Data in SQL Server

18-37

Exercise 1: Learn to query SQL Server data as XML


Scenario
In this exercise, you have decided to learn to query SQL Server data to return XML. You will review and execute scripts that demonstrate the most important FOR XML querying techniques. The main tasks for this exercise are as follows: 1. Review and execute the query and review the results

Task 1: Review and execute the query and review the results
Review the query, execute the query and review the results for scripts 18.1 to 18.9 Results: After this exercise, you have executed queries that return SQL Server relational data as XML.

18-38

Implementing a Microsoft SQL Server 2008 R2 Database

Exercise 2: Write a stored procedure returning XML


Scenario
In this exercise, a new web service is being added to the marketing system. You need to create a stored procedure that will query data from a table and return it as an XML value. The main tasks for this exercise are as follows: 1. 2. 3. Review the requirements Create the stored procedure Test the stored procedure

Task 1: Review the requirements


Review the supporting documentation for details of the required stored procedure WebStock.GetAvailableModelsAsXML

Task 2: Create the stored procedure


Create and implement the stored procedure based on the specifications provided

Task 3: Test the stored procedure


Test the stored procedure by executing the following code:
EXEC WebStock.GetAvailableModelsAsXML;

Results: After this exercise, you should have created and tested the required stored procedure that returns XML.

Querying XML Data in SQL Server

18-39

Challenge Exercise 3: Write a stored procedure that updates using XML (Only if time permits)
Scenario
In this exercise, the reassignment of salesperson territories is done by an external management system. When it completes reassignments, it sends an XML document containing the changes. You need to construct a stored procedure Marketing.UpdateSalesTerritoriesByXML that can process this XML and use it to update the SalesTerritoryID column in the Marketing.Salesperson table. The main tasks for this exercise are as follows: 1. 2. 3. Review the requirements Create the stored procedure Test the stored procedure and ensure the updates have been applied

Task 1: Review the requirements


Review the supporting documentation for details of the required stored procedure Marketing.UpdateSalesTerritoriesByXML

Task 2: Create the stored procedure


Create and implement the stored procedure based on the specifications given in the supporting documentation for the lab

Task 3: Test the stored procedure


Test the stored procedure by executing the following code:
DECLARE @SalespersonMods xml; SET @SalespersonMods = '<SalespersonMods> <SalespersonMod SalespersonID="274"> <Mods> <Mod SalesTerritoryID="3"/> </Mods> </SalespersonMod> <SalespersonMod SalespersonID="278"> <Mods> <Mod SalesTerritoryID="4"/> </Mods> </SalespersonMod> </SalespersonMods>'; EXEC Marketing.UpdateSalesTerritoriesByXML @SalespersonMods; GO SELECT * FROM Marketing.Salesperson; GO

Results: After this exercise, you should have created and tested the required stored procedure that updates XML.

18-40

Implementing a Microsoft SQL Server 2008 R2 Database

Module Review and Takeaways

Review Questions
1. 2. 3. 4. What are AUTO mode queries? What are PATH mode queries? What does the nodes() method do? What are RAW mode queries?

Best Practices
1. 2. 3. Convert existing code that uses the nvarchar data type for XML parameters to use the XML data type. Provide meaningful row names when using RAW mode by using the optional name parameter to the RAW clause. Check the query plans for queries using the nodes() method to ensure that the lack of cardinality estimates is not producing a poor execution plan.

Working with SQL Server 2008 R2 Spatial Data

19-1

Module 19
Working with SQL Server 2008 R2 Spatial Data
Contents:
Lesson 1: Introduction to Spatial Data Lesson 2: Working with SQL Server Spatial Data Types Lesson 3: Using Spatial Data in Applications Lab 19: Working with SQL Server Spatial Data 19-3 19-13 19-27 19-38

19-2

Implementing a Microsoft SQL Server 2008 R2 Database

Module Overview

Business applications routinely deal with addresses and locations, yet they rarely provide effective ways to process distances and proximity. Spatial data in SQL Server allows for effective storage and processing of locations, addresses, and shapes. This capability can help business make better decisions and can also be used to help visualize results, which often makes results easier to interpret.

Objectives
After completing this module, you will be able to: Describe the importance of spatial data and the industry standards related to it Explain how to store spatial data in SQL Server Perform calculations on and query SQL Server spatial data

Working with SQL Server 2008 R2 Spatial Data

19-3

Lesson 1

Introduction to Spatial Data

Before starting to work with spatial data, it is important to gain an understanding of where it is typically used in applications, along with an understanding of the different types of spatial data. Most business applications need to work with addresses or locations. SQL Server can process both planar and geodetic data. It is important to understand the difference between these two types of data as well as how the SQL Server data types relate to the relevant industry standards and measurement systems.

Objectives
After completing this lesson, you will be able to: Explain how spatial data is useful in a wide variety of business applications Describe the different types of spatial data Describe the difference between planar and geodetic data types Explain the relationship between the SQL Server spatial data support and the industry standards Work with spatial reference identifiers to provide measurement systems

19-4

Implementing a Microsoft SQL Server 2008 R2 Database

Target Applications

Key Points
There is a perception that spatial data is not useful in mainstream applications. This is an invalid perception as almost every business application can benefit from the use of spatial data.

Business Applications
While mapping provides an interesting visualization in some cases, business applications can make good use of spatial data for much more routine tasks. Consider how many business applications you have seen that do not involve storing addresses or locations. Customers or clients have street addresses, mailing addresses, and delivery addresses. The same is true for stores, offices, suppliers, and many other business-related entities.

Business Intelligence Applications


A particularly strong use of spatial data comes when it is combined with Business Intelligence applications. These applications often deal with results that are best visualized rather than being presented as tables of numbers. Spatial capabilities make it possible to provide very rich forms of visualization.

Common Business Questions


Consider a pet accessories supply company. They have stores all over the country. They know where their stores are and they know where their customers live. The owner has a feeling though that the company's customers are not buying from their nearest store but the owner also has no firm facts to base this feeling on. It could be true that customers really do purchase from their local store. The owner may have just come across a small sample of data and been misled by it. It could also be true that customers don't purchase from their local stores. If so, it might be interesting to know what they purchase when they travel to another store. Perhaps the local store doesn't hold a wide

Working with SQL Server 2008 R2 Spatial Data

19-5

enough variety of stock. Perhaps instead, the customers purchase everything they need from a more remote store as they don't like the staff at the local store. It is important to realize though that these sorts of questions are normal business questions, not specialized mapping questions. This is the sort of problem you can solve quite easily if you are able to process spatial data in a database.

19-6

Implementing a Microsoft SQL Server 2008 R2 Database

Types of Spatial Data

Key Points
In the spatial data community, several types of spatial data are used. SQL Server works with vector-based 2D data but has some storage options for 3D values.

Vector vs Raster Data


Spatial data could be stored as either a series of line segments that together form an overall shape (vector storage) or as a series of dots or pixels that are formed by dividing a shape into smaller pieces (raster storage). Vector storage is the method that SQL Server spatial data is based upon. One key advantage of vector-based storage is the way that it can scale. Imagine storing the details of a line. You could divide the line into a series of dots that make up the line. However, if you then zoom in into an image of the line, the individual dots would then become visible, along with the gaps between the dots. This is how raster-based storage works. Alternately, if the line was stored as the coordinates of the start and end points of the line, no matter how much you zoom in or out, the line would still look complete. This is because it would effectively be redrawn at each level of magnification. This is how vector-based storage works.

2D, 3D, 4D
You are likely familiar with seeing drawings or maps on paper that are two dimensional in nature. A third dimension would represent the elevation of a point on the map. 4D systems usually incorporate changes in a shape over time. SQL Server spatial data is currently based on the 2D technology. In some of the objects and properties it provides, SQL Server spatial data supports storing and retrieving of 3D values but it is important to realize that the third dimension is ignored during calculations. This means that if you calculate the distance between say a point and a building, the calculated distance is the same regardless of which floor or level in the building the point is located.

Working with SQL Server 2008 R2 Spatial Data

19-7

Question: Which existing SQL Server data type could be used to store (but not directly process) raster data?

19-8

Implementing a Microsoft SQL Server 2008 R2 Database

Planar vs. Geodetic

Key Points
Planar systems represent the Earth as a flat surface. Geodetic systems represent the Earth more like its actual shape.

Planar Systems
Prior to the advent of computer systems, it was very difficult to perform calculations on round models of the Earth. For convenience, mapping tended to be two dimensional in nature. Most people are familiar with traditional flat maps of the world. As soon as larger distances are involved, however, flat maps provide a significant distortion, particularly as you move from the center of the map. When most of the standard maps from atlases were first drawn, they also were oriented around where the people drawing them lived. That way, the least distortion occurred where the people that were using the maps were based. As an example, in the flat map shown, it isnt obvious how Africas area (about 30 million square kilometers) compares to North Americas area (about 24 million square kilometers). Also, compare Antarcticas size on the map and note that it is really only about 13 million square kilometers in size.

Geodetic Systems
Geodetic systems represent the Earth in a round shape. Some systems use simple spheres but it is important to realize that the Earth is not actually spherical. SQL Server spatial data offers a number of systems for representing the shape of the Earth. Most systems model the Earth as an ellipsoid rather than as a sphere. Question: What is the difference between an ellipsoid and a sphere?

Working with SQL Server 2008 R2 Spatial Data

19-9

OGC Object Hierarchy

Key Points
The Open Geospatial Consortium (OGC) is the industry body that provides specifications for how spatial data processing should occur in SQL-based systems.

SQL Specification
One of the two data types that SQL Server provides is the geometry data type. It conforms to the OGC Simple Features for SQL Specification 1.0 and is used for planar spatial data. Besides defining how the data should be stored, the specification details common properties and methods to be applied to the data. The OGC defines a series of data types that form an object tree. In the chart shown in the slide, the objects that are supported and can be created in SQL Server spatial data are shown in blue (or the darker color). Other objects in the OGC Geometry hierarchy are shown in yellow (or the lighter color). It is likely that future versions of SQL Server will expand this coverage of OGC objects.

Extensions
SQL Server also extends the standards in a number of ways. A round-Earth data type called geography has also been provided, along with a number of additional useful properties and methods. Methods and properties that are related to the OGC standard have been defined with an ST prefix (such as STDistance) and those without an ST prefix are Microsoft extensions to the standard (such as MakeValid).

19-10

Implementing a Microsoft SQL Server 2008 R2 Database

Spatial Reference Identifiers

Key Points
Many systems of measurement have existed over time. SQL Server supports many of these measurement systems directly. When you specify a spatial data type in SQL Server, you also specify the measurement system to be used. You specify this by associating a spatial reference ID with the data. A spatial reference ID of zero indicates the lack of a measurement system. This is commonly used where there is no need for a specific measurement system.

Spatial Reference Systems


Any model of the Earth is an approximation, some models closer to reality than others. SQL Server supports many different Earth models via a series of Spatial Reference Identifiers (SRIDs). Each SRID defines the shape of the Earth model, the authority responsible for maintaining it, the unit of measure used, and a multiplier that determines how the unit of measure could be converted to meters.

SRID 4326
The World Geodetic System (WGS) is commonly used in cartography, geodetics, and navigation. The latest standard is WGS 84 and is best known to most people via the Global Positioning System (GPS). GPS is often used in navigation systems and uses WGS 84 as its coordinate system. WGS 84 support is provided by SRID 4326 in SQL Server spatial data. If you query the list of SRIDs in SQL Server, the entry for SRID 4326 has the following name (formally called the Well-known Text or WKT that is associated with the ID):
GEOGCS["WGS 84", DATUM["World Geodetic System 1984", ELLIPSOID["WGS 84", 6378137, 298.257223563]], PRIMEM["Greenwich", 0], UNIT["Degree", 0.0174532925199433]]

This specifies how WGS 84 models the Earth as an ellipsoid (you can imagine it as a squashed ellipsoid), with its major radius of 6378137 meters at the equator, a flattening of 1 / 298.257223563 (or about 21 kilometers) at the poles, a prime meridian (that is, a starting point for measurement) at Greenwich, and a

Working with SQL Server 2008 R2 Spatial Data

19-11

measurement based on degrees. The starting point at Greenwich is specifically based at the Royal Observatory. The units are shown as degrees and the size of a degree is specified in the final value in the definition. Most geographic data today would be represented by SRID 4326. Question: Do you currently use GPS data in any existing applications within your organization?

19-12

Implementing a Microsoft SQL Server 2008 R2 Database

Demonstration 1A: Spatial Reference Systems

Key Points
In this demonstration you will see: The available spatial reference identifiers The available units of measurement

Demonstration Steps
1. 2. 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_19_PRJ\6232B_19_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.

3. 4. 5.

Working with SQL Server 2008 R2 Spatial Data

19-13

Lesson 2

Working with SQL Server Spatial Data Types

SQL Server supports two spatial data types, geometry and geography, which have been created as system CLR data types. It is important to know how to use each of these data types and how to interchange data using industry standard formats.

Objectives
After completing this lesson, you will be able to: Describe the support provided by SQL Server spatial data Explain how system CLR types differ from user CLR types Use the geometry data type Use the geography data type Work with standard spatial data formats Use OGC methods and properties on spatial data Use Microsoft extensions to the OGC standard when working with spatial data

19-14

Implementing a Microsoft SQL Server 2008 R2 Database

SQL Server Spatial Data

Key Points
SQL Server supplies rich support for spatial data. It provides two data types. The geometry data type is suited to flat Earth (planar) models, and the geography data type is suited for round Earth (geodetic) models.

geometry Data Type


The geometry data type is the SQL Server implementation of the OGC Geometry data type. It supports the majority of the methods and properties of the OGC type plus extensions to the OGC type. The geometry type is used when modeling flat Earth models such as two dimensional diagrams. The geometry data type offers an X- and Y-based coordinate system.

geography Data Type


The geography data type is a Microsoft extension to the OGC standards that is suitable when working with round Earth models such as GPS data. The geography data type works with a Long and Lat (longitude and latitude) coordinate system. Note that although "latitude and longitude" is a commonly-used phrase in the general community, the geographical community uses the terminology in the reverse order. When specifying inputs for geographic data in SQL Server, the longitude value precedes the latitude value.

Additional Support
The Bing Maps software development kit (SDK) has been updated to work closely with SQL Server spatial data. SQL Server Reporting Services 2008 R2 includes a map control that can be used to render spatial data and a wizard to help to configure the map control. The map control is available for reports built using BIDS and for reports built using Report Builder.

Working with SQL Server 2008 R2 Spatial Data

19-15

An application that stores or retrieves spatial data from a SQL Server database needs to be able to work with that data as a spatial data type. To make this possible, a separate installer file (MSI) has been provided as part of the SQL Server 2008 R2 Feature Pack to allow client applications to also make use of the SQL Server spatial data types. The installer is called the "Microsoft System CLR Types for SQL Server 2008 R2". This file is installed on client systems and allows an application on the client to "rehydrate" a geography object that has been read from a SQL Server database into a SqlGeography object within .NET managed code.

ST Prefix
For the properties and methods that are implementations of the OGC standards, an ST prefix has been added to the names of the properties and methods. For example, the X and Y coordinates of a geometry object are provided by STX and STY properties and the Distance calculation is provided by the STDistance method. For Microsoft extensions to the OGC standards, no prefix has been added to the name of the methods or properties. As an example, there is a MakeValid method. Care must also be taken when referring to properties and methods as they are case sensitive, even on servers that are configured for case insensitivity. Question: You may have used a web service to calculate the coordinates of an address. What is this process commonly called?

19-16

Implementing a Microsoft SQL Server 2008 R2 Database

System vs. User SQL CLR Types

Key Points
The geometry and geography data types have been implemented as CLR types using managed code. They are defined as system CLR types and work even when CLR integration is not enabled at the SQL Server instance level.

System CLR Types


SQL Server 2005 introduced the concept of a CLR user-defined data type, for data types implemented in managed code. CLR data types in SQL Server 2005 were limited in size. They needed to be capable of being serialized into 8 KB of storage (they needed to fit in one SQL Server data page). SQL Server 2008 introduced the concept of a system CLR data type, separate from the user-defined data types but also implemented in managed code. SQL Server 2008 also replaced the 8 KB limit on serialization with a 2 GB limit. This increased limit makes it possible to create complex data types using managed code. In SQL Server 2008 R2, there are three system CLR data types that take advantage of this large data type support: geometry, geography, and hierarchyid. Unlike user-defined CLR data types, these system data types operate even when the 'clr enabled' setting for the server instance is disabled. You can see the currently installed assemblies and whether or not they are user-defined by executing the following query:
SELECT name, assembly_id, permission_set_desc, is_user_defined FROM sys.assemblies;

Working with SQL Server 2008 R2 Spatial Data

19-17

Accessing Properties and Methods


You can access a property of an instance of a spatial data type by referring to it as Instance.Property. As an example of this, look at the following code that is accessing the STX property of a variable called @Location:
SELECT @Location.STX;

You can access a method of an instance of a spatial data type by referring to it as Instance.Method(). As an example of this, look at the following code that is calling the MakeValid method of a variable called @InputLocation:
SELECT @Location = @InputLocation.MakeValid();

It is also possible to call methods that are defined on the data types (geometry and geography) rather than on instances (that is, columns or variables) of those types. This is an important distinction. As an example of this, look at the following code that is calling the GeomFromText method of the geometry data type:
SELECT @Location = geometry::STGeomFromText('POINT (12 15)',0);

Note that you are not calling the method on a column or variable of type geometry but on the geometry type itself. In .NET terminology, this would be referred to as calling a public static method on the geometry class. Note also that the methods and properties of the spatial data types are case-sensitive, even on servers configured with case-insensitive default collations.

19-18

Implementing a Microsoft SQL Server 2008 R2 Database

geometry Data Type

Key Points
The geometry data type is used for flat Earth (that is, planar) data storage and calculations. It provides comprehensive coverage of the OGC standard.

geometry Data Type


The geometry data type is based on an X and Y coordinate system. It is a 2D data type. In the definition of the type, there is provision for Z (elevation) and M (measure) as well as the X and Y coordinates. The geometry data type allows the Z and M values to be entered and retrieved but it ignores these values when performing calculations. You can see input and output of X, Y, Z, and M in the following code:
DECLARE @Location geometry; SELECT @Location = geometry::STGeomFromText('POINT (12 15 2 9)',0); SELECT @Location.STAsText(); SELECT @Location.AsTextZM();

When executed, the above code returns the following results:

Comprehensive coverage of the OGC Geometry data type is provided by the SQL Server geometry data type. The X and Y coordinates are represented by STX and STY properties.

Working with SQL Server 2008 R2 Spatial Data

19-19

SRID and geometry


When working with geometric data, the measurement system is not directly relevant. For example, the area of a shape which is 3 x 2 is still 6 regardless of whether 3 and 2 are in meters or in inches. For this reason, there is no need to specify an SRID when working with geometric data. When inputting data, the SRID value is typically left as zero.

Spatial Results Viewer


Whenever a SQL Server result set is being displayed in SQL Server Management Studio and the results include columns of geometry or geography data type, a special spatial results viewer tab will also be provided, to allow you to visualize the spatial results.

19-20

Implementing a Microsoft SQL Server 2008 R2 Database

geography Data Type

Key Points
The geography data type is used for round Earth values, typically involving actual positions or locations on the Earth. It is an extension to the OGC standard.

geography Data Type


The geography data type is based on a latitude and longitude coordinate system. The latitude and longitude values are represented by the Lat and Long properties. Unlike the geometry data type where the X and Y coordinates can be any valid number, the Lat and Long properties must relate to valid latitudes and longitudes for the selected spatial reference system. 4326 (or WGS 84) is the most commonly used spatial reference system when working with the geography data type. The geography data type can also store but not process Z and M values.

Result Size Limitations


In the SQL Server 2008 implementation of the geography data type, any resulting geography value must be contained within a single hemisphere. This does not mean any specific hemisphere such as the northern or southern hemispheres but just that no two points can be more than half the Earth apart if they are contained in the same instance of the geography data type.

Point Order in Polygons


When defining the shape of a polygon via a series of points, the order in which the points are provided matters. Imagine the set of points that define a postal code region. The same set of points actually defines two regions: all the points inside the postal code region and all the points outside the postal code region. To enclose points, they are listed in anti-clockwise order. As you draw a shape, all the points to the left of the line that you draw will be enclosed by the shape. The points on the line are also included.

Working with SQL Server 2008 R2 Spatial Data

19-21

If you draw a postal code region in a clockwise direction, you are defining all points outside the region. Because results are not permitted to span more than a single hemisphere, an error would then be returned.

Spatial Results Viewer


As discussed in the previous topic, a spatial results viewer will be provided whenever a result set is displayed in SQL Server Management Studio and the results include either geometry or geography data. For geography, the viewer is quite configurable. You can set which column to display, the geographic projection to use for display (for example, Mercator, Bonne, etc.), and you can choose to display another column as a label over the relevant displayed region. The spatial results viewer in SQL Server Management Studio in SQL Server 2008 R2 is limited to displaying the first 5000 objects from the result set.

19-22

Implementing a Microsoft SQL Server 2008 R2 Database

Spatial Data Formats

Key Points
The internal binary format of any CLR data type is not directly used for input and output of the data type in most cases. String-based representations of the data need to be accommodated.

CLR Data Type Representation


CLR data types (including the geometry and geography system CLR data types) are stored in a binary format determined by the designer of the data type. While it is possible to both input and output instances of the data type using a binary string, this is not typically very helpful as you would need to have a detailed understanding of the internal binary format. All CLR data types must implement two string-related methods. The Parse method is used to convert a string to the data type and the ToString method is used to convert the data type back to a string. Both methods are implemented in the spatial types and you will see how they are implemented shortly.

Spatial Data Formats


The OGC and other organizations that work with spatial data define a number of formats that can be used for interchanging spatial data. Some of the formats that SQL Server supports are: Well-known Text (WKT) is the most common string format and is quite human-readable. Well-known Binary (WKB) is a more compact binary representation that is useful for computer to computer interchange. Geography Markup Language (GML) is the XML-based representation for spatial data.

Note that the Parse method is implemented and assumes that the input is in WKT format. The ToString method is also implemented and also assumes the WKT format. There are a number of variations of these methods used for input and output. As an example, the STAsText method provides a specific WKT format as output and the AsTextZM method is a Microsoft extension that provides the Z and M values as well as the 2D coordinates.

Working with SQL Server 2008 R2 Spatial Data

19-23

Question: Why is there a need to represent spatial data types as strings within SQL Server?

19-24

Implementing a Microsoft SQL Server 2008 R2 Database

OGC Methods and Properties

Key Points
A wide variety of OGC methods and properties has been provided in SQL Server spatial data, along with a number of OGC defined collections. Several of the common methods and properties are described here but many more exist.

Common Methods
The STDistance method returns the distance between two spatial objects. Note that this does not only apply to points. The distance between two polygons can also be calculated. It is returned as the minimum distance between any two points on the polygons. The STIntersects method returns 1 when two objects intersect and 0 otherwise. The STArea method returns the total surface area of a geometry instance. The STLength method returns the total length of the objects in a geometry instance. For example, with a polygon, STLength returns the total length of all line segments that make up the polygon. The STUnion method returns a new object that is formed by uniting all points from two objects. The STBuffer method returns an object whose points are within a certain distance of an instance of a geometry object.

Common Collection Properties


Support has also been provided in SQL Server for a number of collections defined in the OGC specifications. A GeometryCollection can be held in a geometry object and can contain a number of other nested geometry objects. Properties such as STNumGeometries and STGeometryN provide access to the members of these collections.

Working with SQL Server 2008 R2 Spatial Data

19-25

Microsoft Extensions

Key Points
Besides the OGC properties and methods, Microsoft has provided a number of useful extensions to the standards. Several of these extensions are described in this topic but many more exist.

Common Extensions
While the coverage provided by the OGC specifications is good, Microsoft has enhanced the data types by adding properties and methods that extend the standards. Note that the extended methods and properties do not have the ST prefix. The MakeValid method takes an arbitrary shape and returns another shape that is valid for storage in a geometry data type. SQL Server produces only valid geometry instances, but allows for the storage and retrieval of invalid instances. A valid instance representing the same point set of any invalid instance can then be retrieved using the MakeValid method. The Reduce method is used to reduce the complexity of an object while attempting to maintain the overall shape of the object. The IsNull method returns 1 if an instance of a spatial type is NULL; otherwise it returns 0. The AsGML method returns the object encoded as Geographic Markup Language (GML). An example of GML is shown here:
<Point xmlns="http://www.opengis.net/gml"> <pos>12 15</pos> </Point>

GML is excellent for information interchange but you can see that the representation of objects in XML can quickly become very large. The BufferWithTolerance method returns a buffer around an object but uses a tolerance value to allow for minor rounding errors.

19-26

Implementing a Microsoft SQL Server 2008 R2 Database

Demonstration 2A: Spatial Data Types

Key Points
In this demonstration you will see how to work with SQL Server spatial data types.

Demonstration Steps
1. 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_19_PRJ\6232B_19_PRJ.ssmssln and click Open. Open and execute the 00 Setup.sql script file from within Solution Explorer.

2. 3.

Open the 21 Demonstration 2A.sql script file. Follow the instructions contained within the comments of the script file.

Working with SQL Server 2008 R2 Spatial Data

19-27

Lesson 3

Using Spatial Data in Applications

Once you have gained an understanding of how spatial data is stored and accessed in SQL Server, it is important to gain an understanding of implementation issues that need to be addressed when building applications that use SQL Server spatial data. In particular, spatial indexes can be created to improve the performance of the applications and an understanding of how spatial indexes work and which methods they are useful for is necessary for building performant applications.

Objectives
After completing this lesson, you will be able to: Describe the need for spatial indexes Explain the basic tessellation process used within SQL Server spatial indexes Describe the different types of spatial indexes Implement spatial indexes Explain which geometry methods can benefit from spatial indexes Explain which geography methods can benefit from spatial indexes Describe options for extending SQL Server spatial data support

19-28

Implementing a Microsoft SQL Server 2008 R2 Database

Performance Issues in Spatial Queries

Key Points
Spatial queries can often involve a very large number of data points. Executing methods like STIntersect for a large number of points is slow. Spatial indexes help avoid unnecessary calculations.

Discussion
Imagine trying to locate the streets that intersect your suburb or region. Question: What is the challenge in locating the intersecting streets? Question: Which streets would you need to check? Question: How could you minimize this problem?

Working with SQL Server 2008 R2 Spatial Data

19-29

Tessellation Process

Key Points
Spatial indexes help avoid unnecessary calculations by breaking larger problems down into problems that need to be solved and those that don't need to be solved.

Tessellation
In the example from the discussion where you were considering finding streets that intersect your suburb or region, the biggest problem is that checking every street in the state or worse, in the country, would take a very long time. The irony of this is that almost all of these calculations would return an outcome that showed no intersection. To avoid making unnecessary calculations, SQL Server breaks the problem-space into relevant areas by using a four-level grid. Each grid level is made up of a number of cells. The basic idea is that if your suburb is located within a region of cells, any streets that do not extend into those cells do not need to be checked at all. Grid levels are used to quickly isolate large areas that do not need to be checked. As a real-world human-based example, if you are checking for streets that are part of Vienna, you do not need to check for streets that are contained entirely within Paris. Moreover, you do not need to check any street that is contained entirely within France. You can quickly eliminate those as not being of interest to you.

19-30

Implementing a Microsoft SQL Server 2008 R2 Database

Spatial Indexes

Key Points
Spatial indexes are unlike standard relational indexes. Instead of locating specific rows to be returned, queries that use spatial indexes operate in a two-phase manner. In the first phase, possible candidates are found. In the second phase, the returned list of candidates is individually checked.

Spatial Indexes
When you traverse a clustered or non-clustered index on a SQL Server table, you apply the predicates in the WHERE clause to filter the specific rows. After applying the predicate, you are left with precisely the rows you require. Spatial indexes work differently than this. Instead of precisely locating the specific rows, spatial indexes are used to locate rows that could potentially be of interest. You saw in the last topic how tessellation can be applied to minimize the number of calculations that need to be performed. Spatial indexes use this tessellation process to quickly reduce the overall number of rows to a list of candidate rows that might potentially be of interest. In the street-based example that was mentioned previously, if Vienna was contained inside a grid cell and a street entered that cell, you still do not know if the street actually intersects the boundaries of Vienna. However, you know that you need to check whether or not it does, as it is possible that it might.

Primary and Secondary Filters


Spatial indexes are used as a primary filter on the data. All possible candidate rows are returned by the filter. There may still be false positives after the filter is applied. The secondary filter is used to locate the precise rows of interest. It executes the methods in the WHERE clause of the query on the filtered set of candidate rows. This greatly reduces the number of calculations that SQL Server needs to make as long as the spatial index has been effective. To allow a check on the effectiveness of the primary filter, SQL Server provides a Filter method that only applies to the primary filter. The number of rows returned by that method can then be compared to the

Working with SQL Server 2008 R2 Spatial Data

19-31

total number of rows to see how effective the spatial index has been. This will be shown in an upcoming demonstration.

19-32

Implementing a Microsoft SQL Server 2008 R2 Database

Implementing Spatial Indexes

Key Points
Spatial indexes are created using the CREATE SPATIAL INDEX statement. Indexes on geometry data type should specify a BOUNDING_BOX.

CREATE SPATIAL INDEX


Spatial indexes are created in a similar way as non-clustered indexes. You execute the CREATE SPATIAL INDEX statement, providing a name for the index, the table that the index is to be created on, and the spatial data column that needs to be indexed. The table must have a clustered primary key before a spatial index can be built on it.

Index Bounds
Unlike more traditional types of index, a spatial index is most useful when it knows the overall area that is covered by the spatial data. Spatial indexes created on the geography data type do not need to specify a bounding box as the data type is naturally limited by the Earth itself. Spatial indexes on the geometry data type specify a BOUNDING_BOX. This provides the coordinates of a rectangle that would contain all possible points or shapes of interest to the index. The geometry data type has no natural boundaries and specifying a bounding box allows SQL Server to produce a more useful index. If values arise outside the bounding box coordinates, the rows they are contained in would need to be returned by the primary filter.

Grid Density
SQL Server also allows you to specify grid densities when creating spatial indexes. You specify a value for the number of cells per grid for each grid level in the index. A value of LOW indicates 16 cells per grid or a 4 x 4 cell grid. A value of MEDIUM indicates 64 cells per grid or a 8 x 8 cell grid. A value of HIGH indicates 256 cells per grid or a 16 x 16 cell grid.

Working with SQL Server 2008 R2 Spatial Data

19-33

Spatial indexes are also different from other types of index as it might makes sense to create multiple spatial indexes on the same table and column. Indexes with one set of grid densities might be more useful than a similar index with a different set of grid densities for locating data in a specific query.

Limitations
Spatial indexes do not support the use of ONLINE build operations, as are available for other types of index in the Enterprise Edition of SQL Server.

19-34

Implementing a Microsoft SQL Server 2008 R2 Database

geometry Methods Supported by Spatial Indexes

Key Points
Not all geometry methods and not all predicate forms can benefit from the presence of spatial indexes. The table in the slide shows the specific predicates that can potentially make use of a spatial index as a primary filter. Unless the predicate in your query is in one of these forms, spatial indexes that you create will be ignored.

Working with SQL Server 2008 R2 Spatial Data

19-35

geography Methods Supported by Spatial Indexes

Key Points
Similarly to the geometry type, not all geography methods and not all predicate forms can benefit from the presence of spatial indexes. The table in the slide shows the specific predicates that can potentially make use of a spatial index as a primary filter. Unless the predicate in your query is in one of these forms, spatial indexes that you create will be ignored.

19-36

Implementing a Microsoft SQL Server 2008 R2 Database

Extending SQL Server Spatial

Key Points
A very active community that contributes user-created extensions to SQL Server spatial data exists on the CodePlex site. In the slide, the functions, types, and aggregates that were present in the sqlspatial.codeplex.com project at the time of writing these notes are listed. As the project continues to evolve, the capabilities provided in the project will change. You may be able to use some of these extensions directly. They may also be useful as starting points when creating your own extensions to the SQL Server spatial data.

Working with SQL Server 2008 R2 Spatial Data

19-37

Demonstration 3A: Spatial Data in Applications

Key Points
In this demonstration you will see how to use SQL Server spatial data to solve some business questions.

Demonstration Steps
1. 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_19_PRJ\6232B_19_PRJ.ssmssln and click Open. Open and execute the 00 Setup.sql script file from within Solution Explorer.

2. 3.

Open the 31 Demonstration 3A.sql script file. Follow the instructions contained within the comments of the script file.

19-38

Implementing a Microsoft SQL Server 2008 R2 Database

Lab 19: Working with SQL Server Spatial Data

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. 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: 4. 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.

5. 6. 7.

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.

Working with SQL Server 2008 R2 Spatial Data

19-39

Log on using the following credentials: i. ii. User name: AdventureWorks\Administrator Password: Pa$$w0rd

8. 9. 10. 11. 12. 13. 14. 15.

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_19_PRJ\6232B_19_PRJ.ssmssln. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.

Lab Scenario
Your organization has only recently begun to acquire spatial data within its databases. The new Marketing database was initially designed prior to the company beginning to implement spatial data. One of the developers has provided a table of the locations where prospects live. It is called Marketing.ProspectLocation. A second developer has added columns to it for Latitude and Longitude and geocoded the addresses. You will make some changes to the system to help support the need for spatial data.

Supporting Documentation Stored Procedure Specifications


Stored Procedure Name Input Parameters Marketing.GetNearbyProspects @ProspectID int @DistanceInKms int None Distance (in Kms) ProspectID LastName FirstName WorkPhoneNumber CellPhoneNumber AddressLine1 AddressLine2 City Longitude Latitude Distance

Output Parameters Output Rowset Columns

Output Order

19-40

Implementing a Microsoft SQL Server 2008 R2 Database

Exercise 1: Familiarity With Geometry Data Type


Scenario
In this lab, you have decided to learn to write queries using the geometry data type in SQL Server. You will review and execute scripts that demonstrate querying techniques. The main tasks for this exercise are as follows: 1. Review and execute the sample script

Task 1: Review and execute the sample script


Review the query, execute the query, and review the results for scripts 19.1 to 19.9. Results: After this exercise, you should have seen how to work with the geometry data type.

Working with SQL Server 2008 R2 Spatial Data

19-41

Exercise 2: Adding Spatial Data to an Existing Table


Scenario
In this lab, you need to modify an existing table Marketing.ProspectLocation to replace the existing Latitude and Longitude columns with a new Location column of type geography. You need to migrate the data to the new Location column before you delete the existing Latitude and Longitude columns. The main tasks for this exercise are as follows: 1. 2. 3. Add a Location column Write code to assign values to this column Drop the existing Latitude and Longitude columns

Task 1: Add a Location column


Add a Location column to the Marketing.ProspectLocation table.

Task 2: Write code to assign values to this column


Write code to assign values to this column based on the existing Latitude and Longitude columns.

Task 3: Drop the existing Latitude and Longitude columns


Once you are sure the new column has correct data, drop the existing Latitude and Longitude columns.

Results: After this exercise, you should have replaced the existing Longitude and Latitude columns with a new Location column.

19-42

Implementing a Microsoft SQL Server 2008 R2 Database

Challenge Exercise 3: Business Application of Spatial Data (Only if time permits)


Scenario
Salespeople are keen to visit with prospects at their own locations, rather than just on the phone. To minimize effort, they are keen when visiting a prospect to also see other prospects in the same area. You will write a stored procedure that provides details of other prospects in the area. To ensure it performs quickly, you will create a spatial index on the table. The main tasks for this exercise are as follows: 1. 2. 3. 4. Review the requirements Create a spatial index Design and implement the Stored Procedure Test the procedure

Task 1: Review the requirements


Review the supporting documentation for details of the required stored procedure

Task 2: Create a spatial index


Create a spatial index on the Marketing.ProspectLocation table

Task 3: Design and implement the Stored Procedure


Design and implement the stored procedure based on the specifications given in the supporting documentation for the lab

Task 4: Test the procedure


Test the stored procedure by executing the following code:
EXEC Marketing.GetNearbyProspects 2,50;

Results: After this exercise, you should have created and tested the required stored procedure.

Working with SQL Server 2008 R2 Spatial Data

19-43

Module Review and Takeaways

Review Questions
1. 2. What is the main difference between the geometry and geography data types? Why does the order of points matter when defining a polygon?

Best Practices
1. 2. 3. Set the SRID for geometry objects to 0 to ensure that operations on multiple geometry objects can always be performed. Use a CHECK CONSTRAINT to ensure that the SRID values for a column are consistent across all rows. Before creating spatial indexes, make sure that the queries that need to be executed against the data use predicate forms that are supported by the types of index you are creating.

19-44

Implementing a Microsoft SQL Server 2008 R2 Database

Working with Full-Text Indexes and Queries

20-1

Module 20
Working with Full-Text Indexes and Queries
Contents:
Lesson 1: Introduction to Full-Text Indexing Lesson 2: Implementing Full-Text Indexes in SQL Server Lesson 3: Working with Full-Text Queries Lab 20: Working with Full-Text Indexes and Queries 20-3 20-10 20-21 20-33

20-2

Implementing a Microsoft SQL Server 2008 R2 Database

Module Overview

Existing business applications and the database applications that are associated with them tend to offer very limited options when users need to search for information. Full-text indexing in SQL Server allows you to create very flexible searching options, much more powerful than what is possible with traditional T-SQL language statements alone.

Objectives
After completing this module, you will be able to: Describe why user interfaces in existing applications are not sufficient for end user search needs Implement full-text indexes in SQL Server Query SQL Server using full-text queries

Working with Full-Text Indexes and Queries

20-3

Lesson 1

Introduction to Full-Text Indexing

Most developers feel that their applications provide sufficiently usable search options for end users. This is usually not the case. There is a substantial mismatch between what is being provided to end users and what they really want to use. In this lesson, you will explore this mismatch and see how traditional searching approaches using T-SQL statements such as LIKE are not capable of providing appropriate levels of search capability. You will also investigate the types of queries that users really wish to execute.

Objectives
After completing this lesson, you will be able to: Explain why applications need to offer much more flexible user-interaction options Explain why the T-SQL LIKE statement, while powerful, does not offer the level of flexibility that users really want Execute queries that use SQL Server full-text predicates or table-valued functions.

20-4

Implementing a Microsoft SQL Server 2008 R2 Database

Discussion: The Need for More Flexible User Interaction

Key Points
Spend some time looking at the two simple search screens on the slide. Ask yourself which of these screens you would prefer to interact with. Question: Which type of interface would you prefer? Most people prefer the first search page shown. Why do you think so? IT Professionals tend to like everything they deal with to be exact, precise, and well-structured. Ironically, this is the exact opposite of what most end users prefer. They prefer much more flexible and fuzzy interfaces. Consider the early online mapping engines. When you interacted with those online mapping engines, you needed to enter values into multiple input locations for street number, street name, suburb, country, etc. in contrast to the current online mapping engines. Most online mapping engines today have a single input box where you type what you are looking for. The system then works out whats needed. Question: Why aren't interfaces to business systems built like that?

Working with Full-Text Indexes and Queries

20-5

Why LIKE Isnt Enough

Key Points
The LIKE operator in T-SQL is a very powerful operator that works by finding string values within strings. It applies a pattern-based search. While this can be useful, there is a big difference between searching for substrings and searching for words.

T-SQL LIKE Operator


The most common use for the LIKE operator in T-SQL is to search for substrings within strings. In the example shown on the slide, the search term '%Lee%' is being used. This looks for rows where the FirstName column contains the string 'Lee'. This is not the same as searching for the word Lee. The search also returns rows where the name is Ashlee, Carolee, Colleen, Kathleen, Keylee, Shirleen, Waleed, and Wathalee. Similarly, if a search was made using the term '%Pen%', as well as values containing the word Pen, you would get values such as pencil, pendulum, penitentiary, open, and so on. Question: What is needed to really find the word Pen? To be able to find the word Pen, you would need to have an understanding of 'words'. Question: What would you need to know to be able to find words rather than substrings? Finding words involves much more than searching for strings within other strings. To start with, you would need to have an understanding of punctuation, yet the rules for punctuation differ by language. This means that you would also need to have an understanding of the target languages.

Performance
Another consideration is performance. An index on a column is ignored when you are searching for values using a pattern with a leading % wildcard.

20-6

Implementing a Microsoft SQL Server 2008 R2 Database

Question: Is LIKE case sensitive?

Working with Full-Text Indexes and Queries

20-7

Fuzziness in Queries

Key Points
While being able to find words within columns that you search is useful, effective search needs much more capability than that. End users are looking for much more "fuzzy" concepts when searching.

Query Fuzziness
IT professionals tend to like to work in an exact and precise way with highly defined structure. Ironically, end users want something quite different. They prefer interfaces that are much more flexible and "fuzzy". They often don't know exactly what they are looking for but they know something about it, such as what it was about or some of the key words related to it.

Near
Most users have had the experience of searching for two words and the returned results include documents that contained both words but they were so far apart in the document that the fact that they were both contained in the document was almost meaningless. Ideally, you need a concept of nearness. Often the nearer together two words are, the more relevant the result is. But how do you measure how far apart words are? Full-text indexes in SQL Server understand nearness and also understand more subtle concepts, such as sentence and paragraph breaks. SQL Server knows that two words that are side-by-side in a single sentence are logically closer than two words with a sentence break between them.

Thesaurus
It is common for different people in an organization to call the same object by different names. One person might say "Client" while another says "Customer". Full-text search in SQL Server is capable of being taught that these terms are equivalent. This can be particularly important with companies that are involved in mergers.

20-8

Implementing a Microsoft SQL Server 2008 R2 Database

Inflections
To a human, the words "drive", "drove", and "driving" are really just the same word. If a human was searching for one of these words, they would expect the system to return results containing any of them. This is much harder for computer systems. SQL Server understands inflectional forms of words.

FreeText
End users often do not know what they are looking for but know some information about what the result is related to. For example, if the user wants to find data related to "Attempts to Improve Solar Energy Efficiency", how would you search for that using T-SQL? Full-text indexing and querying in SQL Server allows you to search for results based on semantics (or meaning). This is extremely powerful and directly appeals to end users. Consider how popular existing Internet-based search engines such as Bing are. Users really like this form of search yet very few business applications today provide them with the ability to do searches like this.

Working with Full-Text Indexes and Queries

20-9

Demonstration 1A: Using Full-Text Queries

Key Points
In this demonstration you will see why full-text indexing is important for creating advanced and flexible user interfaces

Demonstration Steps
1. 2. 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_20_PRJ\6232B_20_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.

3. 4. 5.

20-10

Implementing a Microsoft SQL Server 2008 R2 Database

Lesson 2

Implementing Full-Text Indexes in SQL Server

In the previous lesson, you saw how traditional search options based on T-SQL operators such as LIKE provided only limited searching ability. In this lesson, you will learn about the advanced search capabilities and how to implement full-text indexes. Before learning the details of how full-text indexes are implemented, you will also need to gain an understanding of the components of a full-text searching system.

Objectives
After completing this lesson, you will be able to: Describe existing search-related options and their features Discuss specific capabilities of full-text indexes implemented in SQL Server Describe the core components that make up a full-text search system Detail the available languages supported by SQL Server full-text indexing Implement a full-text index in SQL Server

Working with Full-Text Indexes and Queries

20-11

Discussion: Search-related Options

Key Points
There are many existing forms of search available on the Windows operating system platform. Question: Which forms of search are you already familiar with? Question: Describe your experiences (both good and bad) with any form of search. Include your experience with earlier versions of full-text search in SQL Server if you have used it. Full-text search in SQL Server was completely redesigned in SQL Server 2008. In prior versions, SQL Server interfaced with the search capabilities at the operating system level. This led to both management and performance-related challenges. Starting with SQL Server 2008, full-text search has been implemented directly inside the SQL Server engine. This has brought significant benefits in terms of both management and performance. The only components that now live outside the SQL Server engine are the components that can be created or customized by end users and developers. This separation is maintained to ensure stability and security of the SQL Server engine.

20-12

Implementing a Microsoft SQL Server 2008 R2 Database

Full-Text Search in SQL Server

Key Points
Full-text indexing in SQL Server allows for the creation of word-based indexes built on character-based data stored in SQL Server tables.

Data Types
Full-text indexes in SQL Server are created on character-based data. A wide variety of character data types is supported. Single-byte character columns, char and varchar, are supported as well as their double-byte character equivalents, nchar and nvarchar. While creating full-text indexes on text, ntext, and image data types is possible, it is not recommended as these data types have been deprecated and will be removed in a later version of SQL Server. If possible, first convert any text, ntext, and image columns as follows: Old Data Type text ntext image Next, build indexes on those data types. XML data can also be indexed via full-text indexes. XML indexes allow fast access for certain types of XQuery based queries. Full-text indexes on XML allow indexing all the text within the XML. SQL Server knows how to extract character data from a large number of document types that can be stored in varbinary(max) columns. To be able to index these columns, another column in the table must New Data Type varchar(max) nvarchar(max) varbinary(max)

Working with Full-Text Indexes and Queries

20-13

hold the file extension (for example, .TXT) of the document that is being held in the varbinary(max) column.

Full-Text Indexes
Full-text indexes are stored in the database, as other indexes are. Each index is associated with a table that contains the character data being indexed and full-text indexing supports multiple concurrent languages in different columns. Once full-text indexes are created, special query predicates and table-valued functions can be used to provide powerful querying abilities. The table-valued functions are also able to rank results, where appropriate, to provide a measure of how relevant the returned results are. Full-text indexes can be created on textual data in a variety of languages. A significant number of languages are supported by default and it is possible to extend the product by the construction of code to support additional languages. The predicates that are supported by full-text indexes allow users to query using simple words and phrases that are much more familiar to the users.

20-14

Implementing a Microsoft SQL Server 2008 R2 Database

Core Components of Full-Text Search

Key Points
The full-text indexing system is made up of a number of components that are described using specific terminology. It is important to understand the role of each component and to understand the terminology used. iFilters, Word Breakers and Stemmers operate sequentially to extract the words that need to be placed in the index.

iFilter
The first step in indexing character data is to obtain a stream of characters. If the data is being held in a character-based column in a table, this is straightforward. However, if the data is being held in a document stored in a varbinary(max) column, SQL Server needs to know how to extract a stream of characters from that type of document. The filters that perform this action are called iFilters. A significant number of iFilters are provided with SQL Server. SQL Server also supports the concept of adding additional iFilters. You can create user-created iFilters for special types of documents or you can obtain iFilters from companies that create special document types. A common example of this would be to install an iFilter to work with PDF documents.

Word Breaker
Once a stream of characters has been obtained, the next step is to break that stream into a series of words. This involves an understanding of the punctuation and whitespace rules in each language. The output is then a stream of words, rather than a stream of characters.

Stemmer
When a stream of words has been obtained, processing needs to be done to standardize the format of the words. Inflectional forms of the words need to be resolved and verbs conjugated (that is, drive, drove, driving). Together, word breaking and stemming are often called tokenizing.

Working with Full-Text Indexes and Queries

20-15

Noise Word Removal


It is not always desirable to index all the words in a document. Every language has a series of words such as "and" or "the" that do not add value to the index. You can see the list of standard noise words for the English language (which has Windows locale identifier 1033) by executing the query:
SELECT * FROM sys.fulltext_system_stopwords WHERE language_id = 1033;

Note that in recent versions of SQL Server, the term "noise word" has been replaced by the term "stop word". SQL Server also allows you to create stoplists that contain your own stopwords that you do not want to index. A good example of this would be your company name. It is likely that it appears in every document so it would likely add little value to the index. Question: Which among the core components of full-text search are likely to be language-specific?

Indexing, Querying, Scoring


Finally, you then have a list of words to be indexed. SQL Server uses them to construct the full-text index. It is important to understand that, unlike a standard clustered or nonclustered index, full-text indexes are not updated during data modification statements. However, if auto-population is enabled, the full-text indexes are updated shortly after the data modification has been performed. Querying involves using the full-text predicates and table-valued functions to return results. Scoring (also known as ranking) involves providing a measure of relevance of each row in the result set.

iFilter, Word Breaker, Stemmer, and Stopword Example


As a high-level example of the actions performed by the iFilter, Word Breaker, Stemmer and Stopword components, consider the following document:
<Document> <Author>Proseware, Inc.</Author> <Address>19 Proseware Drive, CONTOSO</Address> <Title>Driving Us Broke And Driving Us Crazy</Title> </Document>

An iFilter could be created to extract text from this type of document. The iFilter will output a stream of text. The exact text that is output will depend upon the design of the iFilter but the following output could be obtained:
author - proseware, inc..address - 19 proseware drive, contoso.title - driving us broke and driving us crazy.

Note that this particular iFilter replaces XML element tags with the name of the tag and a dash separator. It also adds a period at the end of each tag, to assist with keeping terms that are related within the same sentence in the output. After a Word Breaker has been applied, the following output could be obtained:
author proseware inc. address 19 proseware drive contoso. title driving us broke and driving us crazy.

After a Stopword list is applied, the following output could be obtained:


author proseware inc. address proseware drive contoso. title driving broke driving crazy.

20-16

Implementing a Microsoft SQL Server 2008 R2 Database

After a Stemmer has been applied, the following output could be obtained:
author proseware inc. address proseware drive contoso. title drive broke driving crazy.

At this point, the words are ready to be inserted into a full-text index. The list of words is different to the original text but is sufficient for indexing the text.

Working with Full-Text Indexes and Queries

20-17

Language Support and Supported Word Breakers

Key Points
A large number of languages are supported by the built-in functionality in SQL Server full-text indexing.

Language Support
You can see from the list of languages presented in the slide how many languages are directly supported by full-text indexing in SQL Server. A full list of the supported languages can be seen by executing the following query:
SELECT * FROM sys.fulltext_languages;

The query returns the Windows locale identifier in a column called lcid and the name of the language. Question: Which of the languages in the list do you need to support in your applications or databases? Note that the three languages shown in red (or in lighter color in monochrome printing) are included with the product but disabled by default. They must be manually registered before they can be used. These language files were provided by third party organizations and were not included in the detailed testing of the SQL Server product so they are shipped in a disabled state.

20-18

Implementing a Microsoft SQL Server 2008 R2 Database

Implementing Full-Text Indexes

Key Points
Creating and querying full-text indexes is not difficult but involves a number of steps.

Table with Character-based Data


Full-text indexes are created on tables in a way that is similar to how non-clustered indexes are created. The table must contain some character-based data from the list of supported data types mentioned earlier.

Full-Text Catalog
Full-text indexes are created within full-text catalogs. This concept is mainly retained for backward compatibility with the earlier versions of SQL Server, when the full-text indexes were created in the operating system rather than directly in the database. While some maintenance operations can still be carried out at the catalog level but in general, most databases do not need more than one full-text catalog. While the CREATE FULLTEXT CATALOG statement includes an option to specify a filegroup, this setting is now ignored. One full-text catalog can be identified as the DEFAULT catalog and will be used for all full-text indexes that are created without specifying a catalog.

Full-Text Index
The full-text index is created using the CREATE FULLTEXT INDEX command. You need to specify a name for the index, the table that it is based upon, and the name of the column that contains the character data. If the character data is contained within a document in a column of type varbinary(max), you also need to specify the name of another column that will hold the name of the type of document. For example, this column could hold values such as '.TXT' and '.DOC'.

Working with Full-Text Indexes and Queries

20-19

You also need to specify which index can be used to uniquely identify rows within the table. This will almost always be the primary key of the table. One full-text index is allowed per table or indexed view, and each full-text index applies to a single table or indexed view.

Populate the Index


Once the index is created, you can manually request SQL Server to start populating it, based on the existing data or you can set the index to be auto-populated. Auto-population is the most common option used. SQL Server tracks the rows that have been changed and updates the index as close to the end of the data modification as possible.

Query the Index


Querying the full-text indexes relates to using the full-text predicates or the full-text table-valued functions in T-SQL queries. In the next lesson, you will see how to use full-text querying capability to return results from the full-text indexes.

20-20

Implementing a Microsoft SQL Server 2008 R2 Database

Demonstration 2A: Implementing Full-Text Indexes

Key Points
In this demonstration you will see: How to create a full-text catalog How to create a full-text index How to check when a full-text index is fully populated

Demonstration Steps
1. 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_20_PRJ\6232B_20_PRJ.ssmssln and click Open. Open and execute the 00 Setup.sql script file from within Solution Explorer.

2. 3.

Open the 21 Demonstration 2A.sql script file. Follow the instructions contained within the comments of the script file.

Working with Full-Text Indexes and Queries

20-21

Lesson 3

Working with Full-Text Queries

The real power of using full-text indexes comes after the index has been built and populated and you begin to execute queries that make use of the index. There are two basic ways to execute queries using full-text indexes. Full-text predicates can be added to WHERE clauses. Alternately, tables of full-text results can be returned and queried or joined to other tables. It is also important to be able to exercise control over which words are included in the index and to use the thesaurus to provide synonyms or replacements for common search terms.

Objectives
After completing this lesson, you will be able to: Write queries using the CONTAINS predicate Write queries using the FREETEXT predicate Return CONTAINS and FREETEXT results as tables along with ranking of relevance Create stopwords and stoplists Add details of synonyms and replacements to a full-text thesaurus Manage and debug full-text indexes

20-22

Implementing a Microsoft SQL Server 2008 R2 Database

CONTAINS Queries

Key Points
Queries using the CONTAINS predicate search for words or combinations of words. They can also perform proximity searches and advanced searches using inflectional forms of words or synonyms and replacements from a thesaurus.

CONTAINS
The CONTAINS predicate is used to search for words. The most basic form of usage is shown in the first example on the slide. The query returns the MessageID and Description columns from the dbo.Messages table for each row where the Description column contains the word 'filing'.

Boolean Logic
Boolean logic can also be applied to search for combinations of words. In the second example shown in the slide, the query is changed so that only rows where the Description column contains the word 'file' but does not also contain the word 'boundary' are returned. The permitted Boolean operators are: AND AND NOT OR

Proximity
The CONTAINS predicate can also search for combinations of words using the NEAR operator. This is shown in the following WHERE clause:
WHERE CONTAINS(Description, 'drive NEAR car')

This predicate will filter rows where the Description column contains the word "drive" somewhere "near" the word "car". It is important to realize however, that NEAR is a relative term. Results are often more or

Working with Full-Text Indexes and Queries

20-23

less relevant depending upon how near the search words are in the column. Later in this lesson, you will see how ranking the results of a proximity query usually provide more useful outcomes.

Inflectional
Earlier in the module, you learned how end users think of words like drive, drove, and driving as being different versions of the same word. In a CONTAINS query, you can include a search for these by using the FORMSOF function. This is shown in the following WHERE clause:
WHERE CONTAINS(Description, 'FORMSOF(INFLECTIONAL, drive)')

This predicate will filter rows where the Description column contains a word that is an inflectional form of the word "drive", such as "driving" or "drove".

Thesaurus
It is also useful to be able to search for words that are treated as having the same meaning within the organization. This is shown in the following WHERE clause:
WHERE CONTAINS(Description, 'FORMSOF(THESAURUS,client)')

This predicate will filter rows where the Description column contains words that have been configured as synonyms for the word "client". Later in the lesson, you will see how to configure a thesaurus to make these queries possible.

Specified Relevance
The CONTAINS predicate can also search for terms based upon the weighting that you assign to each term. This is shown in the following WHERE clause:
WHERE CONTAINS(Description, 'ISABOUT (certificate weight (.8), symmetric weight (.4), key weight (.2) )')

In this WHERE clause, the developer is telling SQL Server how important each search term is by assigning a weight to each term. In this example, the word 'certificate' is ranked as 0.8, the word 'symmetric' is ranked as 0.4 and the word 'key' is ranked as 0.2. The more important a search term is, the heigher the weight that should be assigned to it. Weights are values between 0 and 1.0. The ISABOUT function is another example where it is important to rank the relevance of the results returned. The ISABOUT function will be discussed later in the lesson.

20-24

Implementing a Microsoft SQL Server 2008 R2 Database

FREETEXT Queries

Key Points
FREETEXT queries are the most powerful form of full-text query. They depend upon SQL Server understanding the meaning of the term or phrase being searched for.

FREETEXT
The FREETEXT predicate allows for the creation of the most powerful forms of full-text query. Users can enter the details of the meaning of what they are looking for and SQL Server finds matches that are relevant. In the example shown in the slide, the MessageID and Description columns from the dbo.Messages table are being returned for any rows where the Description column contains a value that is relevant to the phrase 'statement was terminated'.

Weighting
SQL Server determines the relevance of the column data by internally assigning a weight to each of the search terms and then matching using the weights. This is very similar to the way the ISABOUT option works in the CONTAINS predicate but with FREETEXT, SQL Server automatically assigns the search term weightings based on an internal algorithm. This provides a result that makes it appear that SQL Server has "understood" the meaning of the search phrase.

Working with Full-Text Indexes and Queries

20-25

Table Functions and Ranking Results

Key Points
Many of the CONTAINS and FREETEXT predicate options will return a large number of returned rows. Some will be more relevant than others. SQL Server can also provide a ranking on the relevance of the results when table-valued functions are used instead of WHERE clause predicates.

CONTAINSTABLE
CONTAINSTABLE is a table-valued function that returns the same rows that would have been filtered by a CONTAINS predicate but additionally provides a measure of relevance of each returned result via a RANK column that is returned in the table. It also provides a KEY column that determines the unique identity of the returned row so that it can be joined to the underlying table if necessary.

FREETEXTTABLE
FREETEXTTABLE is the table-valued function equivalent of the FREETEXT predicate. It also returns the same rows that would have been filtered by a FREETEXT predicate along with RANK and KEY columns. In the example shown in the slide, the MessageID and Description columns are being returned from the dbo.Messages table for rows where the Description column is relevant to the search phrase 'statement was terminated'. Note, however, that the rows that are filtered have been returned as a table which has then been joined back to the source dbo.Messages table. The table returned by the FREETEXTTABLE function includes a column named KEY that is then used to locate the row in the original table. In this example, it would be used to find entries in the dbo.Messages table based upon the value in the MessageID column.

RANK
Besides returning the relevant rows, CONTAINSTABLE and FREETEXTTABLE also return a measure of relevance of each returned row called RANK.

20-26

Implementing a Microsoft SQL Server 2008 R2 Database

In the example shown in the slide, the query returns an output where the resultant rows are arranged by the RANK descending. This will return the most relevant rows first. You will see an example of this in the next demonstration. Note that the value returned by the RANK column is only meaningful within the table of results that are returned during that particular execution of the query. The value cannot be used to compare with other CONTAINSTABLE or FREETEXTTABLE function return values. Question: Would a search engine be more likely to use the table forms of these or the predicate forms?

Working with Full-Text Indexes and Queries

20-27

Thesaurus

Key Points
The full-text thesaurus allows specifying synonyms or replacements for search terms. It is set up in a language-specific XML file for each SQL Server instance.

Thesaurus
The full-text thesaurus does not live within the database. It is an instance-level XML file that contains details of synonyms and replacement searches. There is one XML file per language per SQL Server instance. It is stored in the FTDATA folder that is located within the default database file folder for the instance.

Expansion
In the example shown in the slide, an expansion has been set up. Expansions are used for synonyms. In this example, SQL Server has been told that the words 'user', 'operator', and 'developer' can be used interchangeably. If a search is performed for any of these three words, a search is automatically performed for all three of the words.

Replacement
A replacement has also been created in the example shown in the slide. A replacement is used to provide alternate search terms. In the example shown, if the user searches for either the word 'NT5' or the word 'W2K', then a search for the word 'Windows 2000' would be carried out instead. Note that no search for 'NT5' or 'W2K' would actually be carried out. Only the replacement term would be searched for.

Diacritic Sensitivity
You may have noticed another option in the example thesaurus file in the slide. Diacritics are marks that are used as indicators in certain languages. These are uncommon in the English language today apart from when words have been adopted from another language. Many other languages use accents, breves,

20-28

Implementing a Microsoft SQL Server 2008 R2 Database

diaeresis, cedillas, etc. For example, the Greek language includes diacritics for breathings, stress and iota subscripts. Indic diacritics include the anusvara, chandrabindu, nukta, and virama. With the default value of zero for diacritics_sensitive, these are ignored. When the value is set to one, the search becomes sensitive to diacritics.

Working with Full-Text Indexes and Queries

20-29

Stopwords and Stoplists

Key Points
Not all words in any language are useful in a word index. SQL Server automatically excludes common noise words from full-text indexes. These are referred to as stopwords. You can also configure other words to be ignored by full-text indexing. Stopwords are created within stoplists.

Noise Words (Stopwords)


Using English as an example, words such as 'and' or 'the' are not useful in an index. Similarly, in Simplified Chinese (language_id 2052), words such as '' (which means 'I') or '' (which means 'not') are not useful in an index. Each language, therefore, has a set of words that should be ignored when creating an index. You can see the list of system-supplied stopwords for all languages by executing the following query:
SELECT * FROM sys.fulltext_system_stopwords;

Stoplists and Stopwords


In addition to the system-supplied stopwords, SQL Server allows you to define your own sets of stopwords. These are grouped together in stoplists. In the slide, a full-text stoplist called CompanyNames is being created and then the word 'Microsoft' is being added for language_id 1033 (English). The word 'Microsoft' would then no longer be indexed in full-text indexes within this database. You can see the list of stoplists that have been created by executing the following query:
SELECT * FROM sys.fulltext_stoplists;

You can see the user-defined stopwords by executing the following query:
SELECT * FROM sys.fulltext_stopwords;

20-30

Implementing a Microsoft SQL Server 2008 R2 Database

SQL Server Management of Full-Text

Key Points
Full-text indexes live within the database that holds the tables they are based on. Like other indexes, they can benefit from periodic reorganization to remove fragmentation. Several useful DMVs have been provided for working with full-text indexing.

Fragmentation
Full-text indexes can become fragmented like other types of index. This can cause a loss of performance. The ALTER INDEX REORGANIZE command can be used to reorganize a full-text index to reduce fragmentation and increase performance. Changes to full-text indexes are not merged into the main index files immediately. Changes are first written to separate locations within the index. To perform a master merge or all full-text indexes in a fulltext catalog, the ALTER FULLTEXT CATALOG REORGANIZE command can be used. A fully merged index will have higher performance.

Dynamic Management Views and Functions


Several dynamic management objects have been added to SQL Server to make it easier to troubleshoot full-text indexing. The views and functions are all prefixed with a sys.dm_fts* prefix. One particularly useful function is sys.dm_fts_parser. You can pass a string, a language id, and optionally a stoplist to this function. It will then display how it parses the string into words and how it categorizes those words into useful words or noise words. This can be very helpful when trying to work out how a character value is being indexed. Full-text indexing supports many document types without the need to install additional components. You can see the list of supported document types by executing the query:
SELECT * FROM sys.fulltext_document_types;

Working with Full-Text Indexes and Queries

20-31

This query returns a row for each supported document type.

20-32

Implementing a Microsoft SQL Server 2008 R2 Database

Demonstration 3A: Working with Full-Text Queries

Key Points
In this demonstration you will see how to: Query a full-text index. Locate the built-in stopwords. Create a stoplist and add a value to it. Check the parsing of text by the full-text engine.

Demonstration Steps
1. 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_20_PRJ\6232B_20_PRJ.ssmssln and click Open. Open and execute the 00 Setup.sql script file from within Solution Explorer.

2. 3.

Open the 31 Demonstration 3A.sql script file. Follow the instructions contained within the comments of the script file.

Working with Full-Text Indexes and Queries

20-33

Lab 20: Working with Full-Text Indexes and Queries

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. 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: 4. 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.

5. 6. 7.

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.

20-34

Implementing a Microsoft SQL Server 2008 R2 Database

Log on using the following credentials: i. ii. User name: AdventureWorks\Administrator Password: Pa$$w0rd

8. 9. 10. 11. 12. 13. 14. 15.

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_20_PRJ\6232B_20_PRJ.ssmssln. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.

Lab Scenario
Users have been complaining about the limited querying ability provided in the marketing system. You are intending to use full-text indexing to address these complaints. You will implement a full-text index on the Marketing.ProductDescription table to improve this situation. You will implement a stoplist to avoid excessive unnecessary index size. If you have time, your manager would like you to help provide a more natural interface for your users. This will involve creating a new stored procedure.

Supporting Documentation Stored Procedure Specifications


Name Input Parameters Output Parameters Columns Returned Marketing.GetRelevantDescriptions @PhraseToSearch nvarchar(1000) Nil ProductDescriptionID, Description, Ranking

Provide relevant results by using the FREETEXTTABLE function and limit your results to rows with LanguageID = 'en' (for English).

Working with Full-Text Indexes and Queries

20-35

Exercise 1: Implement a full-text index


Scenario
In this exercise, you will implement a full-text index on the Marketing.ProductDescription table to improve the searching abilities. The main tasks for this exercise are as follows: 1. 2. 3. 4. 5. 6. 7. Create a full-text catalog. Create a full-text index on the Description column of the Marketing.ProductDescription table. Enable automatic change tracking for the index. Check to see that the population of the index is complete. Write a simple CONTAINS query. Write a CONTAINS query that searches for two words. Write a CONTAINS query that uses INFLECTIONAL forms.

Task 1: Create a full-text catalog


Execute T-SQL statements to create a new full-text catalog called DefaultFullTextCatalog. Ensure that the catalog is set as the default full-text catalog.

Task 2: Create a full-text index on the Description column of the


Marketing.ProductDescription table
Execute T-SQL statements to create a full-text index on the Description column of the Marketing.ProductDescription table. Specify the primary key of the table as the key index. Initially configure change tracking and population off.

Task 3: Enable automatic change tracking for the index


Execute T-SQL statements to enable automatic change tracking for the table.

Task 4: Check to see that the population of the index is complete


Query the sys.fulltext_indexes system view to determine if the population is complete. Look in particular at the has_crawl_completed column.

Task 5: Write a simple CONTAINS query


Write a query to search for ProductDescriptionID and Description where the Description column contains the word bottle.

Task 6: Write a CONTAINS query that searches for two words


Write a query to search for ProductDescriptionID and Description where the Description column contains the words, elastic and lycra.

Task 7: Write a CONTAINS query that uses INFLECTIONAL forms


Write a query to search for ProductDescriptionID and Description where the Description column contains inflectional forms of the word wash.

Results: After this exercise, you should have created and tested a full-text index.

20-36

Implementing a Microsoft SQL Server 2008 R2 Database

Exercise 2: Implement a stoplist


Scenario
In this exercise, you will implement a stoplist to avoid excessive unnecessary index size. The main tasks for this exercise are as follows: 1. 2. 3. 4. Review the existing system stopwords. Create a full-text stoplist. Add words to the stoplist. View the stoplist.

Task 1: Review the existing system stopwords


Review the existing system stopwords by querying the view sys.fulltext_system_stopwords for language_id 1033. (English)

Task 2: Create a full-text stoplist


Create a full-text stoplist called CommonWords.

Task 3: Add words to the stoplist


Add the words, Bike and AdventureWorks to the stoplist for the English language.

Task 4: View the stoplist


View the new stoplist by querying the sys.fulltext_stoplists and sys.fulltext_stopwords views. Results: After this exercise, you should have created a new stoplist that will help avoid excessive index size growth.

Working with Full-Text Indexes and Queries

20-37

Challenge Exercise 3: Create a stored procedure to implement a full-text search (Only if time permits)
Scenario
In this exercise, you want to provide a more natural interface for your users. In this exercise, you will create a stored procedure that implements a more advanced type of search. The main tasks for this exercise are as follows: 1. 2. Review the supporting documentation. Design, implement, and test the stored procedure.

Task 1: Review the supporting documentation


The supporting documentation includes specifications for the design of a new stored procedure.

Task 2: Design, implement, and test the stored procedure


Design and implement the stored procedure. The procedure Marketing.GetRelevantDescriptions takes an input search term and returns the specified columns from the Marketing.ProductDescription table. Rows are returned where they are considered relevant, based on the FREETEXTTABLE function and the English language. Test the stored procedure using the search phrases 'strong frame' and 'serious competition'.

Results: After this exercise, you should have created a new stored procedure and tested its behavior.

20-38

Implementing a Microsoft SQL Server 2008 R2 Database

Module Review and Takeaways

Review Questions
1. 2. 3. 4. What is the function of a stopword? What are iFilters used for? What is the difference between FREETEXT and FREETEXTTABLE? How do you configure a thesaurus for use with full-text indexing?

Best Practices
1. 2. Create a stoplist for your company. Add to the stoplist, any words that are used in almost all your company documents. Use auto-population of indexes except in rare cases with specific issues. (These situations would typically involve data that is updated at a high rate and where the index does not need to be kept completely up to date). Try to encourage developers in your organization to offer much more flexible user interfaces to your end users, based on full-text indexes in SQL Server.

3.

Working with Full-Text Indexes and Queries

20-39

Course Review and Evaluation

20-40

Implementing a Microsoft SQL Server 2008 R2 Database

Lab: Introduction to SQL Server and its Toolset

L1-1

Module 1: Introduction to SQL Server 2008 R2 and its Toolset

Lab: Introduction to SQL Server and its Toolset


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. 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: 4. 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-SQL1 is not started: Right-click 623XB-MIA-SQL1 and click Start. Right-click 623XB-MIA-SQL1 and click Connect. In the Virtual Machine Connection window, wait until the Press CTRL+ALT+DELETE to log on message appears.

5. 6. 7.

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: User name: AdventureWorks\Administrator Password: Pa$$w0rd

8. 9.

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.

Exercise 1: Verify SQL Server Component Installation


Task 1: Check that Database Engine and Reporting Services have been installed for the
MKTG instance
1. 2. 3. Click Start, click All Programs, click Microsoft SQL Server 2008 R2, click Configuration Tools, and then click SQL Server Configuration Manager. In the left-hand pane of the SQL Server Configuration Manager window, click SQL Server Services. In the right-hand pane, ensure that the following services are listed for the MKTG instance: SQL Server (MKTG) SQL Full-text Filter Daemon Launcher (MKTG) SQL Server Reporting Services (MKTG) SQL Server Agent (MKTG)

L1-2

Lab: Introduction to SQL Server and its Toolset

Note: The SQL Full-text Filter Daemon Launcher is present and it is part of the Database Engine.

Task 2: Note the services that are installed for the default instance and that Integration
Services is not installed on a per instance basis
1. 2. In the left-hand pane of the SQL Server Configuration Manager window, click SQL Server Services. In the right-hand pane, ensure that the following services are listed for the default instance: 3. SQL Server (MSSQLSERVER) SQL Full-text Filter Daemon Launcher (MSSQLSERVER) SQL Server Analysis Services (MSSQLSERVER) SQL Server Agent (MSSQLSERVER)

In the right-hand pane, note that SQL Server Integration Services 10.0 is not installed as a perinstance basis as there is no instance name shown.

Task 3: Ensure that all required services including SQL Server Agent are started and set
to autostart for both instances
1. Check that all the services for the MKTG instance have a Start Mode of Automatic. Ignore the SQL Full-text Filter Daemon Launcher service at this time. Note: The SQL Server Agent (MKTG) service is not set to autostart. 2. 3. 4. 5. 6. Right-click the SQL Server Agent (MKTG) service and click Properties. In the Log On tab, click Start and the SQL Server Agent service should start. In the Service tab, set the value for the Start Mode to Automatic, and then click OK. Check that all the services for the default instance have a Start Mode of Automatic. Ignore the SQL Full-text Filter Daemon Launcher service at this time. Check that the SQL Server Agent (MSSQLSERVER) service has Start Mode set to Automatic. Note: The SQL Server Agent (MSSQLSERVER) service is not set to autostart. 7. 8. Right-click the SQL Server Agent (MSSQLSERVER) service and click Properties. In the Log On tab, click Start and the SQL Server Agent service should start.

Lab: Introduction to SQL Server and its Toolset

L1-3

9.

In the Service tab, set the value for the Start Mode to Automatic, and then click OK.

10. The SQL Server Services need to be configured as the screenshot below:

Exercise 2: Alter Service Accounts for New Instance


Task 1: Change the service account for the MKTG database engine
1. 2. 3. 4. 5. 6. In the left-hand pane of the SQL Server Configuration Manager window, click SQL Server Services. In the right-hand pane, right-click SQL Server (MTKG), and select Properties. In the Account Name text box, type AdventureWorks\PWService. In the Password text box, type Pa$$w0rd. In the Confirm Password text box, type Pa$$w0rd and click OK. In the Confirm Account Change window, click Yes.

Task 2: Change the service account for the MKTG SQL Server Agent
1. 2. 3. 4. 5. 6. In the left-hand pane of the SQL Server Configuration Manager window, click SQL Server Services. In the right-hand pane, right-click SQL Server Agent (MTKG), and select Properties. In the Account Name text box, type AdventureWorks\PWService. In the Password text box, type Pa$$w0rd. In the Confirm Password text box, type Pa$$w0rd and click OK. Right-click SQL Server Agent (MTKG) and select Start to restart the service.

Exercise 3: Enable Named Pipes Protocol for Both Instances


Task 1: Enable the named pipes protocol for the default instance
1. 2. 3. In the left-hand pane of the SQL Server Configuration Manager window, expand SQL Server Network Configuration and then click Protocols for MSSQLSERVER. In the right-hand pane, right-click Named Pipes and select Enable. In the Warning window, click OK.

Task 2: Enable the named pipes protocol for the MKTG instance
1. In the left-hand pane of the SQL Server Configuration Manager window, click Protocols for MKTG.

L1-4

Lab: Introduction to SQL Server and its Toolset

2. 3.

In the right-hand pane, right-click Named Pipes and select Enable. In the Warning window, click OK.

Task 3: Restart both database engine services


1. 2. 3. 4. 5. In the left-hand pane of the SQL Server Configuration Manager window, click SQL Server Services. Right-click SQL Server (MSSQLSERVER) and select Restart. Right-click SQL Server (MKTG) and select Restart. In the left-hand pane of the SQL Server Configuration Manager window, click SQL Server Services. In the toolbar, click the Refresh icon.

Exercise 4: Create Aliases for AdventureWorks and Proseware


Task 1: Create a 32-bit alias (AdventureWorks) for the default instance
1. 2. 3. 4. 5. 6. In the left-hand pane of the SQL Server Configuration Manager window, expand SQL Native Client 10.0 Configuration (32bit) and click Client Protocols. Confirm that the Named Pipes protocol is Enabled. In the left-hand pane, right-click Aliases and select New Alias. In the Alias New window, in the Alias Name text box, type AdventureWorks. In the Protocol drop-down list box, select Named Pipes. In the Server text box, type . and click OK.

Task 2: Create a 32-bit alias (Proseware) for the MKTG instance


1. 2. 3. 4. 5. 6. In the left-hand pane of the SQL Server Configuration Manager window, expand SQL Native Client 10.0 Configuration (32bit) and click Client Protocols. Confirm that the Named Pipes protocol is Enabled. In the left-hand pane, right-click Aliases and select New Alias. In the Alias New window, in the Alias Name text box, type Proseware. In the Protocol drop-down list box, select Named Pipes. In the Server text box, type .\MKTG and click OK.

Task 3: Create a 64-bit alias (AdventureWorks) for the default instance


1. 2. 3. 4. 5. 6. In the left-hand pane of the SQL Server Configuration Manager window, expand SQL Native Client 10.0 Configuration and click Client Protocols. Confirm that the Named Pipes protocol is Enabled. In the left-hand pane, right-click Aliases and select New Alias. In the Alias New window, in the Alias Name text box, type AdventureWorks. In the Protocol drop-down list box, select Named Pipes. In the Server text box, type . and click OK.

Task 4: Create a 64-bit alias (Proseware) for the MKTG instance


1. In the left-hand pane of the SQL Server Configuration Manager window, expand SQL Native Client 10.0 Configuration and click Client Protocols.

Lab: Introduction to SQL Server and its Toolset

L1-5

2. 3. 4. 5. 6.

Confirm that the Named Pipes protocol is Enabled. In the left-hand pane, right-click Aliases and select New Alias. In the Alias New window, in the Alias Name text box, type Proseware. In the Protocol drop-down list box, select Named Pipes. In the Server text box, type .\MKTG and click OK.

Task 5: Use SQL Server Management Studio to connect to both aliases to ensure they
work as expected
1. 2. 3. 4. 5. Click Start, click All Programs, click Microsoft SQL Server 2008 R2, and then click SQL Server Management Studio. In the Connect to Server window, ensure that Server Type is set to Database Engine. In the Server name text box, type Proseware. In the Authentication drop-down list, select Windows Authentication, and click Connect. In Object Explorer, under Proseware expand Databases. Note: The databases that are present include at least the following: System Databases, Database Snapshots, ReportServer$MKTG, and ReportServer$MKTGTempDB. 6. 7. 8. 9. In Object Explorer, click Connect, click Database Engine. In the Connect to Server window, ensure that Server Type is set to Database Engine. In the Server name text box, type AdventureWorks. In the Authentication drop-down list, select Windows Authentication, and click Connect.

10. In Object Explorer, under AdventureWorks expand Databases. Note: The databases that are present include at least the following: System Databases, Database Snapshots, AdventureWorks2008R2, and AdventureWorksDW2008R2. 11. Close SQL Server Management Studio. 12. Close SQL Server Configuration Manager.

Challenge Exercise 5: Ensure SQL Browser is Disabled and Configure a Fixed TCP/IP Port (Only if time permits)
Task 1: Configure the TCP port for the MKTG database engine instance to 51550
1. 2. 3. 4. 5. 6. In the Virtual Machine window, click Start. From the Start menu, click All Programs, click Microsoft SQL Server 2008 R2, click Configuration Tools, and then click SQL Server Configuration Manager. In the left-hand pane of the SQL Server Configuration Manager window, expand SQL Server Network Configuration and then click Protocols for MKTG. Right-click the TCP/IP protocol and select Properties. In the TCP/IP Properties window, click IP Addresses tab. Scroll to the bottom of the screen, under the IPAll section, clear the value for TCP Dynamic Ports.

L1-6

Lab: Introduction to SQL Server and its Toolset

7. 8. 9.

For TCP Port, type 51550, and click OK. In the Warning window, click OK. In the left-hand pane, click SQL Server Services.

10. Right-click SQL Server (MKTG) and select Restart. 11. In the left-hand pane of the SQL Server Configuration Manager window, click SQL Server Services. 12. In the toolbar, click the Refresh icon and make sure the service starts.

Task 2: Disable the SQLBrowser service


1. 2. 3. 4. In the left-hand pane of the SQL Server Configuration Manager window, click SQL Server Services. In the right-hand pane, right-click SQL Server Browser and click Stop. Right-click the SQL Server Browser and click Properties. In the SQL Server Browser Properties window, in the Service tab, set the Start Mode to Disabled and click OK.

Lab: Working with Data Types

L2-1

Module 2: Working with Data Types

Lab: Working with Data Types


Lab Setup
For this lab, you will use the available virtual machine environment. Before you begin the lab, you must complete the following steps: 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. 4. 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. 5. In Virtual Machine Connection window, click on the Revert toolbar icon. 6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action to complete. 7. 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: 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_02_PRJ\6232B_02_PRJ.ssmssln. 15. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar. 1. 2. 3.

Exercise 1: Choosing Appropriate Data Types


Task 1: Determine column names and data types
1. Review the supporting documentation for details of the PhoneCampaign, Opportunity and SpecialOrder tables and determine column names, data types, and nullability for each data item in the design.

L2-2

Lab: Working with Data Types

Note: With any design exercise, there is no one correct answer. A sample solution has been provided below. Table 1: PhoneCampaign Description Which campaign this relates to. The prospect that was contacted. When contact was first attempted with the prospect. Column Name and Data Type PhoneCampaignID INT NOT NULL ProspectID INT NOT NULL FirstAttemptedContact DATETIME NULL

Comments related to the contact that was made, if it ContactComments NVARCHAR(MAX) NULL was made. When contact was actually made with the prospect. Outcome of the contact: sale, later follow-up or no interest Value of any sale made (up to 2 decimal places) Table 2: Opportunity Description Name of the opportunity Which prospect this opportunity relates to Stage the sale is at: Lead, Qualification, Proposal Development, Contract Negotiations, Complete, Lost Date that the opportunity was raised Probability of success Rating: Cold, Warm, Hot Estimated closing date Estimated revenue Delivery address Table 3: SpecialOrder Description Which prospect this order is for Column Name and Data Type ProspectID INT NOT NULL Column Name and Data Type OpportunityID INT NOT NULL ProspectID INT NOT NULL SalesStageCode CHAR(2) NOT NULL InitialContact DATETIME NULL ContactOutcomeCode CHAR(1) NULL

SalesValue DECIMAL(10,2) NULL

DateRaised DATETIME NOT NULL Likelihood TINYINT NOT NULL Rating CHAR(1) NOT NULL EstimatedClosingDate DATE NOT NULL EstimatedRevenue DECIMAL(10,2) NOT NULL DeliveryAddress NVARCHAR(MAX) NOT NULL

Lab: Working with Data Types

L2-3

Description External supplier of the item Description of the item Quantity Required (some quantities are whole numbers, some are fractional with up to 3 decimal places) Date of order Promised delivery date Actual delivery date

Column Name and Data Type SupplierID INT NOT NULL ItemDescription NVARCHAR(100) NOT NULL QuantityRequired DECIMAL(10,3) NOT NULL

OrderDate DATETIME NOT NULL PromisedDeliveryDate DATE NOT NULL ActualDeliveryDate DATE NULL

Special requirements (any comments related to the SpecialRequirements NVARCHAR(MAX) NULL special order) Quoted price per unit (up to 2 decimal places) QuotedPricePerUnit DECIMAL(10,2) NOT NULL

Exercise 2: Writing Queries With Data Type Conversions


Task 1: Connect to the MarketDev Database
1. 2. In Object Explorer, expand the Databases under Proseware. Right-click the MarketDev database and click New Query.

Task 2: Review the first query requirement and write a SELECT statement to meet the
requirement
1. 2. 3. 4. Review the supporting documentation for details for the first query requirement. In Object Explorer, expand the Databases under Proseware. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
SELECT ProductID, ProductName, CONVERT(varchar(8),SellEndDate,112) AS SellEndDate FROM Marketing.Product; GO

5. 6.

In the toolbar, click Execute. Ensure that the results from the query match the required output as shown in the supporting documentation.

Task 3: Review the second query requirement and write a SELECT statement to meet the
requirement
1. 2. Review the supporting documentation for details for the second query requirement. In Object Explorer, expand the Databases under Proseware.

L2-4

Lab: Working with Data Types

3. 4.

Right-click the MarketDev database and click New Query. Type the query below in the query pane:
SELECT ProspectID, CAST(Demographics AS nvarchar(1000)) AS Demographics FROM Marketing.Prospect; GO

5. 6.

In the toolbar, click Execute. Ensure that the results from the query match the required output as shown in the supporting documentation.

Challenge Exercise 3: Designing and Creating Alias Data Types (Only if time permits)
Task 1: Investigate the storage of phone numbers and email addresses
1. 2. In the Object Explorer, expand Databases, and expand MarketDev, and expand Tables. In each table, expand Columns, noting any columns that are holding details of Phone Numbers or Email Addresses. The following columns should be identified: Table Marketing.Prospect Marketing.Prospect Marketing.Prospect Phone Number Columns CellPhoneNumber HomePhoneNumber WorkPhoneNumber Definition NVARCHAR(20) NVARCHAR(25) VARCHAR(22)

Table Marketing.Prospect Marketing.SalesPerson

Email Address Columns EmailAddress EmailAlias

Definition NVARCHAR(100) NVARCHAR(256)

Task 2: Create a data type that stores phone numbers


1. 2. 3. In Object Explorer, expand the Databases under Proseware. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE TYPE PhoneNumber FROM nvarchar(25); GO

4.

In the toolbar, click Execute.

Task 3: Create a data type that stores email addresses


1. 2. In Object Explorer, expand the Databases under Proseware. Right-click the MarketDev database and click New Query.

Lab: Working with Data Types

L2-5

3.

Type the query below in the query pane:


CREATE TYPE EmailAddress FROM nvarchar(256); GO

4.

In the toolbar, click Execute

L2-6

Lab: Working with Data Types

Lab: Designing and Implementing Tables

L3-1

Module 3: Designing and Implementing Tables

Lab: Designing and Implementing Tables


Lab Setup
For this lab, you will use the available virtual machine environment. Before you begin the lab, you must complete the following steps: 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. 4. 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. 5. In Virtual Machine Connection window, click on the Revert toolbar icon. 6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action to complete. 7. 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: 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_03_PRJ\6232B_03_PRJ.ssmssln. 15. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar. 1. 2. 3.

Exercise 1: Improve the Design of Tables


Task 1: Review the supplied design
1. Review the supplied design in the supporting documentation for the exercise.

Task 2: Suggest an improved design


Note: With any design exercise, there is no one correct answer. A sample solution has been provided below.

L3-2

Lab: Designing and Implementing Tables

Table1: Competitor (Table name change to singular to match existing singular table names in the database) Name CompetitorID Data Type INT NOT NULL CompetitorName NVARCHAR(30) NOT NULL NVARCHAR(max) NOT NULL DATE NOT NULL The column name Name is too generic Unicode data type for flexibility Common to have multiple addresses Unicode data type for flexibility Removed underscore for consistency Chose appropriate data type Renamed for consistency Note: Suspect this should be a code or a number but would require more information from Business Analyst Unicode data type for flexibility Comments NVARCHAR(max) NULL Unicode data type for flexibility NULL because there may be no comments Table2A: City (Duplicated City details extracted from the original table called TVAdvertisements) Name CityID Data Type INT NOT NULL CityName NVARCHAR(25) NOT NULL Renamed original column Retained data type where no further information is available Design Rationale Added a surrogate key Design Rationale Prefer numeric code for surrogate keys

StreetAddress

DateEntered

StrengthOfCompetitio NVARCHAR(8) n NOT NULL

Table2B: TVStation (Duplicated TV Station details extracted from the original table called TVAdvertisements) Name TVStationID Data Type INT NOT NULL NVARCHAR(15) NOT NULL Design Rationale Added a surrogate key

TVStationName

Renamed original column Retained data type where no further information is available

Lab: Designing and Implementing Tables

L3-3

Name CityID

Data Type INT NOT NULL DECIMAL(12,2) NOT NULL

Design Rationale City details extracted to a separate table

CostPerAdvertisement

Chose appropriate data type

TotalCostOfAllAdvertisements removed as it should be calculated NumberOfAdvertisements removed as it should be calculated Table2C: TVAdvertisement (Extracted repeating groups from the original table called TVAdvertisements) Name TVAdvertisementID Data Type INT NOT NULL INT NOT NULL DATETIME NOT NULL Design Rationale Added a surrogate key

TVStationID

Reference to TV Station table

ScreeningTime

Single data type to hold both values Name to reflect combination of values

Table3: CampaignResponse (Table name change to singular to match existing singular table names in the database and removed underscore for consistency) Name TVAdvertisementID ResponseReceived ProspectID Data Type INT NOT NULL DATETIME NOT NULL INT NOT NULL Design Rationale Added a surrogate key Improved column name Reference to existing Prospect table Changed to a straightforward code using first letter An alternative would be to extract the response method as another lookup table Chose appropriate data type Chose appropriate data type ResponseProfit should be removed as it should be calculated rather than stored in the table

ResponseMethodCode CHAR(1) NOT NULL

ChargeFromReferrer RevenueReceived

DECIMAL(12,2) NOT NULL DECIMAL(12,2) NOT NULL

L3-4

Lab: Designing and Implementing Tables

Exercise 2: Create a Schema


Task 1: Connect to the MarketDev Database
1. 2. In Object Explorer, expand the Databases under Proseware. Right-click the MarketDev database and click New Query.

Task 2: Create a schema named DirectMarketing


1. Type the query below in the query pane:
CREATE SCHEMA DirectMarketing AUTHORIZATION dbo; GO

2.

In the toolbar, click Execute.

Challenge Exercise 3: Create the Tables (Only if time permits)


Task 1: Create the tables
1. 2. 3. In Object Explorer, expand the Databases under Proseware. Right-click the MarketDev database and click New Query. Type the query below in the query pane: Note: The sample query below is based on the sample solution. Your query should be based on your design. The solution shown below is contained in the 71 Lab Exercise 3.sql script file in Solution Explorer.
CREATE TABLE DirectMarketing.Competitor ( CompetitorID INT NOT NULL PRIMARY KEY, CompetitorName NVARCHAR(30) NOT NULL, StreetAddress NVARCHAR(MAX) NOT NULL, DateEntered DATE NOT NULL, StrengthOfCompetition NVARCHAR(8) NOT NULL, Comments NVARCHAR(MAX) NULL ); GO CREATE TABLE DirectMarketing.City ( CityID INT NOT NULL PRIMARY KEY, CityName NVARCHAR(25) NOT NULL ); GO CREATE TABLE DirectMarketing.TVStation ( TVStationID INT NOT NULL PRIMARY KEY, TVStationName NVARCHAR(15) NOT NULL, CityID INT NOT NULL, CostPerAdvertisement DECIMAL(12,2) NOT NULL ); GO CREATE TABLE DirectMarketing.TVAdvertisement ( TVAdvertisementID INT NOT NULL PRIMARY KEY, TVStationID INT NOT NULL, ScreeningTime DATETIME NOT NULL ); GO

Lab: Designing and Implementing Tables

L3-5

CREATE TABLE DirectMarketing.CampaignResponse ( CampaignResponseID INT NOT NULL PRIMARY KEY, ResponseReceived DATETIME NOT NULL, ProspectID INT NOT NULL, ResponseMethodCode CHAR(1) NOT NULL, ChargeFromReferrer DECIMAL(12,2) NOT NULL, RevenueReceived DECIMAL(12,2) NOT NULL ); GO

4.

In the toolbar, click Execute.

L3-6

Lab: Designing and Implementing Tables

Lab: Designing and Implementing Views

L4-1

Module 4: Designing and Implementing Views

Lab: Designing and Implementing Views


Lab Setup
For this lab, you will use the available virtual machine environment. Before you begin the lab, you must complete the following steps: 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. 4. 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. 5. In Virtual Machine Connection window, click on the Revert toolbar icon. 6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action to complete. 7. 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: 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_04_PRJ\6232B_04_PRJ.ssmssln. 15. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar. 1. 2. 3.

Exercise 1: Design, Implement and Test the WebStock Views


Task 1: Create the WebStock schema
1. 2. 3. In Object Explorer, expand the Databases under Proseware. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE SCHEMA WebStock AUTHORIZATION dbo; GO

L4-2

Lab: Designing and Implementing Views

4.

In the toolbar, click Execute.

Task 2: Review the design requirements


1. Review the supplied design in the supporting documentation for the OnlineProducts and AvailableModels views.

Task 3: Design and implement the views


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE VIEW WebStock.OnlineProducts AS SELECT p.ProductID, p.ProductName, p.ProductNumber, COALESCE(p.Color,'N/A') AS Color, CASE p.DaysToManufacture WHEN 0 THEN 'Instock' WHEN 1 THEN 'Overnight' WHEN 2 THEN 'Fast' ELSE 'Call' END AS Availability, p.Size, p.SizeUnitMeasureCode AS UnitOfMeasure, p.ListPrice AS Price, p.Weight FROM Marketing.Product AS p WHERE p.SellEndDate IS NULL AND p.SellStartDate IS NOT NULL; GO

CREATE VIEW WebStock.AvailableModels AS SELECT p.ProductID, p.ProductName, pm.ProductModelID, pm.ProductModel FROM Marketing.Product AS p INNER JOIN Marketing.ProductModel AS pm ON p.ProductModelID = pm.ProductModelID WHERE p.SellEndDate IS NULL AND p.SellStartDate IS NOT NULL; GO

3.

In the toolbar, click Execute.

Task 4: Test the views


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
SELECT * FROM WebStock.OnlineProducts; GO SELECT * FROM WebStock.AvailableModels; GO

3.

In the toolbar, click Execute.

Lab: Designing and Implementing Views

L4-3

Exercise 2: Design and Implement the Contacts View


Task 1: Create the Relationship schema
1. 2. 3. In Object Explorer, expand the Databases under Proseware. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE SCHEMA Relationship AUTHORIZATION dbo; GO

4.

In the toolbar, click Execute.

Task 2: Review the design requirements


1. Review the supplied design in the supporting documentation for the Contacts view.

Task 3: Design and implement the view


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE VIEW Relationship.Contacts AS SELECT p.ProspectID AS ContactID, p.FirstName, p.MiddleName, p.LastName, 'PROSPECT' AS ContactRole FROM Marketing.Prospect AS p UNION ALL SELECT sp.SalespersonID, sp.FirstName, sp.MiddleName, sp.LastName, 'SALESPERSON' FROM Marketing.Salesperson AS sp; GO

3.

In the toolbar, click Execute.

Task 4: Test the view


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
SELECT * FROM Relationship.Contacts; GO

3.

In the toolbar, click Execute.

Challenge Exercise 3: Modify the AvailableModels View (Only if time permits)


Task 1: Alter the AvailableModels View
1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:

L4-4

Lab: Designing and Implementing Views

ALTER VIEW WebStock.AvailableModels AS SELECT p.ProductID, p.ProductName, pm.ProductModelID, pm.ProductModel, COALESCE(ed.Description,id.Description) AS CatalogDescription FROM Marketing.Product AS p INNER JOIN Marketing.ProductModel AS pm ON p.ProductModelID = pm.ProductModelID LEFT OUTER JOIN Marketing.ProductDescription AS ed ON pm.ProductModelID = ed.ProductModelID AND ed.LanguageID = 'en' LEFT OUTER JOIN Marketing.ProductDescription as id ON pm.ProductModelID = id.ProductModelID AND id.LanguageID = '' WHERE p.SellEndDate IS NULL AND p.SellStartDate IS NOT NULL; GO

3.

In the toolbar, click Execute.

Task 2: Test the view


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
SELECT * FROM WebStock.AvailableModels; GO

3. 4.

In the toolbar, click Execute. This page intentionally left blank

Lab: Planning for SQL Server Indexing

L5-1

Module 5: Planning for SQL Server 2008 R2 Indexing

Lab: Planning for SQL Server Indexing


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. 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 logon 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: i. User name: AdventureWorks\Administrator

4.

5. 6. 7.

ii. 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. 10. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, and click SQL Server Management Studio.
8. 9. 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_05_PRJ\6232B_05_PRJ.ssmssln. 15. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.

Exercise 1: Explore existing index statistics


Task 1: Execute SQL Command
1. 2. In Object Explorer, expand the Databases under Proseware. Right-click the MarketDev database and click New Query.

L5-2

Lab: Planning for SQL Server Indexing

3.

Type the query below in the query pane:


EXEC sp_helpstats Marketing.Product GO

4.

In the toolbar, click Execute.

Task 2: Review the results


1. 2. In the Query Analyzer Results pane, review the results. Check to see if any autostats has been generated. If any autostats have been created, they will appear in the results with an _WA prefix.

Task 3: Create statistics


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE STATISTICS Product_Color_Stats ON Marketing.Product (Color) WITH FULLSCAN; GO

3.

In the toolbar, click Execute.

Task 4: Re-execute the SQL command from task 1


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
EXEC sp_helpstats Marketing.Product GO

3.

In the toolbar, click Execute.

Task 5: Use DBCC SHOW_STATISTICS


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
DBCC SHOW_STATISTICS('Marketing.Product',Product_Color_Stats); GO

3.

In the toolbar, click Execute.

Task 6: Answer questions


1. Complete the answer column in the table below. Note: The results returned can vary. Sample results are shown in the following table

Lab: Planning for SQL Server Indexing

L5-3

Question How many rows were sampled? How many steps were created? What was the average key length? How many Black products are there?

Answer 504 10 5.178571 93

Task 7: Execute SQL Command and check accuracy of statistics


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
SELECT COUNT(1) FROM Marketing.Product WHERE Color = 'Black'; GO

3.

In the toolbar, click Execute.

Task 8: Calculate Selectivity of each query


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
-- Calculate the total number of rows in the table SELECT COUNT(1) FROM Marketing.Prospect; GO

3.

In the toolbar, click Execute. Note: A sample result would be 19955

4.

Type the query below in the same query pane:


-- Query 1 SELECT ProspectID, FirstName, LastName FROM Marketing.Prospect WHERE FirstName LIKE 'A%'; GO

5. 6.

Highlight only Query 1 and click Execute. Calculate the selectivity of the query. Note: A sample result would be 2013 / 19955 or approximately 10.1%

7.

Type the query below in the same query pane:


-- Query 2 SELECT ProspectID, FirstName, LastName FROM Marketing.Prospect WHERE FirstName LIKE 'Alejandro%';

L5-4

Lab: Planning for SQL Server Indexing

GO

8. 9.

Highlight only Query 2 and click Execute. Calculate the selectivity of the query. Note: A sample result would be 48 / 19955 or approximately 0.2%

10. Type the query below in the same query pane:


-- Query 3 SELECT ProspectID, FirstName, LastName FROM Marketing.Prospect WHERE FirstName LIKE 'Arif%'; GO

11. Highlight only Query 3 and click Execute. 12. Calculate the selectivity of the query. Note: A sample result would be 1 / 19955 or approximately 0.0%

Challenge Exercise 2: Design column orders for indexes (Only if time permits)
Task 1: Design an index
1. Review the supporting documentation for Query 1, the columns and column order is detailed in the table below: Columns ProspectID Column Order 1

Rationale: Selecting by ProspectID only and no output order

Task 2: Design an index


1. Review the supporting documentation for Query 2, the columns and column order is detailed in the table below: Columns FirstName Column Order 1

Rationale: Selecting by FirstName only and no output order

Task 3: Design an index


1. Review the supporting documentation for Query 3, the columns and column order is detailed in the table below:

Lab: Planning for SQL Server Indexing

L5-5

Columns FirstName LastName

Column Order 1 2

Rationale: Selecting only a single FirstName. Adding LastName to the index will supply the correct output order

Task 4: Design an index


1. Review the supporting documentation for Query 4, the columns and column order is detailed in the table below: Columns FirstName LastName Column Order 1 2

Rationale: Selecting a range of FirstNames could have varying selectivity. In this case, the selectivity of the FirstName column is sufficient to warrant the index on the FirstName. Note that if the constant was an A rather than an S, the index would be better defined as LastName, FirstName instead

Task 5: Design an index


1. Review the supporting documentation for Query 5, the columns and column order is detailed in the table below: Columns LanguageID Column Order 1

Rationale: Grouping by LanguageID. Note that in this case an alternate output order would not change the recommendation

L5-6

Lab: Planning for SQL Server Indexing

Lab: Implementing Table Structures in SQL Server

L6-1

Module 6: Implementing Table Structures in SQL Server 2008 R2

Lab: Implementing Table Structures 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. 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 logon 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: i. User name: AdventureWorks\Administrator

4.

5. 6. 7.

ii. 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. 10. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, and click SQL Server Management Studio.
8. 9. 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_06_PRJ\6232B_06_PRJ.ssmssln. 15. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.

Exercise 1: Creating Tables as Heaps


Task 1: Review the Requirements
1. Review the supporting documentation for Table 1 and 2.

L6-2

Lab: Implementing Table Structures in SQL Server

Task 2: Create the Tables in the MarketDev database


1. 2. 3. In Object Explorer, expand the Databases under Proseware. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE TABLE Relationship.ActivityLog ( ActivityTime datetimeoffset, SessionID int, Duration int, ActivityType int ); GO CREATE TABLE Relationship.PhoneLog ( PhoneLogID int PRIMARY KEY NONCLUSTERED, SalespersonID int, CalledPhoneNumber nvarchar(16), CallDurationSeconds int ); GO

4.

In the toolbar, click Execute.

Exercise 2: Creating Tables with Clustered Indexes


Task 1: Review the Requirements
1. Review the supporting documentation for Tables 3 and 4.

Task 2: Create the Tables in the MarketDev database


1. 2. 3. In Object Explorer, expand the Databases under Proseware. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE TABLE Relationship.MediaOutlet ( MediaOutletID int PRIMARY KEY CLUSTERED, MediaOutletName nvarchar(40), PrimaryContact nvarchar(50), City nvarchar(50) ); GO CREATE TABLE Relationship.PrintMediaPlacement ( PrintMediaPlacementID int PRIMARY KEY CLUSTERED, MediaOutletID int, PlacementDate datetime, PublicationDate datetime, RelatedProductID int, PlacementCost decimal(18,2) ); GO

4.

In the toolbar, click Execute.

Lab: Implementing Table Structures in SQL Server

L6-3

Challenge Exercise 3: Comparing the Performance of Clustered Indexes vs. Heaps (Only if time permits)
Task 1: Review the Table Design
1. Review the supporting documentation for Table 5.

Task 2: Create the Relationship.Table_Heap Table


1. 2. 3. In Object Explorer, expand the Databases under Proseware. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE TABLE Relationship.Table_Heap ( ApplicationID int IDENTITY(1,1), ApplicantName nvarchar(150), EmailAddress nvarchar(100), ReferenceID uniqueidentifier, Comments nvarchar(500) ); GO

4.

In the toolbar, click Execute.

Task 3: Create the Relationship.Table_ApplicationID Table


1. 2. 3. In Object Explorer, expand the Databases under Proseware. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE TABLE Relationship.Table_ApplicationID ( ApplicationID int IDENTITY(1,1), ApplicantName nvarchar(150), EmailAddress nvarchar(100), ReferenceID uniqueidentifier, Comments nvarchar(500) ); GO CREATE CLUSTERED INDEX IX_ApplicantID ON Relationship.Table_ApplicationID (ApplicationID); GO

4.

In the toolbar, click Execute.

Task 4: Create the Relationship.Table_EmailAddress Table


1. 2. 3. In Object Explorer, expand the Databases under Proseware. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE TABLE Relationship.Table_EmailAddress ( ApplicationID int IDENTITY(1,1),

L6-4

Lab: Implementing Table Structures in SQL Server

ApplicantName nvarchar(150), EmailAddress nvarchar(100), ReferenceID uniqueidentifier, Comments nvarchar(500) ); GO CREATE CLUSTERED INDEX IX_EmailAddress ON Relationship.Table_EmailAddress (EmailAddress); GO

4.

In the toolbar, click Execute.

Task 5: Create the Relationship.Table_ReferenceID Table


1. 2. 3. In Object Explorer, expand the Databases under Proseware. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE TABLE Relationship.Table_ReferenceID ( ApplicationID int IDENTITY(1,1), ApplicantName nvarchar(150), EmailAddress nvarchar(100), ReferenceID uniqueidentifier, Comments nvarchar(500) ); GO CREATE CLUSTERED INDEX IX_ReferenceID ON Relationship.Table_ReferenceID (ReferenceID); GO

4.

In the toolbar, click Execute.

Task 6: Load and Execute the Workload Script


1. 2. In Solution Explorer, double-click the file 72 Lab Exercise 3 Workload Script.sql. In the toolbar, click Execute.

Note: this may take approximately five minutes to complete, depending on available hardware resources. You can check where it is up to by periodically switching to the Messages tab. A message is printed as each of the four sections is completed. While the script is running, review the contents of the script and estimate the proportion of time difference you expect to see in the results.

Task 7: Compare Table Performance


1. Compare the performance of each table structure as reported by the results of executing the Workload script.

Note: Results will vary substantially depending upon the hardware the Virtual Machine is running on. Sample results are shown below. HeapTime 23 seconds ApplicationIDTime 21 seconds EmailAddressTime 91 seconds ReferenceIDTime 134 seconds

Lab: Reading SQL Server Execution Plans

L7-1

Module 7: Reading SQL Server 2008 R2 Execution Plans

Lab: Reading SQL Server Execution Plans


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. On the host computer, click Start, point to Administrative Tools, and then click Hyper-V Manager. Maximize the Hyper-V Manager window. Right-click 623XB-MIA-DC and click Start. Right-click 623XB-MIA-DC and click Connect.

3. In the Virtual Machines list, if the virtual machine 623XB-MIA-DC is not started:

4.

5. 6. 7.

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 logon 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: i. User name: AdventureWorks\Administrator

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.

ii.

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_07_PRJ\6232B_07_PRJ.ssmssln. 15. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.

Exercise 1: Actual vs. Estimated Plans


Task 1: Load the test script
1. In Solution Explorer, double-click the file

L7-2

Lab: Reading SQL Server Execution Plans

2.

51 Lab Exercise 1.sql. Highlight the following section of the script:


USE AdventureWorks2008R2; GO

3.

In the toolbar, click Execute.

Task 2: Generate an estimated execution plan for script 7.1


1. Highlight the following section of the script
SELECT * FROM dbo.DatabaseLog; GO

2.

From the Query menu, select Display Estimated Execution Plan. Note: A Table Scan operator was used.

Task 3: View the estimated execution plan for script 7.2 using SHOWPLAN_XML
1. Highlight the following section of the script
SET SHOWPLAN_XML ON; GO SELECT * FROM dbo.DatabaseLog; GO SET SHOWPLAN_XML OFF; GO

2. 3. 4. 5.

In the toolbar, click Execute. In the Results pane, click on the XML that is returned to view the execution plan. In the Results pane, right-click in the whitespace in the plan, click Show Execution Plan XML. In the ExecutionPlanX.sqlplan tab, review the XML. Note: The XML is complex and it includes a large amount of detail that is not immediately obvious from the graphical plan.

6.

Close the XML window and the execution plan window. If prompted to save changes, do not save the changes.

Task 4: Generate the actual execution plan for script 7.3


1. 2. In the Query menu and click Include Actual Execution Plan. Highlight the following section of the script
SELECT * FROM dbo.DatabaseLog; GO

3.

In the toolbar, click Execute.

Lab: Reading SQL Server Execution Plans

L7-3

4.

Click on the Execution Plan pane. Note: The plan is identical to the estimated plan from the previous task.

Task 5: Try to generate an estimated execution plan for script 7.4


1. Highlight the following section of the script
CREATE TABLE dbo.SomeTable ( SomeTableID INT IDENTITY(1, 1) PRIMARY KEY, FullName varchar(35) ); INSERT INTO dbo.SomeTable VALUES('Hello'),('There'); SELECT * FROM dbo.SomeTable; DROP TABLE dbo.SomeTable; GO

2.

From the Query menu, select Display Estimated Execution Plan. Note: An Estimated Execution Plan cannot be created. Note the reason (invalid object name) for the inability to create a plan in the messages tab.

Task 6: Review the actual execution plan for script 7.4


1. Highlight the following section of the script again
CREATE TABLE dbo.SomeTable ( SomeTableID INT IDENTITY(1, 1) PRIMARY KEY, FullName varchar(35) ); INSERT INTO dbo.SomeTable VALUES('Hello'),('There'); SELECT * FROM dbo.SomeTable; DROP TABLE dbo.SomeTable; GO

2. 3.

In the toolbar, click Execute. Review the Execution Plan that has been returned. Note: The returned plan shows the INSERT and SELECT statements but not the CREATE and DROP statements.

Task 7: Review the execution plans currently cached in memory using script 7.5
1. Highlight the following section of the script
SELECT cp.objtype AS PlanType, OBJECT_NAME(st.objectid,st.dbid) AS ObjectName, cp.refcounts AS ReferenceCounts, cp.usecounts AS UseCounts, st.text AS SQLBatch, qp.query_plan AS QueryPlan FROM sys.dm_exec_cached_plans AS cp CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) AS qp CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) AS st; GO

L7-4

Lab: Reading SQL Server Execution Plans

2. 3.

In the toolbar, click Execute. Review the results being returned. Note: The results returned will vary from system to system. Browse through the rows in the Results tab to gain an understanding of the types of plans currently in memory.

Exercise 2: Identify Common Plan Elements


Task 1: Load the test script
1. In Solution Explorer, double-click the file 61 Lab Exercise 2.sql. Highlight the query as shown in the script below:
USE AdventureWorks2008R2; GO

2.

3. 4.

In the toolbar, click Execute. From the Query menu click Include Actual Execution Plan.

Task 2: Explain the actual execution plan from script 7.6


1. Highlight script 7.6 as shown in the code below
SELECT * FROM Person.Person; GO

2. 3.

In the toolbar, click Execute. Explain the results being returned. Note: The table has a clustered index and the entire table is being read.

Task 3: Explain the actual execution plan from script 7.7


1. Highlight script 7.7 as shown in the code below
SELECT * FROM Person.Person WHERE Person.BusinessEntityID = 12; GO

2. 3.

In the toolbar, click Execute. Explain the results being returned. Note: The table has a clustered index and a specific clustering key is being used to seek.

Task 4: Explain the actual execution plan from script 7.8


1. Highlight script 7.8 as shown in the code below
SELECT * FROM Production.ProductInventory ORDER BY Shelf;

Lab: Reading SQL Server Execution Plans

L7-5

GO

2. 3.

In the toolbar, click Execute. Explain the results being returned. Note: The table has a clustered index and the entire table is being read. The rows are then sorted by Shelf.

Task 5: Explain the actual execution plan from script 7.9


1. Highlight script 7.9 as shown in the code below
SELECT * FROM dbo.DatabaseLog WHERE DatabaseLogID = 1; GO

2. 3.

In the toolbar, click Execute. Explain the results being returned. Note: The table is structured as a heap. The table has a nonclustered index on DatabaseLogID that is being used to locate the row required. Because the entire row is then required, a lookup is being made into the heap.

Task 6: Explain the actual execution plan from script 7.10


1. Highlight script 7.10 as shown in the code below
SELECT AddressID, AddressLine1, AddressLine2, City, StateProvinceID, PostalCode FROM Person.Address WHERE StateProvinceID = 32; GO

2. 3.

In the toolbar, click Execute. Explain the results being returned. Note: The table has a clustered index. There is a nonclustered index that is sufficiently selective to be useful in locating entries for the given StateProvinceID. After the rows are located by that index, lookups to the clustered index need to be performed because not all columns that are required for the query are contained within the nonclustered index.

Task 7: Explain the actual execution plan from script 7.11


1. Highlight script 7.11 as shown in the code below
SELECT AddressID, AddressLine1, AddressLine2, City, StateProvinceID, PostalCode FROM Person.Address WHERE StateProvinceID = 79; GO

2.

In the toolbar, click Execute.

L7-6

Lab: Reading SQL Server Execution Plans

3. 4.

Explain the results being returned. Compare this plan to the one returned in script 7.10. The reason why the plans are different can be attributed to Note: SQL Server has chosen to scan an entire index as it covers the query. The rows with the correct StateProvinceID are being selected from that index. Note the Missing Index hint that appears.

Task 8: Explain the actual execution plan from script 7.12


1. Highlight script 7.12 as shown in the code below
SELECT City, COUNT(City) AS CityCount FROM Person.Address GROUP BY City; GO

2. 3.

In the toolbar, click Execute. Explain the results being returned. Note: SQL Server has decided to read an entire index that contains the City column rather than reading the entire table. As the index is not in City order, it then needs to execute a hash match aggregate operation to calculate the required aggregate.

Task 9: Explain the actual execution plan from script 7.13


1. Highlight script 7.13 as shown in the code below
SELECT StateProvinceID, COUNT(1) AS StateProvinceCount FROM Person.Address GROUP BY StateProvinceID; GO

2. 3. 4.

In the toolbar, click Execute. Explain the results being returned. Compare this plan to the one returned in script 7.12. The reason why the plans are different can be attributed to Note: There is a nonclustered index that is in StateProvinceID order. SQL Server has chosen to scan that index. As it is already in StateProvinceID order, a stream aggregate operation was able to be performed.

Task 10: Explain the actual execution plan from script 7.14
1. Highlight script 7.14 as shown in the code below
SELECT City, COUNT(City) AS CityCount FROM Person.Address GROUP BY City HAVING COUNT(1) > 5; GO

2.

In the toolbar, click Execute.

Lab: Reading SQL Server Execution Plans

L7-7

3.

Note the difference in this plan from the plan for script 7.12. Note: This query is identical to the one in script 7.12 with the addition of the HAVING clause. That clause has caused SQL Server to add a filter operation.

Challenge Exercise 3: Query Cost Comparison (Only if time permits)


Task 1: Load the test script
1. In Solution Explorer, double-click the file 71 Lab Exercise 3.sql. Highlight the query as shown in the script below:
USE AdventureWorks2008R2; GO

2.

3. 4.

In the toolbar, click Execute. From the Query menu click Include Actual Execution Plan.

Task 2: Explain the actual execution plan from script 7.15


1. Highlight script 7.15 as shown in the code below
SELECT DISTINCT a.City FROM Person.Address AS a ORDER BY a.City; SELECT a.City FROM Person.Address AS a GROUP BY a.City ORDER BY a.City; GO

2. 3.

In the toolbar, click Execute. Explain the results being returned. Note: Even though the two queries are structured quite differently, they are requesting exactly the same results in the same order. It is then logical that SQL Server executes the same plan for both queries.

L7-8

Lab: Reading SQL Server Execution Plans

Lab: Improving Performance through Nonclustered Indexes

L8-1

Module 8: Improving Performance through Nonclustered Indexes

Lab: Improving Performance through Nonclustered Indexes


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. 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 logon 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: i. User name: AdventureWorks\Administrator

4.

5. 6. 7.

ii. 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. 10. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, and click SQL Server Management Studio.
8. 9. 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_08_PRJ\6232B_08_PRJ.ssmssln. 15. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.

Exercise 1: Nonclustered index usage review


Task 1: Review the query
1. Review the supporting documentation for Query 1.

L8-2

Lab: Improving Performance through Nonclustered Indexes

Task 2: Review the existing Index and Table structures


1. In Object Explorer, expand Proseware, expand Databases, expand MarketDev, expand Tables, and expand Marketing.WebLog. Review existing indexes and table structures for this table. Note: Clustered Primary Key on WebLogID and Non-Clustered index on SessionStart.

2.

Task 3: Design a more appropriate index


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE INDEX IX_WebLog_Perf_20100830_A ON Marketing.WebLog (SessionStart) INCLUDE (SessionID, ServerID, UserName); GO

3.

In the toolbar, click Execute.

Task 4: Test your design


1. 2. 3. Right-click the MarketDev database and click New Query. From the Query menu, click Include Actual Execution Plan. Type the query below in the query pane:
DECLARE @StartTime datetime2 = '2010-08-30 16:27'; SELECT TOP(5000) wl.SessionID, wl.ServerID, wl.UserName FROM Marketing.WebLog AS wl WHERE wl.SessionStart >= @StartTime ORDER BY wl.SessionStart, wl.ServerID;

4.

In the toolbar, click Execute.

Exercise 2: Improving nonclustered index designs


Task 1: Review the index design
1. Review the supporting documentation for Query 2.

Task 2: Implement the index


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE INDEX IX_WebLog_Perf_20100830_B ON Marketing.WebLog (ServerID, SessionStart) INCLUDE (SessionID, UserName); GO

3.

In the toolbar, click Execute.

Lab: Improving Performance through Nonclustered Indexes

L8-3

Task 3: Test the design and explain why the index was not used
1. 2. 3. Right-click the MarketDev database and click New Query. From the Query menu, click Include Actual Execution Plan. Type the query below in the query pane:
DECLARE @StartTime datetime2 = '2010-08-30 16:27'; SELECT TOP(5000) wl.SessionID, wl.ServerID, wl.UserName FROM Marketing.WebLog AS wl WHERE wl.SessionStart >= @StartTime ORDER BY wl.SessionStart, wl.ServerID; GO

4.

In the toolbar, click Execute. Note: The structure of the index does not support efficient selection of rows or ordering of results.

Exercise 3: SQL Server Profiler and Database Engine Tuning Advisor


Task 1: Review the query
1. Review the supporting documentation for Query 3.

Task 2: Review the existing Index and Table structures


1. In Object Explorer, expand Proseware, expand Databases, expand MarketDev, expand Tables, and expand Marketing.PostalCode. Review existing indexes and table structures for this table. Note: Clustered index on Country, PostalCode.

2.

Task 3: Design a more appropriate index by following the Missing Index suggestion
1. 2. 3. Right-click the MarketDev database and click New Query. From the Query menu, click Include Actual Execution Plan. Type the query below in the query pane:
SELECT PostalCode, Country FROM Marketing.PostalCode WHERE StateCode = 'KY' ORDER BY StateCode, PostalCode; GO

4. 5. 6.

In the toolbar, click Execute. In the Execution Plan tab, note the missing index suggestion in green. Right-click in whitespace in the middle of the graphical execution plan and choose Missing Index Details.

L8-4

Lab: Improving Performance through Nonclustered Indexes

Note: Review the suggested index design. 7. 8. Close the Missing Index Details query window. Type the query below in the previous query pane:
CREATE NONCLUSTERED INDEX IX_PostalCode_Perf_20100830_A ON Marketing.PostalCode (StateCode) INCLUDE (Country,PostalCode); GO

9.

Highlight the above query, click Execute.

10. Highlight the previous query as shown below in the query pane:
SELECT PostalCode, Country FROM Marketing.PostalCode WHERE StateCode = 'KY' ORDER BY StateCode, PostalCode; GO

11. In the toolbar, click Execute. 12. In the Execution Plan tab, note that the missing index suggestion has now disappeared. Note: The query is now utilizing the new index. 13. Leave the query pane open for the next task.

Task 4: Create a better index that removes the sort operation. If you create another
index, confirm that SQL Server selects it
1. Type the query below in the query pane from the previous task:
CREATE NONCLUSTERED INDEX IX_PostalCode_Perf_20100830_B ON Marketing.PostalCode (StateCode, PostalCode) INCLUDE (Country); GO

2. 3.

Highlight the above query, click Execute. Highlight the previous query as shown below in the query pane:
SELECT PostalCode, Country FROM Marketing.PostalCode WHERE StateCode = 'KY' ORDER BY StateCode, PostalCode; GO

4. 5.

In the toolbar, click Execute. Click on the Execution Plan tab. Note: The sort operation is now unnecessary and the new index is now utilized.

Lab: Improving Performance through Nonclustered Indexes

L8-5

Challenge Exercise 4: Nonclustered index design (Only if time permits)


Task 1: Open SQL Server Profiler and configure and start a trace
1. 2. 3. 4. 5. 6. 7. 8. 9. In SQL Server Management Studio, in the Tools menu, click SQL Server Profiler. In the 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 Trace Properties window, type Module08Trace in the Trace Name textbox. In the Use the Template drop down list box, select Tuning. Click Save to file checkbox. In the Save As window, click Desktop in the left-hand pane under Favorites and click Save. Uncheck the Enable File Rollover checkbox. In the Set maximum file size(MB) textbox, type 500.

10. Click Events Selection tab, and click Column Filters. 11. In the Edit Filter pane, click the DatabaseName column header. 12. In the DatabaseName pane, expand the Like node, type MarketDev, and click OK. 13. In the Trace Properties window, click Run. 14. In the Window menu, ensure that AutoScroll is not selected.

Task 2: Load and execute the workload file


1. 2. 3. In SQL Server Management Studio, double-click 81 Lab Exercise 4.sql in Solution Explorer. In the toolbar, click Execute. Wait for the query to complete. Note: The query will take approximately 3 minutes to execute, depending upon the available hardware resources.

Task 3: Stop and analyze the trace using DTA


1. 2. 3. 4. 5. In SQL Server Profiler, from the File menu, click Stop Trace. From the Tools menu, click Database Engine Tuning Advisor. In the Connect to Server window, click Connect. Maximize the Database Engine Tuning Advisor window. In the Workload group box, ensure that File is selected and click the Browse for a Workload File icon (the icon is the first icon to the right of the text box in the Workload group box). Browse to the Desktop folder, select the Module08Trace.trc file and click Open.

6.

L8-6

Lab: Improving Performance through Nonclustered Indexes

7. 8. 9.

In the Database for workload analysis dropdown, select MarketDev. In the Select databases and tables to tune list, check the MarketDev database. Click the Tuning Options tab and click Advanced Options.

10. In the Advanced Tuning Options window, check the Define max space for recommendations (MB) checkbox and enter 500 for the size and click OK. 11. From the toolbar, click the Start Analysis. Note: Observe the tuning progress and when the analysis is complete, note the recommendations. The exact recommendations you see will depend upon how long you ran the query, etc. but it is likely you will see a recommendation for two new indexes and a substantial estimated performance improvement. 12. On the Recommendations tab, note the Estimated improvement. 13. Scroll the Index Recommendations output to the right and note the hyperlinks to sample code. 14. Click each of the recommendations in the Definition column turn and note the suggested index structures. 15. Close DTA. 16. Close SQL Server Profiler.

Lab: Designing and Implementing Stored Procedures

L9-1

Module 9: Designing and Implementing Stored Procedures

Lab: Designing and Implementing Stored Procedures


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. 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 logon 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: i. User name: AdventureWorks\Administrator

4.

5. 6. 7.

ii. 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. 10. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, and click SQL Server Management Studio.
8. 9. 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_09_PRJ\6232B_09_PRJ.ssmssln. 15. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.

L9-2

Lab: Designing and Implementing Stored Procedures

Exercise 1: Create stored procedures


Task 1: Review the Reports.GetProductColors stored procedure specification
1. Review the supplied design requirements in the supporting documentation for Reports.GetProductColors.

Task 2: Design, create and test the Reports.GetProductColors stored procedure


1. In Object Explorer, expand the Proseware server, expand Databases, right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE PROCEDURE Reports.GetProductColors AS SELECT DISTINCT p.Color FROM Marketing.Product AS p WHERE p.Color IS NOT NULL ORDER BY p.Color; GO EXEC Reports.GetProductColors; GO

2.

3.

In the toolbar, click Execute. Note: Ensure that approximately 9 colors are returned and that no NULL row is returned.

Task 3: Review the Reports.GetProductsAndModels stored procedure specification


1. Review the supplied design requirements in the supporting documentation for Reports.GetProductsAndModels.

Task 4: Design, create and test the Reports.GetProductsAndModels stored procedure


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE PROCEDURE Reports.GetProductsAndModels AS SELECT p.ProductID, p.ProductName, p.ProductNumber, p.SellStartDate, p.SellEndDate, p.Color, pm.ProductModelID, COALESCE(ed.Description,id.Description,p.ProductName) AS EnglishDescription, COALESCE(fd.Description,id.Description,p.ProductName) AS FrenchDescription, COALESCE(cd.Description,id.Description,p.ProductName) AS ChineseDescription FROM Marketing.Product AS p LEFT OUTER JOIN Marketing.ProductModel AS pm ON p.ProductModelID = pm.ProductModelID LEFT OUTER JOIN Marketing.ProductDescription AS ed ON pm.ProductModelID = ed.ProductModelID AND ed.LanguageID = 'en'

Lab: Designing and Implementing Stored Procedures

L9-3

LEFT OUTER JOIN Marketing.ProductDescription AS fd ON pm.ProductModelID = fd.ProductModelID AND fd.LanguageID = 'fr' LEFT OUTER JOIN Marketing.ProductDescription AS cd ON pm.ProductModelID = cd.ProductModelID AND cd.LanguageID = 'zh-cht' LEFT OUTER JOIN Marketing.ProductDescription AS id ON pm.ProductModelID = id.ProductModelID AND id.LanguageID = '' ORDER BY p.ProductID,pm.ProductModelID; GO EXEC Reports.GetProductsAndModels; GO

3.

In the toolbar, click Execute. Note: Ensure that approximately 504 rows are returned. Check that appropriate language descriptions appear. ProductID 1 should have the same description for all three languages. ProductID 776 should have different descriptions for each language.

Exercise 2: Create a parameterized stored procedure


Task 1: Review the Reports.GetProductsByColor stored procedure specification
1. Review the supplied design requirements in the supporting documentation for Reports.GetProductsByColor.

Task 2: Design, create and test the Reports.GetProductsByColor stored procedure


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE PROCEDURE Reports.GetProductsByColor @Color nvarchar(16) AS SELECT p.ProductID, p.ProductName, p.ListPrice AS Price, p.Color, p.Size, p.SizeUnitMeasureCode AS UnitOfMeasure FROM Marketing.Product AS p WHERE (p.Color = @Color) OR (p.Color IS NULL AND @Color IS NULL) ORDER BY ProductName; GO EXEC Reports.GetProductsByColor 'Blue'; GO EXEC Reports.GetProductsByColor NULL; GO

3.

In the toolbar, click Execute. Note: Ensure that approximately 26 rows are returned for blue products. Ensure that approximately 248 rows are returned for products with no color.

L9-4

Lab: Designing and Implementing Stored Procedures

Challenge Exercise 3: Alter the execution context of stored procedures (Only if time permits)
Task 1: Alter the Reports.GetProductColors stored procedure to execute as OWNER
1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
ALTER PROCEDURE Reports.GetProductColors WITH EXECUTE AS OWNER AS SELECT DISTINCT p.Color FROM Marketing.Product AS p WHERE p.Color IS NOT NULL ORDER BY p.Color; GO EXEC Reports.GetProductColors; GO

3.

In the toolbar, click Execute. Check that the procedure still executes without error.

Task 2: Alter the Reports.GetProductsAndModels stored procedure to execute as


OWNER
1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
ALTER PROCEDURE Reports.GetProductsAndModels WITH EXECUTE AS OWNER AS SELECT p.ProductID, p.ProductName, p.ProductNumber, p.SellStartDate, p.SellEndDate, p.Color, pm.ProductModelID, COALESCE(ed.Description,id.Description,p.ProductName) AS EnglishDescription, COALESCE(fd.Description,id.Description,p.ProductName) AS FrenchDescription, COALESCE(cd.Description,id.Description,p.ProductName) AS ChineseDescription FROM Marketing.Product AS p LEFT OUTER JOIN Marketing.ProductModel AS pm ON p.ProductModelID = pm.ProductModelID LEFT OUTER JOIN Marketing.ProductDescription AS ed ON pm.ProductModelID = ed.ProductModelID AND ed.LanguageID = 'en' LEFT OUTER JOIN Marketing.ProductDescription AS fd ON pm.ProductModelID = fd.ProductModelID AND fd.LanguageID = 'fr' LEFT OUTER JOIN Marketing.ProductDescription AS cd ON pm.ProductModelID = cd.ProductModelID AND cd.LanguageID = 'zh-cht' LEFT OUTER JOIN Marketing.ProductDescription AS id ON pm.ProductModelID = id.ProductModelID AND id.LanguageID = '' ORDER BY p.ProductID,pm.ProductModelID;

Lab: Designing and Implementing Stored Procedures

L9-5

GO EXEC Reports.GetProductsAndModels; GO

3.

In the toolbar, click Execute. Check that the procedure still executes without error.

Task 3: Alter the Reports.GetProductsByColor stored procedure to execute as OWNER


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
ALTER PROCEDURE Reports.GetProductsByColor @Color nvarchar(16) WITH EXECUTE AS OWNER AS SELECT p.ProductID, p.ProductName, p.ListPrice AS Price, p.Color, p.Size, p.SizeUnitMeasureCode AS UnitOfMeasure FROM Marketing.Product AS p WHERE (p.Color = @Color) OR (p.Color IS NULL AND @Color IS NULL) ORDER BY ProductName; GO EXEC Reports.GetProductsByColor 'Blue'; GO EXEC Reports.GetProductsByColor NULL; GO

3.

In the toolbar, click Execute. Check that the procedure still executes without error.

L9-6

Lab: Designing and Implementing Stored Procedures

Lab: Passing Tables and Merging Data

L10-1

Module 10: Merging Data and Passing Tables

Lab: Passing Tables and Merging Data


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. On the host computer, click Start, point to Administrative Tools, and then click Hyper-V Manager. Maximize the Hyper-V Manager window.

3. 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. 4. 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 PressCTRL+ALT+DELETE to log on message appears. 5. In Virtual Machine Connection window, click on the Revert toolbar icon. 6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action to complete. 7. 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: 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_10_PRJ\6232B_10_PRJ.ssmssln. 15. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.

Exercise 1: Create a Table Type


Task 1: Review the parameters of a stored procedure
1. Review the supplied design requirements in the supporting documentation for Reports.GetProductsByColorList.

L10-2

Lab: Passing Tables and Merging Data

Task 2: Review the existing function


1. In Object Explorer, expand Proseware, expand Databases, expand MarketDev, expand Programmability, expand Functions, and expand Table-valued Functions. Right-click dbo.StringListToTable, click Script Function as, click CREATE To, select New Query Editor Window. Review the design of the existing function.

2.

3.

Task 3: Create a new table type


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE TYPE StringList AS TABLE(StringValue nvarchar(1000) NOT NULL); GO

3.

In the toolbar, click Execute.

Exercise 2: Use a Table Type Parameter


Task 1: Create the stored procedure
1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE PROCEDURE Reports.GetProductsByColorList_Test (@ColorList StringList READONLY) AS SELECT p.ProductID, p.ProductName, p.ListPrice AS Price, p.Color, p.Size, p.SizeUnitMeasureCode AS UnitOfMeasure FROM Marketing.Product AS p INNER JOIN @ColorList AS cl ON p.Color = cl.StringValue ORDER BY p.ProductName; GO

3.

In the toolbar, click Execute.

Task 2: Test the new procedure


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
DECLARE @ColorList StringList; INSERT INTO @ColorList VALUES('Red'),('Blue'),('Silver'); EXEC Reports.GetProductsByColorList_Test @ColorList; GO

3.

In the toolbar, click Execute.

Lab: Passing Tables and Merging Data

L10-3

Note: Approximately 107 rows should be returned.

Challenge Exercise 3: Use a Table Type with MERGE (Only if time permits)
Task 1: Create a new table type
1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE TYPE dbo.SalespersonList AS TABLE (SalespersonID int NOT NULL, FirstName nvarchar(50) NULL, MiddleName nvarchar(50) NULL, LastName nvarchar(50) NULL, BadgeNumber nvarchar(15) NULL, EmailAlias nvarchar(256) NULL, SalesTerritoryID int NULL); GO

3.

In the toolbar, click Execute.

Task 2: Create a replacement stored procedure


1. Review the supplied design in the supporting documentation for the Marketing.SalespersonMerge Stored Procedure. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE PROCEDURE Marketing.SalespersonMerge (@SalespersonDetails SalespersonList READONLY) AS BEGIN MERGE INTO Marketing.Salesperson AS sp USING @SalespersonDetails AS spd ON sp.SalespersonID = spd.SalespersonID WHEN MATCHED THEN UPDATE SET sp.FirstName = COALESCE(spd.FirstName, sp.FirstName), sp.MiddleName = COALESCE(spd.MiddleName, sp.MiddleName), sp.LastName = COALESCE(spd.LastName, sp.LastName), sp.BadgeNumber = COALESCE(spd.BadgeNumber, sp.BadgeNumber), sp.EmailAlias = COALESCE(spd.EmailAlias, sp.EmailAlias), sp.SalesTerritoryID = COALESCE(spd.SalesTerritoryID, sp.SalesTerritoryID) WHEN NOT MATCHED THEN INSERT (SalespersonID, FirstName, MiddleName, LastName, BadgeNumber, EmailAlias, SalesTerritoryID) VALUES (spd.SalespersonID, spd.FirstName, spd.MiddleName, spd.LastName, spd.BadgeNumber, spd.EmailAlias, spd.SalesTerritoryID)

2. 3.

L10-4

Lab: Passing Tables and Merging Data

OUTPUT $action AS Action, inserted.SalespersonID; END; GO

4.

In the toolbar, click Execute.

Task 3: Test the replacement procedure


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
DECLARE @Salespeople SalespersonList; INSERT INTO @Salespeople (SalespersonID, FirstName, MiddleName, LastName, BadgeNumber, EmailAlias, SalesTerritoryID) VALUES (276,'Michael','','Wong',NULL,'adventure-works\mwong',NULL), (601,'John','','Wong','234232','adventure-works\jwong',3); EXEC Marketing.SalespersonMerge @Salespeople; GO

3.

In the toolbar, click Execute. Note: The output should show UPDATE for SalesPersonID 276 and should show INSERT for SalesPersonID 601.

Lab: Creating Highly Concurrent SQL Server Applications

L11-1

Module 11: Creating Highly Concurrent SQL Server 2008 R2 Applications

Lab: Creating Highly Concurrent SQL Server Applications


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. 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: 4. 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.

5. 6. 7.

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: i. ii. User name: AdventureWorks\Administrator Password: Pa$$w0rd

8. 9.

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.

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.

L11-2

Lab: Creating Highly Concurrent SQL Server Applications

14. In the Open Project window, open the project D:\6232B_Labs\6232B_11_PRJ\6232B_11_PRJ.ssmssln. 15. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.

Exercise 1: Detecting Deadlocks


Task 1: Start and configure SQL Server Profiler
1. 2. 3. 4. 5. 6. 7. 8. 9. In SQL Server Management Studio, from Tools menu, click SQL Server Profiler. 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 Trace Properties window, type Deadlock Detection in the Trace Name textbox. Click Events Selection tab. Check the Show all events checkbox. Expand Locks, check Deadlock graph. Uncheck the Show all events checkbox. De-select all events except the Deadlock graph. You may need to scroll the window down to do this.

10. Click Run to start the trace.

Task 2: Load and execute the test scripts


1. 2. 3. In SQL Server Management Studio, double-click 51 Lab Exercise 1.sql in Solution Explorer. Review the script. In SQL Server Management Studio, double-click 52 Lab Exercise 1 2nd Window.sql in Solution Explorer. Review the script. Execute 51 Lab Exercise 1.sql and then immediately execute 52 Lab Exercise 1 2nd Window.sql. Wait for both to complete Note: One of the scripts will return a deadlock error.

4. 5.

Task 3: Stop the trace and review the deadlock graph


1. 2. 3. 4. 5. In SQL Server Profiler, from File menu, click Stop Trace. Review the results from the Deadlock Trace. Maximize the Trace window inside SQL Server Profiler. Click on the event line that contains the Deadlock graph. Review the graph that appears at the bottom of the screen.

Lab: Creating Highly Concurrent SQL Server Applications

L11-3

6.

Hover your mouse over each of the ellipses that represent processes. Note: When you hover your mouse over a process, you will see a pop-up window displaying the TSQL statement that was executed.

7.

Close SQL Server Profiler.

Challenge Exercise 2: Investigating Transaction Isolation Levels (Only if time permits)


Task 1: Load the scripts
1. In SQL Server Management Studio, double-click 62 Lab Exercise 2 2nd Window.sql in Solution Explorer. Right-click the tab at the top of the window that opens and click Close All But This. In SQL Server Management Studio, double-click 61 Lab Exercise 2.sql in Solution Explorer.

2. 3.

Task 2: Execute the code


1. Execute the code step by step by following the instructions in the script files. Note: This exercise involves two script windows. Make sure that you execute only the code for each step and in the correct window as directed by the scripts.

L11-4

Lab: Creating Highly Concurrent SQL Server Applications

Lab: Handling Errors in T-SQL Code

L12-1

Module 12: Handling Errors in T-SQL Code

Lab: Handling Errors in T-SQL Code


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. 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: 4. 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.

5. 6. 7.

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:

8. 9.

i. User name: AdventureWorks\Administrator ii. 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.

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_12_PRJ\6232B_12_PRJ.ssmssln. 15. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.

L12-2

Lab: Handling Errors in T-SQL Code

Exercise 1: Replace @@ERROR based error handling with structured exception handling
Task 1: Review the existing code
1. In Object Explorer, expand Proseware, expand Databases, expand MarketDev, expand Programmability, expand Stored Procedures, right-click Marketing.MoveCampaignBalance, and click Modify. Review the existing stored procedure.

2.

Task 2: Rewrite the stored procedure to use structured exception handling


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE PROCEDURE Marketing.MoveCampaignBalance_Test ( @FromCampaignID int, @ToCampaignID int, @BalanceToMove decimal(18,2) ) AS BEGIN SET XACT_ABORT ON; BEGIN TRY BEGIN TRANSACTION UPDATE Marketing.CampaignBalance SET RemainingBalance -= @BalanceToMove WHERE CampaignID = @FromCampaignID; UPDATE Marketing.CampaignBalance SET RemainingBalance += @BalanceToMove WHERE CampaignID = @ToCampaignID; COMMIT TRANSACTION; END TRY BEGIN CATCH IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION; PRINT 'Unable to move balance'; RETURN 1; -- 7 END CATCH; END; GO

3. 4.

In the toolbar, click Execute. Leave the query window open for use in the next exercise.

Task 3: Test the stored procedure


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
EXEC Marketing.MoveCampaignBalance_Test 3,2,51.50; GO

3.

In the toolbar, click Execute. Note: You should see two messages each indicating that a single row has been updated.

Lab: Handling Errors in T-SQL Code

L12-3

4.

Leave the query window open for use in the next exercise.

Challenge Exercise 2: Add deadlock retry logic to the stored procedure (Only if time permits)
Task 1: Modify the code to re-try on deadlock
1. In SQL Server Management Studio, return to the query window with the Marketing.MoveCampaignBalance_Test stored procedure code. Modify the query as per the code shown below:
ALTER PROCEDURE Marketing.MoveCampaignBalance_Test ( @FromCampaignID int, @ToCampaignID int, @BalanceToMove decimal(18,2) ) AS BEGIN DECLARE @RetriesRemaining int = 5; SET XACT_ABORT ON; WHILE (@RetriesRemaining > 0) BEGIN BEGIN TRY BEGIN TRANSACTION UPDATE Marketing.CampaignBalance SET RemainingBalance -= @BalanceToMove WHERE CampaignID = @FromCampaignID; UPDATE Marketing.CampaignBalance SET RemainingBalance += @BalanceToMove WHERE CampaignID = @ToCampaignID; COMMIT TRANSACTION; SET @RetriesRemaining = 0; END TRY BEGIN CATCH IF (ERROR_NUMBER() = 1205) BEGIN SET @RetriesRemaining -=1; PRINT 'Warning: deadlock retry'; WAITFOR DELAY '00:00:05'; END ELSE BEGIN SET @RetriesRemaining = 0; -- exit the retry loop IF XACT_STATE() <> 0 ROLLBACK TRANSACTION; PRINT 'Unable to move balance'; RETURN 1; END; END CATCH; END; END; GO

2.

3.

In the toolbar, click Execute.

Task 2: Test the stored procedure


1. In SQL Server Management Studio, return to the query window with the EXEC Marketing.MoveCampaignBalance_Test code as shown in the query pane:
EXEC Marketing.MoveCampaignBalance_Test 3,2,51.50; GO

2.

In the toolbar, click Execute.

L12-4

Lab: Handling Errors in T-SQL Code

Note: You should see two messages each indicating that a single row has been updated.

Lab: Designing and Implementing User-Defined Functions

L13-1

Module 13: Designing and Implementing User-Defined Functions

Lab: 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. 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. 4. 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. 5. In Virtual Machine Connection window, click on the Revert toolbar icon. 6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action to complete. 7. 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: 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.

L13-2

Lab: Designing and Implementing User-Defined Functions

Exercise 1: Formatting Phone Numbers


Task 1: Review the design requirements
1. Review the supplied function specifications in the supporting documentation in the Lab section of the Student Manual, for the Phone Number.

Task 2: Design and create the function


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE FUNCTION dbo.FormatPhoneNumber ( @PhoneNumberToFormat nvarchar(16) ) RETURNS nvarchar(16) AS BEGIN DECLARE @Digits nvarchar(16) = ''; DECLARE @Remaining nvarchar(16) = @PhoneNumberToFormat; DECLARE @Character nchar(1); IF LEFT(@Remaining,1) = N'+' RETURN @Remaining; WHILE (LEN(@Remaining) > 0) BEGIN SET @Character = LEFT(@Remaining,1); SET @Remaining = SUBSTRING(@Remaining,2,LEN(@Remaining)); IF (@Character >= N'0') AND (@Character <= N'9') SET @Digits += @Character; END; RETURN CASE LEN(@Digits) WHEN 10 THEN N'(' + SUBSTRING(@Digits,1,3) + N') ' + SUBSTRING(@Digits,4,3) + N'-' + SUBSTRING(@Digits,7,4) WHEN 8 THEN SUBSTRING(@Digits,1,4) + N'-' + SUBSTRING(@Digits,5,4) WHEN 6 THEN SUBSTRING(@Digits,1,3) + N'-' + SUBSTRING(@Digits,4,3) ELSE @Digits END; END; GO

3.

In the toolbar, click Execute.

Task 3: Test the function


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
SELECT SELECT SELECT SELECT SELECT GO dbo.FormatPhoneNumber('+61 3 9485-2342'); dbo.FormatPhoneNumber('415 485-2342'); dbo.FormatPhoneNumber('(41) 5485-2342'); dbo.FormatPhoneNumber('94852342'); dbo.FormatPhoneNumber('85-2342');

3.

In the toolbar, click Execute.

Lab: Designing and Implementing User-Defined Functions

L13-3

Note: The output should resemble the following: +61 3 9485-2342 (415) 485-2342 (415) 485-2342 9485-2342 852-342

Exercise 2: Modifying an Existing Function


Task 1: Review the requirements
1. Review the supplied function specifications in the supporting documentation in the Lab section of the Student Manual, for the dbo.IntegerListToTable function.

Task 2: Design and create the function


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE FUNCTION dbo.IntegerListToTable ( @InputList nvarchar(MAX), @Delimiter nchar(1) = N',') RETURNS @OutputTable TABLE (PositionInList int IDENTITY(1, 1) NOT NULL, IntegerValue int) AS BEGIN DECLARE @RemainingString nvarchar(MAX) = @InputList; DECLARE @DelimiterPosition int; DECLARE @CurrentToken nvarchar(8); WHILE LEN(@RemainingString) > 0 BEGIN SET @DelimiterPosition = CHARINDEX(@Delimiter, @RemainingString); IF (@DelimiterPosition = 0) SET @DelimiterPosition = LEN(@RemainingString) + 1; IF (@DelimiterPosition > 8) SET @DelimiterPosition = 8; SET @CurrentToken = SUBSTRING(@RemainingString,1,@DelimiterPosition - 1); INSERT INTO @OutputTable (IntegerValue) VALUES(CAST(@CurrentToken AS int)); SET @RemainingString = SUBSTRING(@RemainingString, @DelimiterPosition + 1, LEN(@RemainingString)); END; RETURN; END; GO

3.

In the toolbar, click Execute.

Task 3: Test the function


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:

L13-4

Lab: Designing and Implementing User-Defined Functions

SELECT * FROM dbo.IntegerListToTable('234,354253,3242,2',','); GO

3.

In the toolbar, click Execute. Note: The output should resemble the following:

Task 4: Test the function with an alternate delimiter such as the pipe | character
1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
SELECT * FROM dbo.IntegerListToTable('234|354253|3242|2','|'); GO

3.

In the toolbar, click Execute. Note: The output should resemble the following:

Challenge Exercise 3: Resolve a Function-related Performance Issue (Only if time permits)


Task 1: Review the query
1. Review the supplied problematic query in the supporting documentation in the Lab section of the Student Manual.

Task 2: Design an alternate query


1. 2. Right-click the MarketDev database and click New Query. Type the problem query from the supporting documentation and the replacement query in the query pane:
SET STATISTICS TIME ON; GO SELECT dbo.JoinNames(FirstName,MiddleName,LastName) AS FullName FROM Marketing.Prospect

Lab: Designing and Implementing User-Defined Functions

L13-5

ORDER BY FullName; SELECT FirstName + N' ' + CASE WHEN LEN(MiddleName) > 0 THEN MiddleName + N' ' ELSE N'' END + LastName AS FullName FROM Marketing.Prospect ORDER BY FullName; GO

3.

In the toolbar, click Execute.

Task 3: Use SET STATISTICS TIME ON to compare the performance of the new and old
queries
1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
SET STATISTICS TIME ON; GO SELECT dbo.JoinNames(FirstName,MiddleName,LastName) AS FullName FROM Marketing.Prospect ORDER BY FullName; GO SELECT FirstName + N' ' + CASE WHEN LEN(MiddleName) > 0 THEN MiddleName + N' ' ELSE N'' END + LastName AS FullName FROM Marketing.Prospect ORDER BY FullName; GO SET STATISTICS TIME OFF; GO

3.

In the toolbar, click Execute.

L13-6

Lab: Designing and Implementing User-Defined Functions

Note: The execution time for the alternate query should be shorter than the time for the original query. The actual times will vary from computer to computer. The output should resemble the following:

Lab: Ensuring Data Integrity through Constraints

L14-1

Module 14: Ensuring Data Integrity Through Constraints

Lab: 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. 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:

4.

5. 6. 7.

i. ii.
8. 9.

Username: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. 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.

L14-2

Lab: Ensuring Data Integrity through Constraints

Exercise 1: Constraint Design


Task 1: Review the supporting documentation
1. Review the supplied table design requirements in the supporting documentation.

Task 2: Alter the Marketing.Yield table


1. In Object Explorer, expand the Proseware server, expand Databases, right-click the MarketDev database and click New Query. Type the query below in the query pane:
ALTER TABLE Marketing.Yield ALTER COLUMN ProspectID int NOT NULL; GO ALTER TABLE Marketing.Yield ALTER COLUMN LanguageID nchar(6) NOT NULL; GO ALTER TABLE Marketing.Yield ALTER COLUMN YieldOutcome int NOT NULL; GO ALTER TABLE Marketing.Yield ALTER COLUMN RowID uniqueidentifier NOT NULL; GO ALTER TABLE Marketing.Yield ALTER COLUMN LastUpdate datetime2 NOT NULL; GO ALTER TABLE Marketing.Yield ADD CONSTRAINT PK_Yield PRIMARY KEY CLUSTERED (ProspectID, LanguageID); GO ALTER TABLE Marketing.Yield ADD CONSTRAINT FK_Yield_Prospect FOREIGN KEY (ProspectID) REFERENCES Marketing.Prospect(ProspectID); GO ALTER TABLE Marketing.Yield ADD CONSTRAINT FK_Yield_Language FOREIGN KEY (LanguageID) REFERENCES Marketing.Language(LanguageID); GO ALTER TABLE Marketing.Yield ADD CONSTRAINT DF_Yield_YieldOutcome DEFAULT (0) FOR YieldOutcome; GO ALTER TABLE Marketing.Yield ADD CONSTRAINT DF_Yield_RowID DEFAULT (NEWID()) FOR RowID; GO ALTER TABLE Marketing.Yield ADD CONSTRAINT DF_Yield_LastUpdate DEFAULT (SYSDATETIME()) FOR LastUpdate; GO

2.

Lab: Ensuring Data Integrity through Constraints

L14-3

3.

In the toolbar, click Execute.

Challenge Exercise 2: Test the constraints (Only if time permits)


Task 1: Test the default values and data types
1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
INSERT INTO Marketing.Yield (ProspectID, LanguageID, Notes) VALUES (1,'en', 'Excellent outcome'); SELECT * FROM Marketing.Yield; GO

3.

In the toolbar, click Execute. Note: This should execute without errors.

Task 2: Test the primary key


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
INSERT INTO Marketing.Yield (ProspectID, LanguageID, Notes) VALUES (1,'en', 'Another excellent outcome'); GO

3. Inthetoolbar,clickExecute.
Note: This should fail due to the primary key constraint.

Task 3: Test the foreign key reference on language


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
INSERT INTO Marketing.Yield (ProspectID, LanguageID, Notes) VALUES (2,'ex', 'Excellent outcome'); GO

3. Inthetoolbar,clickExecute.
Note: This should fail due to the foreign key reference.

Task 4: Test the foreign key reference on prospect


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
INSERT INTO Marketing.Yield (ProspectID, LanguageID, Notes)

L14-4

Lab: Ensuring Data Integrity through Constraints

VALUES (29292,'en', 'Excellent outcome'); GO

3. Inthetoolbar,clickExecute.
Note: This should fail due to the foreign key reference.

Lab: Responding to Data Manipulation via Triggers

L15-1

Module 15: Responding to Data Manipulation via Triggers

Lab: 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. 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. 4. 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. 5. In Virtual Machine Connection window, click on the Revert toolbar icon. 6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action to complete. 7. 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: 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_15_PRJ\6232B_15_PRJ.ssmssln. 15. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.

L15-2

Lab: Responding to Data Manipulation via Triggers

Exercise 1: Creating and Testing the Audit Trigger


Task 1: Review the supporting documentation and existing system
1. Review the supplied table requirements in the supporting documentation for Marketing.CampaignAudit table. In Object Explorer, expand Proseware, expand Databases, expand MarketDev, expand Tables, expand Marketing.CampaignBalance, and expand Columns. Review the table design.

2.

3.

Task 2: Design a trigger to meet the requirements as stated in the scenario for this
exercise
1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE TRIGGER Marketing.TR_CampaignBalance_Update ON Marketing.CampaignBalance AFTER UPDATE AS BEGIN SET NOCOUNT ON; INSERT Marketing.CampaignAudit (AuditTime, ModifyingUser, RemainingBalance) SELECT SYSDATETIME(), ORIGINAL_LOGIN(), inserted.RemainingBalance FROM deleted INNER JOIN inserted ON deleted.CampaignID = inserted.CampaignID WHERE deleted.RemainingBalance > 10000 OR inserted.RemainingBalance > 10000; END; GO

3.

In the toolbar, click Execute.

Task 3: Write code to test the behavior of the trigger


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
EXEC Marketing.MoveCampaignBalance 3,2,101000; GO SELECT * FROM Marketing.CampaignBalance; GO SELECT * FROM Marketing.CampaignAudit; GO

3.

In the toolbar, click Execute. Note: The output should be similar to the following:

Lab: Responding to Data Manipulation via Triggers

L15-3

Note: The dates and times will depend upon when you execute the code.

Challenge Exercise 2: Improve the Audit Trigger (Only if time permits)


Task 1: Modify the trigger based on the updated requirements
1. In Object Explorer, expand Proseware, expand Databases, expand MarketDev, expand Tables, expand Marketing.CampaignAudit, and expand Triggers. Review the trigger design. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
ALTER TRIGGER Marketing.TR_CampaignBalance_Update ON Marketing.CampaignBalance AFTER UPDATE AS BEGIN SET NOCOUNT ON; INSERT Marketing.CampaignAudit (AuditTime, ModifyingUser, RemainingBalance) SELECT SYSDATETIME(), ORIGINAL_LOGIN(), inserted.RemainingBalance FROM deleted INNER JOIN inserted ON deleted.CampaignID = inserted.CampaignID WHERE ABS(deleted.RemainingBalance - inserted.RemainingBalance) > 10000; END; GO

2. 3. 4.

5.

In the toolbar, click Execute.

Task 2: Delete all rows from the Marketing.CampaignAudit table


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:

L15-4

Lab: Responding to Data Manipulation via Triggers

DELETE FROM Marketing.CampaignAudit; GO

3.

In the toolbar, click Execute.

Task 3: Test the modified trigger


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
SELECT * FROM Marketing.CampaignBalance; GO EXEC Marketing.MoveCampaignBalance 3,2,10100; GO EXEC Marketing.MoveCampaignBalance 3,2,1010; GO SELECT * FROM Marketing.CampaignAudit; GO

3.

In the toolbar, click Execute. Note: The output should be similar to the following:

Note: The dates and times will depend upon when you execute the code.

Lab: Implementing Managed Code in SQL Server

L16-1

Module 16: Implementing Managed Code in SQL Server 2008 R2

Lab: 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: 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. 4. 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. 5. In Virtual Machine Connection window, click on the Revert toolbar icon. 6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action to complete. 7. 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: 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_16_PRJ\6232B_16_PRJ.ssmssln. 15. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar. 1. 2. 3.

Exercise 1: Assess Proposed CLR Code


Task 1: Review the supporting documentation
1. Review the supplied proposed SQLCLR functionality list in the supporting documentation.

L16-2

Lab: Implementing Managed Code in SQL Server

Task 2: For each object listed, determine if implementing it in managed code is


appropriate or not
1. The following components should be included in SQL CLR. Proposed SQLCLR Functionality Should be implemented

Table-valued function that returns a list of files Yes, good use of external access. 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. Yes, good use of string handling.

No, only involves data access.

Yes, good use of external access.

No, only involves data access. No, not an object oriented database.

Exercise 2: Implement a CLR Assembly


Task 1: Ensure the database is configured appropriately to support an
EXTERNAL_ACCESS assembly
1. In Object Explorer, under Proseware expand Databases, expand System Databases, and right-click the master database and click New Query. Type the query below in the query pane:
EXEC sp_configure 'clr enabled',1; GO RECONFIGURE; GO ALTER DATABASE MarketDev SET TRUSTWORTHY ON; GO

2.

3.

In the toolbar, click Execute.

Task 2: Catalog the assembly and the functions contained within it


1. In Object Explorer, under Proseware expand Databases, and right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE ASSEMBLY SQLCLRDemo FROM 'D:\6232B_Labs\6232B_16_PRJ\6232B_16_PRJ\SQLCLRDemo.DLL' WITH PERMISSION_SET = EXTERNAL_ACCESS; GO

2.

Lab: Implementing Managed Code in SQL Server

L16-3

3. 4.

In the toolbar, click Execute. Type the query below in the query pane:
SELECT * FROM sys.assemblies; SELECT * FROM sys.assembly_files; GO

5. 6.

Highlight the query above and in the toolbar click Execute. Type the query below in the query pane:
CREATE FUNCTION dbo.IsValidEmailAddress(@email NVARCHAR(4000)) RETURNS BIT AS EXTERNAL NAME SQLCLRDemo.[SQLCLRDemo.CLRDemoClass].IsValidEmailAddress; GO

7. 8.

Highlight the query above and in the toolbar click Execute. Type the query below in the query pane:
CREATE FUNCTION dbo.FormatAustralianPhoneNumber(@PhoneNumber NVARCHAR(4000)) RETURNS NVARCHAR(4000) AS EXTERNAL NAME SQLCLRDemo.[SQLCLRDemo.CLRDemoClass].FormatAustralianPhoneNumber; GO

9.

Highlight the query above and in the toolbar click Execute.

10. Type the query below in the query pane:


CREATE FUNCTION dbo.FolderList(@RequiredPath NVARCHAR(4000),@FileMask NVARCHAR(4000)) RETURNS TABLE (FileName NVARCHAR(4000)) AS EXTERNAL NAME SQLCLRDemo.[SQLCLRDemo.CLRDemoClass].FolderList; GO

11. Highlight the query above and in the toolbar click Execute.

Task 3: Test the functions contained within the assembly


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
SELECT dbo.IsValidEmailAddress('test@somewhere.com'); 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

3.

In the toolbar, click Execute.

L16-4

Lab: Implementing Managed Code in SQL Server

Challenge Exercise 3: Implement a CLR User-defined Aggregate and CLR Userdefined Data Type (Only if time permits)
Task 1: Catalog and test the user-defined aggregate
1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE AGGREGATE dbo.AggString(@s nvarchar(4000)) RETURNS nvarchar(4000) EXTERNAL NAME SQLCLRDemo.[SQLCLRDemo.AggString]; GO SELECT dbo.AggString(DISTINCT ProductNumber) FROM Marketing.Product WHERE Color = 'Black'; GO

3.

In the toolbar, click Execute.

Task 2: Catalog and test the user-defined data type


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE TYPE dbo.zVarChar EXTERNAL NAME SQLCLRDemo.[SQLCLRDemo.zVarChar]; GO

3. 4. 5.

In the toolbar, click Execute. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE TABLE dbo.TestTable ( RecID int IDENTITY(1,1), TextValue zVarchar ); GO

6. 7. 8.

In the toolbar, click Execute. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
INSERT INTO dbo.TestTable VALUES('Some GO SELECT TextValue.ToString(), TextValue.CompressedLength(), TextValue.CompressionPercentage() FROM dbo.TestTable; GO compressible data');

Lab: Implementing Managed Code in SQL Server

L16-5

SELECT AVG(TextValue.CompressionPercentage()) FROM dbo.TestTable; GO DROP TABLE dbo.TestTable; GO

9.

In the toolbar, click Execute.

10. Right-click the MarketDev database and click New Query. 11. Type the query below in the query pane:
DECLARE @TestString zVarChar; SET @TestString = 'Some compressible PRINT @TestString.CompressedValue(); GO PRINT zVarChar::Compress( 'Some compressible GO value');

value';

12. In the toolbar, click Execute.

L16-6

Lab: Implementing Managed Code in SQL Server

Lab: Storing XML Data in SQL Server

L17-1

Module 17: Storing XML Data in SQL Server 2008 R2

Lab: Storing XML Data 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. 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:

4.

5. 6. 7.

i. ii.
8. 9.

Username: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. 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_17_PRJ\6232B_17_PRJ.ssmssln. 15. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.

L17-2

Lab: Storing XML Data in SQL Server

Exercise 1: Appropriate Usage of XML Data Storage in SQL Server


Task 1: Review the list of Use Cases
1. Review the supplied Use Cases requirements in the supporting documentation.

Task 2: Determine whether each is appropriate for XML


1. The following components should be implemented Use Cases Requirements Existing XML data that is stored but not processed. Storing attributes for a customer. Relational data that is being passed through a system but not processed within it. Storing attributes that are nested (that is attributes stored within attributes). Should be implemented Yes Reason Data is already XML and does not need to be processed. Should be database columns. Only if the data is being sent and received as XML.

No Perhaps

Yes

Not standard relational data.

Exercise 2: Investigate the Storage of XML Data in Variables


Task 1: Review and execute the queries, and review the results
1. 2. Double-click the script 61 Lab Exercise 2.sql, in Solution Explorer. Highlight and execute the first command block as shown:

USE tempdb; GO

3.

Highlight and execute scripts 17.1 to 17.9 separately, comparing the results of each script with the script comment.
-- Script 17.1 Create a table with an xml column CREATE TABLE #Invoices ( InvoiceID int, SalesDate datetime, CustomerID int, ItemList xml); GO -- Script 17.2 Use implicit casting to assign an xml variable DECLARE @itemString nvarchar(2000); SET @itemString = '<Items> <Item ProductID="2" Quantity="3"/> <Item ProductID="4" Quantity="1"/> </Items>'; DECLARE @itemDoc xml; SET @itemDoc = @itemString;

Lab: Storing XML Data in SQL Server

L17-3

INSERT INTO #Invoices VALUES (1, GetDate(), 2, @itemDoc); SELECT * FROM #Invoices; GO

-- Script 17.3 Use implicit casting to assign a string constant INSERT INTO #Invoices VALUES (1, GetDate(), 2, '<Items> <Item ProductID="2" Quantity="3"/> <Item ProductID="4" Quantity="1"/> </Items>'); SELECT * FROM #Invoices; GO -- Script 17.4 Explicitly cast string to xml DECLARE @varToCast nvarchar(2000); SET @varToCast = '<Items> <Item ProductID="2" Quantity="3"/> <Item ProductID="4" Quantity="1"/> </Items>'; DECLARE @castedDoc xml; SET @castedDoc = CAST(@varToCast AS xml); INSERT INTO #Invoices VALUES(1, GetDate(), 2, @castedDoc); SELECT * FROM #Invoices; GO -- Script 17.5 Explicitly convert string to xml DECLARE @varToConvert nvarchar(2000); SET @varToConvert = '<Items> <Item ProductID="2" Quantity="3"/> <Item ProductID="4" Quantity="1"/> </Items>'; DECLARE @convertedDoc xml; SET @convertedDoc = CONVERT(xml, @varToConvert); INSERT INTO #Invoices VALUES(1, GetDate(), 2, @convertedDoc); SELECT * FROM #Invoices; GO -- Script 17.6 Well-formed document. This will succeed INSERT INTO #Invoices VALUES (1, GetDate(), 2, '<?xml version="1.0" ?> <Items> <Item ProductID="2" Quantity="3"/> <Item ProductID="4" Quantity="1"/> </Items>'); SELECT * FROM #Invoices; GO -- Script 17.7 Well-formed fragment. This will succeed INSERT INTO #Invoices VALUES (1, GetDate(), 2, '<Item ProductID="2" Quantity="3"/> <Item ProductID="4" Quantity="1"/>');

L17-4

Lab: Storing XML Data in SQL Server

SELECT * FROM #Invoices; GO -- Script 17.8 Not well-formed. This will fail INSERT INTO #Invoices VALUES (1, GetDate(), 2, '<Items> <Item ProductID="2" Quantity="3"/> <Item ProductID="4" Quantity="1"/>'); SELECT * FROM #Invoices; GO -- Script 17.9 Clean up the temporary table DROP TABLE #Invoices; GO

4.

Review the results from each script. Query Number 17.1 17.2 Query Title Create a table with an xml column. Use implicit casting to assign an xml variable. Use implicit casting to assign a string constant. Explicitly cast string to xml. Explicitly convert string to xml. Well-formed document. This will succeed. Output Command completed successfully. One row is inserted.

17.3

One row is inserted.

17.4 17.5 17.6

One row is inserted. One row is inserted. One row is inserted.

17.7 17.8

Well-formed fragment. This will succeed. One row is inserted. Not well-formed. This will fail. Command will fail due to incorrect XML format. Command completed successfully.

17.9

Clean up the temporary table.

Exercise 3: Investigate the use of XML Schema Collections


Task 1: Review and execute the queries, and review the results
1. 2. Double-click the script 71 Lab Exercise 3.sql, in Solution Explorer. Highlight and execute the first command block as shown:

USE tempdb; GO

Lab: Storing XML Data in SQL Server

L17-5

3.

Highlight and execute scripts 17.10 to 17.11 separately, comparing the results of each script with the script comment.
-- Script 17.10 Create an xml schema collection for resumes CREATE XML SCHEMA COLLECTION ResumeSchemaCollection AS N'<?xml version="1.0" ?> <xsd:schema targetNamespace="http://schemas.adventure-works.com/EmployeeResume" xmlns="http://schemas.adventure-works.com/EmployeeResume" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema" > <xsd:element name="resume"> <xsd:complexType> <xsd:sequence> <xsd:element name="name" type="xsd:string" minOccurs="1" maxOccurs="1"/> <xsd:element name="employmentHistory"> <xsd:complexType> <xsd:sequence minOccurs="1" maxOccurs="unbounded"> <xsd:element name="employer"> <xsd:complexType> <xsd:simpleContent> <xsd:extension base="xsd:string"> <xsd:attribute name="endDate" use="optional"/> </xsd:extension> </xsd:simpleContent> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema>'; GO -- Script 17.11 Retrieve information about the components in the schema collection -Note that schemas are stored as components, not as the original -schema text SELECT cp.* FROM sys.xml_schema_components AS cp JOIN sys.xml_schema_collections AS c ON cp.xml_collection_id = c.xml_collection_id WHERE c.name = 'ResumeSchemaCollection'; GO

4.

Review the results from each script. Query Number 17.10 Query Title Create an xml schema collection for resumes. Output Schema collection is created.

17.11

Retrieve information about Ten rows showing how the individual components of the components in the the XML schema collection are stored. Note the schema collection values in the kind_desc column.

L17-6

Lab: Storing XML Data in SQL Server

Challenge Exercise 4: Investigate the Creation of Database Columns Based on XML (Only if time permits)
Task 1: Review and execute the queries, and review the results
1. 2. Double-click the script 81 Lab Exercise 4.sql, in Solution Explorer. Highlight and execute the first command block as shown:

USE tempdb; GO

3.

Highlight and execute scripts 17.12 to 17.20 separately, comparing the results of each script with the script comment.
-- Script 17.12 Create a table with a typed xml column for documents CREATE TABLE #EmployeeResume ( EmployeeID int, Resume xml (ResumeSchemaCollection)); GO -- Script 17.13 Insert valid XML INSERT INTO #EmployeeResume VALUES (1, '<?xml version="1.0" ?> <resume xmlns="http://schemas.adventure-works.com/EmployeeResume"> <name>Guy Gilbert</name> <employmentHistory> <employer endDate="2000-07-07">Northwind Traders</employer> <employer>Adventure Works</employer> </employmentHistory> </resume>'); SELECT * FROM #EmployeeResume; GO -- Script 17.14 Try to insert invalid XML (this will fail) INSERT INTO #EmployeeResume VALUES (1, '<?xml version="1.0" ?> <resume xmlns = "http://schemas.adventure-works.com/EmployeeResume"> <name>Guy Gilbert</name> </resume>'); GO -- Script 17.15 Use CONTENT keyword CREATE TABLE #EmployeeResumeContent ( EmployeeID int, Resume xml (CONTENT ResumeSchemaCollection)); GO -- Script 17.16 Insert a single document into a CONTENT column INSERT INTO #EmployeeResumeContent VALUES (1, '<?xml version="1.0" ?> <resume xmlns="http://schemas.adventure-works.com/EmployeeResume"> <name>Guy Gilbert</name> <employmentHistory> <employer endDate="2000-07-07">Northwind Traders</employer> <employer>Adventure Works</employer> </employmentHistory> </resume>');

Lab: Storing XML Data in SQL Server

L17-7

SELECT * FROM #EmployeeResumeContent; GO -- Script 17.17 Insert multiple valid elements into a CONTENT column INSERT INTO #EmployeeResumeContent VALUES (1, ' <resume xmlns="http://schemas.adventure-works.com/EmployeeResume"> <name>Guy Gilbert</name> <employmentHistory> <employer endDate="2000-07-07">Northwind Traders</employer> </employmentHistory> </resume> <resume xmlns="http://schemas.adventure-works.com/EmployeeResume"> <name>Guy Gilbert</name> <employmentHistory> <employer endDate="2000-07-07">Northwind Traders</employer> <employer>Adventure Works</employer> </employmentHistory> </resume>'); SELECT * FROM #EmployeeResumeContent; GO -- Script 17.18 Use DOCUMENT keyword CREATE TABLE #EmployeeResumeDocument ( EmployeeID int, Resume xml (DOCUMENT ResumeSchemaCollection)); GO -- Script 17.19 Insert a single document into a DOCUMENT column INSERT INTO #EmployeeResumeDocument VALUES (1, '<?xml version="1.0" ?> <resume xmlns="http://schemas.adventure-works.com/EmployeeResume"> <name>Guy Gilbert</name> <employmentHistory> <employer endDate="2000-07-07">Northwind Traders</employer> <employer>Adventure Works</employer> </employmentHistory> </resume>'); SELECT * FROM #EmployeeResumeDocument; GO -- Script 17.20 Insert multiple valid elements into a DOCUMENT column. This will fail. INSERT INTO #EmployeeResumeDocument VALUES (1, ' <resume xmlns="http://schemas.adventure-works.com/EmployeeResume"> <name>Guy Gilbert</name> <employmentHistory> <employer endDate="2000-07-07">Northwind Traders</employer> </employmentHistory> </resume> <resume xmlns="http://schemas.adventure-works.com/EmployeeResume"> <name>Guy Gilbert</name> <employmentHistory> <employer endDate="2000-07-07">Northwind Traders</employer> <employer>Adventure Works</employer> </employmentHistory> </resume>');

L17-8

Lab: Storing XML Data in SQL Server

SELECT * FROM #EmployeeResumeDocument; GO

4.

Review the results from each script. Query Number 17.12 Query Title Output

Create a table with a typed xml column Command completed successfully. for documents. Insert valid XML. Try to insert invalid XML (this will fail). One row is inserted. No rows are inserted. Even though wellformed XML was supplied, it did not meet the required schema. Command completed successfully. One row is inserted.

17.13 17.14

17.15 17.16

Use CONTENT keyword. Insert a single document into a CONTENT column. Insert multiple valid elements into a CONTENT column.

17.17

One row is inserted. Note the row is inserted, even though no root element is present. Command completed successfully. One row is inserted.

17.18 17.19

Use DOCUMENT keyword. Insert a single document into a DOCUMENT column. Insert multiple valid elements into a DOCUMENT column. This will fail.

17.20

No row is inserted as no root element is present.

Lab: Querying XML Data in SQL Server

L18-1

Module 18: Querying XML Data in SQL Server 2008 R2

Lab: Querying XML Data 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. 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. 4. 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. 5. In Virtual Machine Connection window, click on the Revert toolbar icon. 6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action to complete. 7. 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: 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_18_PRJ\6232B_18_PRJ.ssmssln. 15. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.

Exercise 1: Learn to query SQL Server data as XML


Task 1: Review and execute the query and review the results
1. Double-click the script 51 Lab Exercise 1.sql, in Solution Explorer.

L18-2

Lab: Querying XML Data in SQL Server

In the query below, highlight and execute scripts 18.1 to 18.9 separately, comparing the results of each script with the script comment.
-- Script 18.1 FOR XML AUTO Use MarketDev GO SELECT ProductID, ProductName, ListPrice FROM Marketing.Product FOR XML AUTO; GO -- Script 18.2 ELEMENTS with RAW mode SELECT ProductID, ProductName, ListPrice FROM Marketing.Product FOR XML RAW, ELEMENTS; GO -- Script 18.3 NULL columns with ELEMENTS SELECT ProductID, ProductName, Color FROM Marketing.Product FOR XML AUTO, ELEMENTS XSINIL; GO -- Script 18.4 Note the effect of the column alias compared to 18.3 SELECT ProductID, ProductName, Color FROM Marketing.Product AS Product FOR XML AUTO, ELEMENTS XSINIL; GO -- Script 18.5 Inline XSD schema SELECT ProductID, ProductName, ListPrice FROM Marketing.Product AS Product FOR XML AUTO, XMLSCHEMA; GO -- Script 18.6 Nested XML with TYPE SELECT ProductID, ProductName, ListPrice, (SELECT Description.ProductModelID, Description.Description FROM Marketing.ProductDescription AS Description WHERE Description.ProductModelID = Product.ProductModelID FOR XML AUTO, ELEMENTS, TYPE) AS Description FROM Marketing.Product AS Product; GO -- Script 18.7 PATH mode SELECT ProductID AS "@ProductID", ProductName AS "*", Size AS "Description/@Size", Color AS "Description/text()" FROM Marketing.Product AS Product FOR XML PATH; GO -- Script 18.8 ROOT directive SELECT ProductID, ProductName, ListPrice FROM Marketing.Product AS Product FOR XML AUTO, ROOT('AvailableItems'); GO -- Script 18.9 Named element in RAW modes SELECT ProductID, ProductName, ListPrice

Lab: Querying XML Data in SQL Server

L18-3

FROM Marketing.Product AS Product FOR XML RAW('AvailableItem'); GO

Query Number 18.1

Query Title FOR XML AUTO.

Output One row per product. Note the element name is based on the table name. Note the element centric output and the element name is row. Products without color show xsi:nil=true. Other products show the color.

18.2

ELEMENTS with RAW mode. NULL columns with ELEMENTS.

18.3

18.4

Note the effect of the Note the element name is now Product, based on the alias column alias name of the table. compared to 18.3. Inline XSD schema. Nested XML with TYPE. PATH Mode. Note the inclusion of an XSD schema. Note that rows with a value in the Description column show that value as XML. Note how the output can be constructed with a PATH query. In the output locate each of the elements in the SELECT clause. Note the AvailableItems root node. Note the AvailableItem ElementName.

18.5 18.6

18.7

18.8 18.9

ROOT directive. Named element in RAW modes.

Exercise 2: Write a stored procedure returning XML


Task 1: Review the requirements
1. Review the supplied stored procedure specification in the supporting documentation for WebStock.GetAvailableModelsAsXML.

Task 2: Create the stored procedure


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE PROCEDURE WebStock.GetAvailableModelsAsXML AS BEGIN SELECT p.ProductID, p.ProductName, p.ListPrice, p.Color, p.SellStartDate, pm.ProductModelID,

L18-4

Lab: Querying XML Data in SQL Server

pm.ProductModel FROM Marketing.Product AS p INNER JOIN Marketing.ProductModel AS pm ON p.ProductModelID = pm.ProductModelID WHERE p.SellStartDate IS NOT NULL AND p.SellEndDate IS NULL ORDER BY p.SellStartDate, p.ProductName FOR XML RAW('AvailableModel'), ROOT('AvailableModels'); END; GO

3.

In the toolbar, click Execute.

Task 3: Test the stored procedure


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
EXEC WebStock.GetAvailableModelsAsXML; GO

3.

In the toolbar, click Execute.

Challenge Exercise 3: Write a stored procedure that updates using XML (Only if time permits)
Task 1: Review the requirements
1. Review the supplied stored procedure specification in the supporting documentation for Marketing.UpdateSalesTerritoriesByXML.

Task 2: Create the stored procedure


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE PROCEDURE Marketing.UpdateSalesTerritoriesByXML ( @SalespersonMods xml ) AS BEGIN DECLARE @Handle int; EXEC master.dbo.sp_xml_preparedocument @Handle OUTPUT, @SalespersonMods; UPDATE sp SET sp.SalesTerritoryID = spm.SalesTerritoryID FROM Marketing.Salesperson AS sp INNER JOIN OPENXML(@Handle,'SalespersonMods/SalespersonMod/Mods/Mod',1) WITH (SalesTerritoryID int '@SalesTerritoryID', SalespersonID int '../../@SalespersonID') AS spm ON sp.SalespersonID = spm.SalespersonID; EXEC master.dbo.sp_xml_removedocument @Handle; END; GO

3.

In the toolbar, click Execute.

Lab: Querying XML Data in SQL Server

L18-5

Task 3: Test the stored procedure


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
DECLARE @SalespersonMods xml; SET @SalespersonMods = '<SalespersonMods> <SalespersonMod SalespersonID="274"> <Mods> <Mod SalesTerritoryID="3"/> </Mods> </SalespersonMod> <SalespersonMod SalespersonID="278"> <Mods> <Mod SalesTerritoryID="4"/> </Mods> </SalespersonMod> </SalespersonMods>'; EXEC Marketing.UpdateSalesTerritoriesByXML @SalespersonMods; GO SELECT * FROM Marketing.Salesperson; GO

3.

In the toolbar, click Execute.

L18-6

Lab: Querying XML Data in SQL Server

Lab: Working with SQL Server Spatial Data

L19-1

Module 19: Working with SQL Server 2008 R2 Spatial Data

Lab: Working with SQL Server Spatial Data


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. 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. 4. 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. 5. In Virtual Machine Connection window, click on the Revert toolbar icon. 6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action to complete. 7. 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: 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_19_PRJ\6232B_19_PRJ.ssmssln. 15. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.

Exercise 1: Familiarity With Geometry Data Type


Task 1: Review and execute the sample script
1. Double-click the script 51 Lab Exercise 1.sql, in Solution Explorer.

L19-2

Lab: Working with SQL Server Spatial Data

2.

In the query below, highlight and execute scripts 19.1 to 19.9 separately, comparing the results of each script with the script comment.
-- Script 19.1 Draw a square USE tempdb; GO DECLARE @Shape GEOMETRY; SET @Shape = GEOMETRY::STGeomFromText('POLYGON ((10 10, 10 40, 40 40, 40 10, 10 10))',0); SELECT @Shape AS Square; GO -- Script 19.2 Try an invalid value - note the 6522 error and the wrapped error message BEGIN TRY DECLARE @Shape GEOMETRY; SET @Shape = GEOMETRY::STPolyFromText('POLYGON((0 0,20 15,10 10,0 15,5 5))', 0); END TRY BEGIN CATCH SELECT ERROR_MESSAGE(); END CATCH; GO -- Script 19.3 Draw a more complex shape DECLARE @Shape GEOMETRY; SET @Shape = GEOMETRY::STGeomFromText('POLYGON ((10 10, 5 5,10 40, 40 40, 45 45,40 10, 10 10))',0); SELECT @Shape AS ColoredArea; GO -- Script 19.4 Multiple shapes DECLARE @Shape1 GEOMETRY, @Shape2 GEOMETRY; SET @Shape1 = GEOMETRY::STGeomFromText('POLYGON ((10 10, 5 5,10 40, 40 40, 45 45,40 10, 10 10))',0); SET @Shape2 = GEOMETRY::STGeomFromText('POLYGON ((60 25, 55 5,60 40, 90 40, 95 45,90 10, 60 25))',0); SELECT @Shape1 AS Multishapes UNION ALL SELECT @Shape2; GO -- Script 19.5 Intersecting shapes DECLARE @Shape1 GEOMETRY, @Shape2 GEOMETRY; SET @Shape1 = GEOMETRY::STGeomFromText('POLYGON ((10 10, 5 5,10 40, 40 40, 45 45,40 10, 10 10))',0); SET @Shape2 = GEOMETRY::STGeomFromText('POLYGON ((30 25, 25 5,30 40, 60 40, 65 45,60 20, 30 25))',0); SELECT @Shape1 AS Overlapping UNION ALL SELECT @Shape2; GO -- Script 19.6 Union of the two shapes DECLARE @Shape1 GEOMETRY, @Shape2 GEOMETRY; SET @Shape1 = GEOMETRY::STGeomFromText('POLYGON ((10 10, 5 5,10 40, 40 40, 45 45,40 10, 10 10))',0); SET @Shape2 = GEOMETRY::STGeomFromText('POLYGON ((30 25, 25 5,30 40, 60 40, 65 45,60 20, 30 25))',0); SELECT @Shape1.STUnion(@Shape2) AS Unioned; GO -- Script 19.7 Intersection of shapes

Lab: Working with SQL Server Spatial Data

L19-3

DECLARE @Shape1 GEOMETRY, @Shape2 GEOMETRY; SET @Shape1 = GEOMETRY::STGeomFromText('POLYGON ((10 10, 5 5,10 40, 40 40, 45 45,40 10, 10 10))',0); SET @Shape2 = GEOMETRY::STGeomFromText('POLYGON ((30 25, 25 5,30 40, 60 40, 65 45,60 20, 30 25))',0); SELECT @Shape1 AS Intersected UNION ALL SELECT @Shape2 UNION ALL SELECT @Shape1.STIntersection(@Shape2); GO -- Script 19.8 Draw Australia DECLARE @Australia geometry; SET @Australia = geometry::STGeomFromText('MULTIPOLYGON (((146.91639709472656 43.704837799072266, 145.92631530761719 -43.223194122314453, 145.4830322265625 -42.650703430175781, 145.38616943359375 -42.464195251464844, 145.82795715332031 -42.501945495605469, 145.07258605957031 -41.577156066894531, 144.90054321289063 -40.845218658447266, 146.58587646484375 -41.291374206542969, 147.80001831054688 -41.147617340087891, 148.25955200195313 -40.902679443359375, 148.47319030761719 -41.075611114501953, 148.52291870117188 -41.788833618164062, 148.12933349609375 -42.806430816650391, 147.34538269042969 -43.239715576171875, 146.91639709472656 -43.704837799072266)), ((142.54121398925781 -10.898410797119141, 142.84793090820313 -11.07573413848877, 143.02713012695313 -11.901708602905273, 143.37675476074219 -12.104367256164551, 143.17445373535156 -12.517995834350586, 143.57481384277344 -12.796828269958496, 143.94683837890625 -14.448851585388184, 144.26838684082031 -14.575309753417969, 144.58901977539063 -14.352115631103516, 144.73284912109375 -14.650595664978027, 145.38800048828125 -15.030624389648438, 145.52920532226563 -16.473457336425781, 146.19784545898438 -17.49560546875, 146.12821960449219 -18.239631652832031, 146.52542114257813 -19.065319061279297, 147.61637878417969 -19.546205520629883, 148.17660522460938 20.079109191894531, 148.90739440917969 -20.185646057128906, 148.77070617675781 -20.637355804443359, 149.30514526367188 -21.04315185546875, 149.76042175292969 -22.415578842163086, 150.22093200683594 22.713462829589844, 150.1484375 -22.306673049926758, 150.89729309082031 -22.66114616394043, 151.00613403320313 -23.582916259765625, 151.93380737304688 -24.14051628112793, 152.27639770507813 24.724786758422852, 152.52163696289063 -24.800580978393555, 152.68940734863281 -25.296232223510742, 153.03501892089844 -25.454490661621094, 153.27273559570313 -26.210777282714844, 153.29037475585938 26.993001937866211, 153.14988708496094 -27.324020385742188, 153.60006713867188 -28.111736297607422, 153.69715881347656 -28.823896408081055, 153.14321899414063 -30.682428359985352, 153.17552185058594 31.401203155517578, 152.37985229492188 -32.859695434570312, 151.96830749511719 -32.987766265869141, 151.56816101074219 -33.503929138183594, 150.96563720703125 -35.236156463623047, 150.4251708984375 35.6771354675293, 150.18850708007813 -37.329910278320312, 149.91603088378906 -37.777362823486328, 148.24066162109375 -38.080898284912109, 147.02470397949219 -38.824363708496094, 146.50288391113281 38.876548767089844, 146.72958374023438 -39.163665771484375, 145.73957824707031 -38.70556640625, 145.70791625976563 -38.424533843994141, 145.17349243164063 -38.048786163330078, 144.61477661132813 38.228744506835938, 144.95124816894531 -38.438838958740234, 143.56846618652344 -38.9527587890625, 142.10769653320313

L19-4

Lab: Working with SQL Server Spatial Data

-38.41265869140625, 141.42892456054688 -38.439579010009766, 140.21568298339844 37.624660491943359, 140.02616882324219 -37.229286193847656, 140.02934265136719 -36.578449249267578, 139.64814758300781 -36.024333953857422, 139.57157897949219 -35.5973014831543, 138.5560302734375 35.8480339050293, 138.40083312988281 -35.739955902099609, 138.63349914550781 -35.535476684570312, 138.77128601074219 -34.910751342773438, 138.30516052246094 -34.339134216308594, 137.88699340820313 35.313907623291016, 137.15071105957031 -35.455646514892578, 137.31202697753906 -35.053794860839844, 137.70594787597656 -35.008373260498047, 137.71554565429688 -34.442138671875, 138.11616516113281 33.499790191650391, 138.39241027832031 -33.276569366455078, 138.0718994140625 -32.730152130126953, 138.02352905273438 -33.048313140869141, 137.66084289550781 -33.297161102294922, 137.27078247070313 33.934112548828125, 136.30978393554688 -34.514995574951172, 135.91609191894531 -35.190467834472656, 134.91389465332031 -33.347339630126953, 134.41212463378906 -33.240230560302734, 134.31146240234375 33.011432647705078, 134.44065856933594 -32.724918365478516, 134.04069519042969 -32.325000762939453, 133.32875061035156 -32.320106506347656, 132.90133666992188 -32.072917938232422, 132.38589477539063 32.131229400634766, 131.48382568359375 -31.617877960205078, 129.38905334472656 -31.781232833862305, 127.46874237060547 -32.364013671875, 126.26261138916016 -32.417392730712891, 124.45204925537109 33.127155303955078, 123.56221771240234 -34.025871276855469, 122.37458801269531 -34.161888122558594, 121.61318206787109 -33.953533172607422, 119.97515106201172 -34.103199005126953, 119.53349304199219 34.562080383300781, 118.87643432617188 -34.588871002197266, 118.41074371337891 -35.073368072509766, 117.99697875976563 -35.195281982421875, 116.45505523681641 -35.0837516784668, 115.25058746337891 34.405483245849609, 115.189453125 -33.737743377685547, 115.61216735839844 -33.749591827392578, 115.76168060302734 -33.558475494384766, 115.950927734375 -32.190639495849609, 115.26192474365234 30.786540985107422, 115.11587524414063 -29.680290222167969, 114.83406066894531 -28.885986328125, 114.16830444335938 -28.016206741333008, 114.12889099121094 -27.367696762084961, 113.23877716064453 26.145689010620117, 113.29524993896484 -26.040727615356445, 113.63665008544922 -26.555038452148438, 113.94303894042969 -26.649562835693359, 113.52482604980469 -25.673364639282227, 114.08432006835938 26.4920597076416, 114.29875946044922 -26.521648406982422, 114.25409698486328 -26.271642684936523, 114.38450622558594 -26.254417419433594, 114.38618469238281 -26.000068664550781, 113.58287048339844 24.596633911132812, 113.56556701660156 -24.26606559753418, 113.96568298339844 -23.464162826538086, 113.82909393310547 -22.548957824707031, 114.10423278808594 -22.02070426940918, 114.23101043701172 22.503608703613281, 114.43566131591797 -22.598531723022461, 114.66001129150391 -22.076744079589844, 116.62245941162109 -20.820150375366211, 117.80059051513672 -20.741361618041992, 118.17213439941406 20.454486846923828, 118.93798065185547 -20.300273895263672, 119.13991546630859 -20.007402420043945, 120.01618194580078

Lab: Working with SQL Server Spatial Data

L19-5

-20.100902557373047, 121.07581329345703 -19.659969329833984, 121.77999877929688 18.685775756835938, 122.40011596679688 -18.226715087890625, 122.28913879394531 -17.381425857543945, 122.94200134277344 -16.566312789916992, 123.62236785888672 -17.562946319580078, 123.71196746826172 17.092321395874023, 124.03050994873047 -17.231498718261719, 124.11570739746094 -16.957944869995117, 123.75660705566406 -16.678993225097656, 123.77950286865234 -16.373815536499023, 125.05001068115234 16.513069152832031, 124.54142761230469 -16.245037078857422, 124.62816619873047 -15.640926361083984, 124.89231109619141 -15.449649810791016, 125.31279754638672 -15.607682228088379, 125.35932159423828 14.7875337600708, 126.06686401367188 -14.677942276000977, 126.47202301025391 -14.054102897644043, 126.74971008300781 -14.333209991455078, 127.05709075927734 -13.766800880432129, 127.73275756835938 14.178533554077148, 128.16622924804688 -14.686156272888184, 128.26980590820313 -15.359770774841309, 128.66252136230469 -14.869436264038086, 129.40008544921875 -14.975923538208008, 129.8359375 15.261057853698731, 130.05227661132813 -14.802887916564941, 129.63021850585938 -14.288888931274414, 130.40965270996094 -13.467185020446777, 130.66716003417969 -12.741966247558594, 131.15493774414063 12.613780975341797, 131.06253051757813 -12.429638862609863, 131.23200988769531 -12.251283645629883, 131.74357604980469 -12.383670806884766, 132.95478820800781 -12.152227401733398, 132.71826171875 11.606078147888184, 132.22822570800781 -11.460931777954102, 132.40925598144531 -11.301631927490234, 133.13264465332031 -11.516201972961426, 133.76284790039063 -11.934375762939453, 134.96577453613281 12.0462007522583, 135.33218383789063 -12.369593620300293, 135.85267639160156 -12.171424865722656, 136.29487609863281 -12.558222770690918, 136.50227355957031 -12.494205474853516, 136.63816833496094 12.099803924560547, 136.9947509765625 -12.353300094604492, 136.67274475097656 -13.20579719543457, 136.03456115722656 -13.467802047729492, 136.168212890625 -13.874351501464844, 136.08430480957031 14.186027526855469, 135.66123962402344 -14.66370964050293, 135.62026977539063 -14.956218719482422, 136.89080810546875 -16.008792877197266, 137.27737426757813 -16.014326095581055, 138.4639892578125 16.825523376464844, 139.16641235351563 -16.976600646972656, 139.45198059082031 -17.414670944213867, 140.02192687988281 -17.744054794311523, 140.26387023925781 -17.813465118408203, 140.91120910644531 17.614999771118164, 141.33607482910156 -16.940177917480469, 141.91496276855469 -15.209720611572266, 141.67181396484375 -14.7398042678833, 141.87205505371094 -14.097315788269043, 141.71598815917969 13.792503356933594, 141.802490234375 -13.029497146606445, 142.12260437011719 -12.685539245605469, 141.88218688964844 -12.450845718383789, 142.32931518554688 -11.140419960021973, 142.54121398925781 10.898410797119141 )))',0); SELECT @Australia AS Australia; GO -- Script 19.9 Draw Australia with a buffer around it DECLARE @Australia geometry;

L19-6

Lab: Working with SQL Server Spatial Data

SET @Australia = geometry::STGeomFromText('MULTIPOLYGON (((146.91639709472656 43.704837799072266, 145.92631530761719 -43.223194122314453, 145.4830322265625 -42.650703430175781, 145.38616943359375 -42.464195251464844, 145.82795715332031 -42.501945495605469, 145.07258605957031 -41.577156066894531, 144.90054321289063 -40.845218658447266, 146.58587646484375 -41.291374206542969, 147.80001831054688 -41.147617340087891, 148.25955200195313 -40.902679443359375, 148.47319030761719 -41.075611114501953, 148.52291870117188 -41.788833618164062, 148.12933349609375 -42.806430816650391, 147.34538269042969 -43.239715576171875, 146.91639709472656 -43.704837799072266)), ((142.54121398925781 -10.898410797119141, 142.84793090820313 -11.07573413848877, 143.02713012695313 -11.901708602905273, 143.37675476074219 -12.104367256164551, 143.17445373535156 -12.517995834350586, 143.57481384277344 -12.796828269958496, 143.94683837890625 -14.448851585388184, 144.26838684082031 -14.575309753417969, 144.58901977539063 -14.352115631103516, 144.73284912109375 -14.650595664978027, 145.38800048828125 -15.030624389648438, 145.52920532226563 -16.473457336425781, 146.19784545898438 -17.49560546875, 146.12821960449219 -18.239631652832031, 146.52542114257813 -19.065319061279297, 147.61637878417969 -19.546205520629883, 148.17660522460938 20.079109191894531, 148.90739440917969 -20.185646057128906, 148.77070617675781 -20.637355804443359, 149.30514526367188 -21.04315185546875, 149.76042175292969 -22.415578842163086, 150.22093200683594 22.713462829589844, 150.1484375 -22.306673049926758, 150.89729309082031 -22.66114616394043, 151.00613403320313 -23.582916259765625, 151.93380737304688 -24.14051628112793, 152.27639770507813 24.724786758422852, 152.52163696289063 -24.800580978393555, 152.68940734863281 -25.296232223510742, 153.03501892089844 -25.454490661621094, 153.27273559570313 -26.210777282714844, 153.29037475585938 26.993001937866211, 153.14988708496094 -27.324020385742188, 153.60006713867188 -28.111736297607422, 153.69715881347656 -28.823896408081055, 153.14321899414063 -30.682428359985352, 153.17552185058594 31.401203155517578, 152.37985229492188 -32.859695434570312, 151.96830749511719 -32.987766265869141, 151.56816101074219 -33.503929138183594, 150.96563720703125 -35.236156463623047, 150.4251708984375 35.6771354675293, 150.18850708007813 -37.329910278320312, 149.91603088378906 -37.777362823486328, 148.24066162109375 -38.080898284912109, 147.02470397949219 -38.824363708496094, 146.50288391113281 38.876548767089844, 146.72958374023438 -39.163665771484375, 145.73957824707031 -38.70556640625, 145.70791625976563 -38.424533843994141, 145.17349243164063 -38.048786163330078, 144.61477661132813 38.228744506835938, 144.95124816894531 -38.438838958740234, 143.56846618652344 -38.9527587890625, 142.10769653320313 -38.41265869140625, 141.42892456054688 -38.439579010009766, 140.21568298339844 37.624660491943359, 140.02616882324219 -37.229286193847656, 140.02934265136719 -36.578449249267578, 139.64814758300781 -36.024333953857422, 139.57157897949219 -35.5973014831543, 138.5560302734375 35.8480339050293, 138.40083312988281 -35.739955902099609, 138.63349914550781 -35.535476684570312, 138.77128601074219 -34.910751342773438, 138.30516052246094 -34.339134216308594, 137.88699340820313 35.313907623291016, 137.15071105957031 -35.455646514892578, 137.31202697753906 -35.053794860839844, 137.70594787597656 -35.008373260498047, 137.71554565429688 -34.442138671875, 138.11616516113281 33.499790191650391,

Lab: Working with SQL Server Spatial Data

L19-7

138.39241027832031 -33.276569366455078, 138.0718994140625 -32.730152130126953, 138.02352905273438 -33.048313140869141, 137.66084289550781 -33.297161102294922, 137.27078247070313 33.934112548828125, 136.30978393554688 -34.514995574951172, 135.91609191894531 -35.190467834472656, 134.91389465332031 -33.347339630126953, 134.41212463378906 -33.240230560302734, 134.31146240234375 33.011432647705078, 134.44065856933594 -32.724918365478516, 134.04069519042969 -32.325000762939453, 133.32875061035156 -32.320106506347656, 132.90133666992188 -32.072917938232422, 132.38589477539063 32.131229400634766, 131.48382568359375 -31.617877960205078, 129.38905334472656 -31.781232833862305, 127.46874237060547 -32.364013671875, 126.26261138916016 -32.417392730712891, 124.45204925537109 33.127155303955078, 123.56221771240234 -34.025871276855469, 122.37458801269531 -34.161888122558594, 121.61318206787109 -33.953533172607422, 119.97515106201172 -34.103199005126953, 119.53349304199219 34.562080383300781, 118.87643432617188 -34.588871002197266, 118.41074371337891 -35.073368072509766, 117.99697875976563 -35.195281982421875, 116.45505523681641 -35.0837516784668, 115.25058746337891 34.405483245849609, 115.189453125 -33.737743377685547, 115.61216735839844 -33.749591827392578, 115.76168060302734 -33.558475494384766, 115.950927734375 -32.190639495849609, 115.26192474365234 30.786540985107422, 115.11587524414063 -29.680290222167969, 114.83406066894531 -28.885986328125, 114.16830444335938 -28.016206741333008, 114.12889099121094 -27.367696762084961, 113.23877716064453 26.145689010620117, 113.29524993896484 -26.040727615356445, 113.63665008544922 -26.555038452148438, 113.94303894042969 -26.649562835693359, 113.52482604980469 -25.673364639282227, 114.08432006835938 26.4920597076416, 114.29875946044922 -26.521648406982422, 114.25409698486328 -26.271642684936523, 114.38450622558594 -26.254417419433594, 114.38618469238281 -26.000068664550781, 113.58287048339844 24.596633911132812, 113.56556701660156 -24.26606559753418, 113.96568298339844 -23.464162826538086, 113.82909393310547 -22.548957824707031, 114.10423278808594 -22.02070426940918, 114.23101043701172 22.503608703613281, 114.43566131591797 -22.598531723022461, 114.66001129150391 -22.076744079589844, 116.62245941162109 -20.820150375366211, 117.80059051513672 -20.741361618041992, 118.17213439941406 20.454486846923828, 118.93798065185547 -20.300273895263672, 119.13991546630859 -20.007402420043945, 120.01618194580078 -20.100902557373047, 121.07581329345703 -19.659969329833984, 121.77999877929688 18.685775756835938, 122.40011596679688 -18.226715087890625, 122.28913879394531 -17.381425857543945, 122.94200134277344 -16.566312789916992, 123.62236785888672 -17.562946319580078, 123.71196746826172 17.092321395874023, 124.03050994873047 -17.231498718261719, 124.11570739746094 -16.957944869995117, 123.75660705566406 -16.678993225097656, 123.77950286865234 -16.373815536499023, 125.05001068115234 16.513069152832031, 124.54142761230469 -16.245037078857422, 124.62816619873047 -15.640926361083984, 124.89231109619141 -15.449649810791016, 125.31279754638672 -15.607682228088379, 125.35932159423828 14.7875337600708,

L19-8

Lab: Working with SQL Server Spatial Data

126.06686401367188 -14.677942276000977, 126.47202301025391 -14.054102897644043, 126.74971008300781 -14.333209991455078, 127.05709075927734 -13.766800880432129, 127.73275756835938 14.178533554077148, 128.16622924804688 -14.686156272888184, 128.26980590820313 -15.359770774841309, 128.66252136230469 -14.869436264038086, 129.40008544921875 -14.975923538208008, 129.8359375 15.261057853698731, 130.05227661132813 -14.802887916564941, 129.63021850585938 -14.288888931274414, 130.40965270996094 -13.467185020446777, 130.66716003417969 -12.741966247558594, 131.15493774414063 12.613780975341797, 131.06253051757813 -12.429638862609863, 131.23200988769531 -12.251283645629883, 131.74357604980469 -12.383670806884766, 132.95478820800781 -12.152227401733398, 132.71826171875 11.606078147888184, 132.22822570800781 -11.460931777954102, 132.40925598144531 -11.301631927490234, 133.13264465332031 -11.516201972961426, 133.76284790039063 -11.934375762939453, 134.96577453613281 12.0462007522583, 135.33218383789063 -12.369593620300293, 135.85267639160156 -12.171424865722656, 136.29487609863281 -12.558222770690918, 136.50227355957031 -12.494205474853516, 136.63816833496094 12.099803924560547, 136.9947509765625 -12.353300094604492, 136.67274475097656 -13.20579719543457, 136.03456115722656 -13.467802047729492, 136.168212890625 -13.874351501464844, 136.08430480957031 14.186027526855469, 135.66123962402344 -14.66370964050293, 135.62026977539063 -14.956218719482422, 136.89080810546875 -16.008792877197266, 137.27737426757813 -16.014326095581055, 138.4639892578125 16.825523376464844, 139.16641235351563 -16.976600646972656, 139.45198059082031 -17.414670944213867, 140.02192687988281 -17.744054794311523, 140.26387023925781 -17.813465118408203, 140.91120910644531 17.614999771118164, 141.33607482910156 -16.940177917480469, 141.91496276855469 -15.209720611572266, 141.67181396484375 -14.7398042678833, 141.87205505371094 -14.097315788269043, 141.71598815917969 13.792503356933594, 141.802490234375 -13.029497146606445, 142.12260437011719 -12.685539245605469, 141.88218688964844 -12.450845718383789, 142.32931518554688 -11.140419960021973, 142.54121398925781 10.898410797119141 )))',0); SELECT @Australia.STBuffer(1) UNION ALL SELECT @Australia; GO

3.

Review the results from each script. Remember to click on the Spatial results tab to see the output. Query Number 19.1 19.2 Query Title Draw a square. Try an invalid value - note the 6522 error and the wrapped error message. Output A square is drawn. A .NET error is returned. Scroll to the right to read the full message. Note how specific the message is.

Lab: Working with SQL Server Spatial Data

L19-9

Query Number 19.3

Query Title Draw a more complex shape.

Output The shape is drawn. Note how a polygon is represented in text in the query. Two shapes are drawn. The shapes are moved to intersect. A combined shape is drawn. The two intersecting shapes and the intersection are drawn. Australian map is drawn. Note the calculation of a buffer region around the map.

19.4 19.5 19.6 19.7

Multiple shapes. Intersecting shapes. Union of two shapes. Intersection of shapes.

19.8 19.9

Draw Australia. Draw Australia with a buffer around it.

Exercise 2: Adding Spatial Data to an Existing Table


Task 1: Add a Location column
1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
ALTER TABLE Marketing.ProspectLocation ADD Location GEOGRAPHY NULL; GO

3.

In the toolbar, click Execute.

Task 2: Write code to assign values to this column


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
UPDATE Marketing.ProspectLocation SET Location = GEOGRAPHY::STGeomFromText( 'POINT(' + CAST(Longitude AS varchar(20)) + ' ' + CAST(Latitude AS varchar(20)) + ')',4326); GO

3.

In the toolbar, click Execute.

Task 3: Drop the existing Latitude and Longitude columns


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:

L19-10

Lab: Working with SQL Server Spatial Data

ALTER TABLE Marketing.ProspectLocation DROP COLUMN Latitude; GO ALTER TABLE Marketing.ProspectLocation DROP COLUMN Longitude; GO

3.

In the toolbar, click Execute.

Challenge Exercise 3: Business Application of Spatial Data (Only if time permits)


Task 1: Review the requirements
1. Review the supporting documentation for details of the required stored procedure.

Task 2: Create a spatial index


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE SPATIAL INDEX IX_ProspectLocation_Location ON Marketing.ProspectLocation (Location); GO

3.

In the toolbar, click Execute.

Task 3: Design and implement the Stored Procedure


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE PROCEDURE Marketing.GetNearbyProspects ( @ProspectID int, @DistanceInKms int ) AS BEGIN DECLARE @LocationToTest GEOGRAPHY; SET @LocationToTest = (SELECT pl.Location FROM Marketing.ProspectLocation AS pl WHERE pl.ProspectID = @ProspectID); SELECT pl.Location.STDistance(@LocationToTest) / 1000 AS Distance, p.ProspectID, p.LastName, p.FirstName, p.WorkPhoneNumber, p.CellPhoneNumber, pl.AddressLine1, pl.AddressLine2, pl.City, pl.Location.Long AS Longitude, pl.Location.Lat AS Latitude FROM Marketing.Prospect AS p INNER JOIN Marketing.ProspectLocation AS pl ON p.ProspectID = pl.ProspectID

Lab: Working with SQL Server Spatial Data

L19-11

WHERE pl.Location.STDistance(@LocationToTest) < (@DistanceInKms * 1000) AND p.ProspectID <> @ProspectID ORDER BY Distance; END; GO

3.

In the toolbar, click Execute.

Task 4: Test the procedure


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
EXEC Marketing.GetNearbyProspects 2,50;

3.

In the toolbar, click Execute.

L19-12

Lab: Working with SQL Server Spatial Data

Lab: Working with Full -Text Indexes and Queries

L20-1

Module 20: Working with Full-Text Indexes and Queries

Lab: Working with Full -Text Indexes and Queries


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. 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. 4. 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. 5. In Virtual Machine Connection window, click on the Revert toolbar icon. 6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action to complete. 7. 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: 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_20_PRJ\6232B_20_PRJ.ssmssln. 15. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.

L20-2

Lab: Working with Full -Text Indexes and Queries

Exercise 1: Implement a full-text index


Task 1: Create a full-text catalog
1. In Object Explorer, expand the Proseware server, expand Databases, right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE FULLTEXT CATALOG DefaultFullTextCatalog AS DEFAULT; GO

2.

3.

In the toolbar, click Execute.

Task 2: Create a full-text index on the Description column of the


Marketing.ProductDescription table
1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE FULLTEXT INDEX ON Marketing.ProductDescription(Description) KEY INDEX PK_ProductDescription WITH CHANGE_TRACKING OFF, NO POPULATION; GO

3.

In the toolbar, click Execute.

Task 3: Enable automatic change tracking for the index


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
ALTER FULLTEXT INDEX ON Marketing.ProductDescription SET CHANGE_TRACKING AUTO; GO

3.

In the toolbar, click Execute. Note that a warning might be returned when you execute the above command, even though the command executed successfully. If a warning appears, it can be ignored.

Task 4: Check to see that the population of the index is complete


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
SELECT is_enabled, has_crawl_completed, crawl_type, crawl_start_date, crawl_end_date FROM sys.fulltext_indexes; GO

3. 4.

In the toolbar, click Execute. Re-execute the query until the has_crawl_completed column shows the value 1.

Lab: Working with Full -Text Indexes and Queries

L20-3

Task 5: Write a simple CONTAINS query


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
SELECT d.ProductDescriptionID, d.Description FROM Marketing.ProductDescription AS d WHERE CONTAINS(d.Description,'bottle') ORDER BY d.ProductDescriptionID; GO

3.

In the toolbar, click Execute. Note: Three rows are returned.

Task 6: Write a CONTAINS query that searches for two words


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
SELECT d.ProductDescriptionID, d.Description FROM Marketing.ProductDescription AS d WHERE CONTAINS(d.Description,'elastic AND lycra') ORDER BY d.ProductDescriptionID; GO

3.

In the toolbar, click Execute. Note: One row is returned.

Task 7: Write a CONTAINS query that uses INFLECTIONAL forms


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
SELECT d.ProductDescriptionID, d.Description FROM Marketing.ProductDescription AS d WHERE CONTAINS(d.Description,'FORMSOF(INFLECTIONAL,wash)') ORDER BY d.ProductDescriptionID; GO

3.

In the toolbar, click Execute. Note: One row is returned.

Exercise 2: Implement a stoplist


Task 1: Review the existing system stopwords
1. Right-click the MarketDev database and click New Query.

L20-4

Lab: Working with Full -Text Indexes and Queries

2.

Type the query below in the query pane:


SELECT * FROM sys.fulltext_system_stopwords WHERE language_id = 1033; GO

3.

In the toolbar, click Execute. A list of system stop words for the English language is returned.

Task 2: Create a full-text stoplist


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
CREATE FULLTEXT STOPLIST CommonWords; GO

3.

In the toolbar, click Execute.

Task 3: Add words to the stoplist


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
ALTER ADD ALTER ADD GO FULLTEXT STOPLIST CommonWords 'Bike' LANGUAGE 1033; FULLTEXT STOPLIST CommonWords 'AdventureWorks' LANGUAGE 1033;

3.

In the toolbar, click Execute.

Task 4: View the stoplist


1. 2. Right-click the MarketDev database and click New Query. Type the query below in the query pane:
SELECT * FROM sys.fulltext_stoplists; GO SELECT * FROM sys.fulltext_stopwords; GO

3.

In the toolbar, click Execute. A list of stoplists and stopwords is returned.

Challenge Exercise 3: Create a stored procedure to implement a full-text search (Only if time permits)
Task 1: Review the supporting documentation
1. Review the supporting documentation for specification for a new stored procedure.

Task 2: Design, implement, and test the stored procedure


1. Right-click the MarketDev database and click New Query.

Lab: Working with Full -Text Indexes and Queries

L20-5

2.

Type the query below in the query pane:


CREATE PROCEDURE Marketing.GetRelevantDescriptions ( @PhraseToSearch nvarchar(1000) ) AS BEGIN SELECT d.ProductDescriptionID, d.Description, ft.RANK AS Ranking FROM Marketing.ProductDescription AS d INNER JOIN FREETEXTTABLE(Marketing.ProductDescription, Description, @PhraseToSearch) AS ft ON d.ProductDescriptionID = ft.[KEY] WHERE d.LanguageID = 'en' ORDER BY ft.RANK DESC; END; GO EXEC Marketing.GetRelevantDescriptions 'strong frame'; GO EXEC Marketing.GetRelevantDescriptions 'serious competition'; GO

3.

In the toolbar, click Execute. Note: The first query returns twenty rows. The second query returns five rows.

L20-6

Lab: Working with Full -Text Indexes and Queries

You might also like