0% found this document useful (0 votes)
29 views572 pages

SQL in A Day

This eBook provides an overview of the ePUB format and its customizable features for enhancing the reading experience. It introduces 'Sams Teach Yourself T-SQL in One Hour a Day' by Alison Balter, which covers various aspects of SQL Server and T-SQL, including database creation, table management, and stored procedures. The document also includes acknowledgments, a dedication, and information about the author and her extensive background in computer training and consulting.

Uploaded by

ruipspires
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
29 views572 pages

SQL in A Day

This eBook provides an overview of the ePUB format and its customizable features for enhancing the reading experience. It introduces 'Sams Teach Yourself T-SQL in One Hour a Day' by Alison Balter, which covers various aspects of SQL Server and T-SQL, including database creation, table management, and stored procedures. The document also includes acknowledgments, a dedication, and information about the author and her extensive background in computer training and consulting.

Uploaded by

ruipspires
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 572

About This eBook

ePUB is an open, industry-standard format for eBooks. However, support of ePUB and its many
features varies across reading devices and applications. Use your device or app settings to customize the
presentation to your liking. Settings that you can customize often include font, font size, single or double
column, landscape or portrait mode, and figures that you can click or tap to enlarge. For additional
information about the settings and features on your reading device or app, visit the device manufacturer’s
Web site.
Many titles include programming code or configuration examples. To optimize the presentation of these
elements, view the eBook in single-column, landscape mode and adjust the font size to the smallest
setting. In addition to presenting code and configurations in the reflowable text format, we have included
images of the code that mimic the presentation found in the print book; therefore, where the reflowable
format may compromise the presentation of the code listing, you will see a “Click here to view code
image” link. Click the link to view the print-fidelity code image. To return to the previous page viewed,
click the Back button on your device or app.
Sams Teach Yourself T-SQL in One Hour a Day

Alison Balter

800 East 96th Street, Indianapolis, Indiana 46240 USA


Sams Teach Yourself T-SQL in One Hour a Day
Copyright © 2016 by Pearson Education, Inc.
All rights reserved. No part of this book shall be reproduced, stored in a retrieval system, or transmitted
by any means, electronic, mechanical, photocopying, recording, or otherwise, without written permission
from the publisher. No patent liability is assumed with respect to the use of the information contained
herein. Although every precaution has been taken in the preparation of this book, the publisher and author
assume no responsibility for errors or omissions. Nor is any liability assumed for damages resulting from
the use of the information contained herein.
ISBN-13: 978-0-672-33743-7
ISBN-10: 0-672-33743-6
Library of Congress Cataloging-in-Publication Data: 2015910413
Printed in the United States of America
First Printing October 2015
Editor-in-Chief
Greg Wiegand Acquisitions Editor
Joan Murray Development Editor
Charlotte Kughen Managing Editor
Kristy Hart Project Editor
Andrew Beaster Copy Editor
Language Logistics LLC,
Chrissy White Indexer
Erika Millen
Proofreader
Sarah Kearns Technical Editor
David Walker
Theodor Richardson Publishing Coordinator
Cindy Teeters Media Producer
Dan Scherf Interior Designer
Gary Adair Cover Designer
Mark Shirar Compositor
codeMantra Trademarks
All terms mentioned in this book that are known to be trademarks or service marks have been
appropriately capitalized. Sams Publishing cannot attest to the accuracy of this information. Use of a term
in this book should not be regarded as affecting the validity of any trademark or service mark.
Warning and Disclaimer
Every effort has been made to make this book as complete and as accurate as possible, but no warranty or
fitness is implied. The information provided is on an “as is” basis. The author and the publisher shall
have neither liability nor responsibility to any person or entity with respect to any loss or damages arising
from the information contained in this book.
Special Sales
For information about buying this title in bulk quantities, or for special sales opportunities (which may
include electronic versions; custom cover designs; and content particular to your business, training goals,
marketing focus, or branding interests), please contact our corporate sales department at
[email protected] or (800) 382-3419.
For government sales inquiries, please contact [email protected].
For questions about sales outside the U.S., please contact [email protected].
Table of Contents

Introduction
1 Database Basics
What Is a Database?
What Is a Table?
What Is a Database Diagram?
What Is a View?
What Is a Stored Procedure?
What Is a User-Defined Function?
What Is a Trigger?
2 SQL Server Basics
Versions of SQL Server 2014 Available
SQL Server Components
Introduction to Microsoft SQL Server Management Studio
Connecting to a Database Server
Installing the Sample Files
3 Creating a SQL Server Database
Creating the Database
Defining Database Options
The Transaction Log
Attaching to an Existing Database
4 Working with SQL Server Tables
Creating SQL Server Tables
Adding Fields to the Tables You Create
Working with Constraints
Creating an Identity Specification
Adding Computed Columns
Working with User-Defined Data Types
Adding and Modifying Indexes
Saving Your Table
5 Working with Table Relationships
An Introduction to Relationships
Creating and Working with Database Diagrams
Working with Table Relationships
Designating Table and Column Specifications
Adding a Relationship Name and Description
Determining When Foreign Key Relationships Constrain the Data Entered in a Column
Designating Insert and Update Specifications
6 Getting to Know the SELECT Statement
Introducing T-SQL
Working with the SELECT Statement
Adding on the FROM Clause
Including the WHERE Clause
Using the ORDER BY Clause
7 Taking the SELECT Statement to the Next Level
Adding the DISTINCT Keyword
Working with the FOR XML Clause
Working with the GROUP BY Clause
Including Aggregate Functions in Your SQL Statements
Taking Advantage of the HAVING Clause
Creating Top Values Queries
8 Building SQL Statements Based on Multiple Tables
Working with Join Types
9 Powerful Join Techniques
Utilizing Full Joins
Taking Advantage of Self-Joins
Exploring the Power of Union Queries
Working with Subqueries
Using the INTERSECT Operator
Working with the EXCEPT Operator
10 Modifying Data with Action Queries
The UPDATE Statement
The INSERT Statement
The SELECT INTO Statement
The DELETE Statement
The TRUNCATE Statement
11 Getting to Know the T-SQL Functions
Working with Numeric Functions
Taking Advantage of String Functions
Exploring the Date/Time Functions
Working with Nulls
12 Working with SQL Server Views
An Introduction to Views
Using T-SQL to Create or Modify a View
13 Using T-SQL to Design SQL Server Stored Procedures
The Basics of Working with Stored Procedures
Declaring and Working with Variables
Controlling the Flow
14 Stored Procedure Techniques Every Developer Should Know
The SET NOCOUNT Statement
Using the @@ Functions
Working with Parameters
Errors and Error Handling
15 Power Stored Procedure Techniques
Modifying Data with Stored Procedures
Stored Procedures and Transactions
16 Stored Procedure Special Topics
Stored Procedures and Temporary Tables
Stored Procedures and Cursors
Stored Procedures and Security
17 Building and Working with User-Defined Functions
Scalar Functions
18 Creating and Working with Triggers
Creating Triggers
Creating an Insert Trigger
Creating an Update Trigger
Creating a Delete Trigger
Downsides of Triggers
19 Authentication
The Basics of Security
Types of Authentication
Creating Logins
Creating Roles
20 SQL Server Permissions Validation
Types of Permissions
Getting to Know Table Permissions
Getting to Know View Permissions
Getting to Know Stored Procedure Permissions
Getting to Know Function Permissions
Implementing Column-Level Security
21 Configuring, Maintaining, and Tuning SQL Server
Selecting and Tuning Hardware
Configuring and Tuning SQL Server
22 Maintaining the Databases You Build
Backing Up Your Databases
Restoring a Database
The Database Engine Tuning Advisor
Creating and Working with Database Maintenance Plans
23 Performance Monitoring
Executing Queries in SQL Server Management Studio
Displaying and Analyzing the Estimated Execution Plan
Adding Indexes to Allow Queries to Execute More Efficiently
Setting Query Options
SQL Server Profiler
24 Installing and Upgrading SQL Server
Installing SQL Server 2014 Enterprise Edition
Installing SQL Server Management Studio
Index
About the Author

Alison Balter is the president of InfoTech Services Group, Inc., a computer consulting firm based in
Venice Beach, California. Alison is a highly experienced independent trainer and consultant specializing
in Windows applications training and development. During her 30 years in the computer industry, she has
trained and consulted with many corporations and government agencies. Since Alison founded InfoTech
Services Group, Inc. (formerly InfoTechnology Partners) in 1990, its client base has expanded to include
major corporations and government agencies such as Cisco, Shell Oil, Accenture, AIG Insurance,
Northrop, the Drug Enforcement Administration, Prudential Insurance, Transamerica Insurance, Fox
Broadcasting, the United States Navy, the United States Marines, the University of Southern California
(USC), Massachusetts Institute of Technology (MIT), and others.
Alison is the author of more than 300 internationally marketed computer training videos, including 18
Access 2000 videos, 35 Access 2002 videos, 15 Access 2003 videos, a complete series of both user and
developer videos on Access 2007, and Access 2010 and Access 2013 user videos. Alison travels
throughout North America giving training seminars in Microsoft Access and Microsoft SQL Server.
Alison is also author of 14 books published by Sams Publishing including: Alison Balter’s Mastering
Access 95 Development, Alison Balter’s Mastering Access 97 Development, Alison Balter’s Mastering
Access 2000 Development, Alison Balter’s Mastering Access 2002 Desktop Development, Alison
Balter’s Mastering Access 2002 Enterprise Development, Alison Balter’s Mastering Microsoft Access
Office 2003, Teach Yourself Microsoft Office Access 2003 in 24 Hours, Access Office 2003 in a Snap,
Alison Balter’s Mastering Access 2007 Development, a power user book on Microsoft Access 2007,
Using Access 2010, Access 2013 Absolute Beginner’s Guide, and Teach Yourself SQL Express 2005 in
24 Hours.
An active participant in many user groups and other organizations, Alison is a past president of the
Independent Computer Consultants Association of Los Angeles and of the Los Angeles Clipper Users’
Group. She is also past president of the Ventura County Professional Women’s Network. Alison is a
Microsoft Access MVP and was selected as Ventura County Woman Business Owner of the Year for
2012/2013.
On a personal note, Alison keeps herself busy skiing, taking yoga classes, running, walking, lifting
weights, hiking, and traveling. She most enjoys spending time with her husband, Dan, their daughter
Alexis, and their son Brendan.
Contact Alison via [email protected] or visit InfoTech Services Group’s website at
www.TechIsMyThing.com.
Dedication

Many people are important in my life, but there is no one as special as my husband Dan. I dedicate
this book to Dan. Thank you for your ongoing support, for your dedication to me, for your
unconditional love, and for your patience. Without you, I’m not sure how I would make it through life.
Thank you for sticking with me through the good times and the bad! There’s nobody I’d rather spend
forever with than you.
I also want to thank God for giving me the gift of gab, a wonderful career, an incredible husband, two
beautiful children, a spectacular area to live in, a very special home, and an awesome life. Through
your grace, I am truly blessed.
Acknowledgments

Authoring books is not an easy task. Special thanks go to the following wonderful people who helped
make this book possible and, more important, who give my life meaning:
Dan Balter (my incredible husband), for his ongoing support, love, encouragement, friendship, and, as
usual, patience with me while I authored this book. Dan, words cannot adequately express the love and
appreciation I feel for all that you are and all that you do for me. You treat me like a princess! Thank you
for being the phenomenal person you are, and thank you for loving me for who I am and for supporting me
during the difficult times. I enjoy not only sharing our career successes, but even more I enjoy sharing the
lives of our beautiful children, Alexis and Brendan. I look forward to continuing to reach highs we never
dreamed of.
Alexis Balter (my daughter and confidante), for giving life a special meaning. Your intelligence, drive,
and excellence in all that you do are truly amazing. Alexis, I know that you will go far in life. I am so
proud of you. Even in these difficult teenage years, your wisdom and inner beauty shine through. Finally,
thanks for being my walking partner. I love the conversations that we have when we walk together.
Brendan Balter (my wonderful son and amazing athlete), for showing me the power of persistence.
Brendan, you are relatively small, but, boy, are you mighty! I have never seen such tenacity and fortitude
in a young person. You are able to tackle people twice your size just through your incredible spirit and
your remarkable athletic ability. Your imagination and creativity are amazing! Thank you for your
sweetness, your sensitivity, and your unconditional love. I really enjoy our times together. Most of all,
thank you for reminding me how important it is to have a sense of humor.
Charlotte and Bob Roman (Mom and Dad), for believing in me and sharing in both the good times and the
bad. Mom and Dad, without your special love and support, I never would have become who I am today. I
want you to know that I think that you both are amazing! I want to be just like you when I grow up and I am
88!
Al Ludington, for giving me a life worth living. You somehow walk the fine line between being there and
setting limits, between comforting me and confronting me. Words cannot express how much your
unconditional love means to me. Thanks for showing me that a beautiful mind is not such a bad thing after
all.
Pam Smith, for being one of the most special people in my life. It didn’t take long after we met for me to
figure out that you would be someone who would have a deep impact on my life. I love you for your
spirit, your brilliance, and your inner beauty. Friends forever!
Sue Lopez, for being an absolutely wonderful friend. You inspire me with your music, your love, your
friendship, and your faith in God. Whenever I am having a bad day, I picture you singing “Dear God” or
“Make Me Whole,” and suddenly my day gets better. Thank you for the gift of friendship.
Roz and Ron Carriere, for supporting my endeavors and for encouraging me to pursue my writing. It
means a lot to know that you guys are proud of me for what I do. I enjoy our times together as a family.
Herb and Maureen Balter (my honorary dad and mom), for being such a wonderful father-in-law and
mother-in-law. I want you to know how special you are to me. I appreciate your acceptance and your
warmth. I also appreciate all you have done for Dan and me. I am grateful to have you in my life.
Mary Forman, for not only being one of the most special clients that I have ever had, but also for being a
wonderful friend. You are a ray of sunshine in my day and are a pleasure to work with.
Reverend James, for being an ongoing spiritual inspiration to me. I absolutely love and benefit from your
weekly messages. I feel blessed to be an integral part of your congregation.
To all my friends at Federal Defense Industries, Phil, Sharyn, Ross, Randye, Steve, and Elaine, who I
have not only enjoyed being with and getting to know through the years, but who have also contributed in
many ways to my success in business.
Greggory Peck from Blast Through Learning, for your contribution to my success in this industry. I believe
that the opportunities you gave me early on have helped me reach a level in this industry that would have
been much more difficult for me to reach on my own. Most of all, Greggory, thanks for your love and
friendship. I love you bro!
Joan Murray, Mark Renfrow, and Andy Beaster for making my experience with Sams a positive one. I
know that you all worked very hard to ensure that this book came out on time and with the best quality
possible. Without you, this book wouldn’t have happened. I have really enjoyed working with all of you
over these past several months. I appreciate your thoughtfulness and your sensitivity to my schedule and
commitments outside this book. It is nice to work with people who appreciate me as a person, not just as
an author.
We Want to Hear from You!

As the reader of this book, you are our most important critic and commentator. We value your opinion and
want to know what we’re doing right, what we could do better, what areas you’d like to see us publish in,
and any other words of wisdom you’re willing to pass our way.
We welcome your comments. You can email or write to let us know what you did or didn’t like about this
book—as well as what we can do to make our books better.
Please note that we cannot help you with technical problems related to the topic of this book.
When you write, please be sure to include this book’s title and author as well as your name and email
address. We will carefully review your comments and share them with the author and editors who worked
on the book.
Email: [email protected]
Mail: Sams Publishing
ATTN: Reader Feedback
800 East 96th Street
Indianapolis, IN 46240 USA
Reader Services

Visit our website and register this book at informit.com/register for convenient access to any updates,
downloads, or errata that might be available for this book.
Introduction

Many excellent books about T-SQL are available, so how is this one different? In talking to the many
people I meet in my travels around the country, I have heard one common complaint. Instead of the host of
wonderful books available to expert database administrators (DBAs), most SQL Server readers yearn for
a book targeted toward the beginning-to-intermediate DBA or developer. They want a book that starts at
the beginning, ensures that they have no gaps in their knowledge, and takes them through some of the more
advanced aspects of SQL Server. Along the way, they want to acquire volumes of practical knowledge
that they can easily port into their own applications. I wrote Sams Teach Yourself T-SQL in One Hour a
Day with those requests in mind.
This book begins by providing you with some database basics. In Lesson 1, “Database Basics,” you get a
summary of all the components that are covered through the remainder of the book.
Lesson 2, “SQL Server Basics,” teaches you the basics of working with SQL Server Management Studio.
You learn about the versions of SQL Server available. You then find out how to connect with a database
server and install the sample files.
In Lesson 3, “Creating a SQL Server Database,” you see how to create a new SQL Server database. The
SQL Server database is a container within which you will place all the other objects you learn about
throughout the book.
Lessons 4 through 18 cover tables, relationships, the T-SQL language, views, stored procedures,
functions, and triggers. These objects are at the heart of every SQL Server database. Lesson 4, “Working
with SQL Server Tables,” explains how to work with tables. Then you move on to Lesson 5, “Working
with Table Relationships,” which covers how to work with table relationships.
Knowledge of the T-SQL language is an important aspect of SQL Server. Probably the most used keyword
used in T-SQL is SELECT. Lesson 6, “Getting to Know the SELECT Statement,” delves into the SELECT
statement in quite a bit of detail. Lesson 7, “Taking the SELECT Statement to the Next Level,” expands on
Lesson 6 by covering some more sophisticated T-SQL techniques. You then move on to Lesson 8,
“Building SQL Statements Based on Multiple Tables,” where you find out how you can build T-SQL
statements based on data from multiple tables. Lesson 9, “Powerful Join Techniques,” builds on Lesson 8
to provide you with different techniques you can use to join tables. Not only can you use T-SQL to
retrieve data, but you can also use it to modify data. Lesson 10, “Modifying Data with Action Queries,”
shows you how to modify data with action queries. Lesson 11, “Getting to Know the T-SQL Functions,”
introduces you to many of the built-in T-SQL functions, such as DataAdd, DateDiff, and Upper.
These built-in functions prove invaluable for building database applications.
Another important SQL Server object is the view. Lesson 12, “Working with SQL Server Views,” shows
you how to build and work with views. Lesson 13, “Using T-SQL to Design SQL Server Stored
Procedures,” begins the in-depth coverage of stored procedures. Lessons 14, 15, and 16 continue to build
on each other, each providing more sophisticated coverage of stored procedures and their uses.
Lesson 17, “Building and Working with User-Defined Functions,” provides you with an alternative to
stored procedures: user-defined functions. Lesson 18, “Creating and Working with Triggers,” shows you
how you can use triggers to respond to inserts, updates, and deletes.
The last six lessons cover security and administration. You learn about SQL Server authentication and
permissions validation and how you can take advantage of both to properly secure your databases. The
lessons in Part III also show you how to configure, maintain, and tune the SQL Servers that you manage.
Without proper care, even the fastest hardware could run a database that is abysmally slow!
Finally, this book uses the sample database called AdventureWorks2014. Lesson 2 covers the process of
installing the sample database. Also, all the sample code created in this book are available in a script file
that you can open and execute from a SQL Server Management Studio query.
SQL Server, and the T-SQL language, are powerful and exciting. With the keys to deliver all that it offers,
you can produce applications that provide much satisfaction as well as many financial rewards. After
poring over this hands-on guide and keeping it nearby for handy reference, you too can become masterful
at working with SQL Server and T-SQL. This book is dedicated to demonstrating how you can fulfill the
promise of making SQL Server perform up to its lofty capabilities. As you will see, you have the ability
to really make SQL Server shine in the everyday world!
Lesson 1. Database Basics

Before you learn about the T-SQL language, it is important that you understand the basics of server
databases and the objects they contain. This lesson explains: What a database is
What a table is
What database diagrams, views, stored procedures, user-defined functions, and triggers are

What Is a Database?
T-SQL is the language you use when working with Microsoft SQL Server. Microsoft SQL Server is
considered a client-server database. It is used along with an application that presents the data. An
example of such a database is Microsoft Access. A SQL Server database is a collection of objects. This
collection of objects includes all of the tables, views, stored procedures, functions, and other objects
necessary to build a database system. The tables, which are explained in the next section, in a database
usually relate to each other.

What Is a Table?
Tables are generally the first thing you add to a SQL Server database. Tables contain the data in your SQL
Server database. Each table contains information about a subject. For example, one table might contain
information about customers, whereas another table might contain information about orders. Each table in
a database must have a unique name.
A table is made up of rows and columns. The columns are called fields, and each field has a unique name.
Each row contains an individual occurrence of the subject modeled by the table. Each field contains a
specific piece of information about the item that is being described by the row. A row is most often
referred to as a record. For example, within the Customer table, the fields included may be the
CustomerID, CompanyName, ContactFirstName, ContactLastName, and so on, and each record in the
Customer table contains information about a specific customer. Lesson 4, “Working with SQL Server
Tables,” covers the details of creating and working with tables.

What Is a Database Diagram?


A database diagram graphically shows the structure of the database (see Figure 1.1), showing how one
table is related to another within the database. Using a database diagram, you can modify the tables,
columns, relationships, keys, indexes, and constraints that make up the database. For more about database
diagrams, see Lesson 5, “Working with Table Relationships,” where you find out that database diagrams
are very powerful!
FIGURE 1.1 A database diagram graphically shows the structure of the database.

What Is a View?
A view is a virtual table. Its contents are based on a query. Like a table, a view is composed of rows and
columns. An example is a view that retrieves data from a customer table and from an order table. It
retrieves information from each table for the customers residing in the state of Alaska.
Except in the case of a special type of view called an indexed view, views exist only in memory (their
data is not stored on disk). The data in a view comes from one or more tables in the database (see Figure
1.2). It can also come from other views, and even from data in other databases. Whenever you reference a
view, SQL Server dynamically retrieves the rows and columns contained in it. There are no restrictions
on querying and only a few restrictions on modifying data via views. For more information about views,
see Lesson 12, “Working with SQL Server Views.”
FIGURE 1.2 The View Designer included in SQL Server Management Studio helps you when
designing a view.

What Is a Stored Procedure?


A stored procedure is a piece of programming code that can accept input parameters and can return one or
more output parameters to the calling procedure or batch (see Figure 1.3). Stored procedures generally
perform operations on the database, including the process of calling other stored procedures. An example
is a stored procedure that updates the city of all customers residing in Westlake Village, changing the city
to Venice Beach.
FIGURE 1.3 You can easily create a stored procedure from within the SQL Server Management
Studio.
Stored procedures can also return status information to the calling procedure to indicate whether they
succeeded or failed. Lesson 13, “Using T-SQL to Design SQL Server Stored Procedures,” Lesson 14,
“Stored Procedure Techniques Every Developer Should Know,” and Lesson 15, “Power Stored
Procedure Techniques,” cover stored procedures in quite a bit of detail.

What Is a User-Defined Function?


User-defined functions are procedures that accept parameters, perform some sort of action, and return the
result of that action as a value (see Figure 1.4). The return value can be either a single value or a set of
values. An example is a user-defined function that combines the contents of the first name, middle initial
and last name fields, returning them as a single string.
FIGURE 1.4 User-defined functions are procedures that accept parameters, perform some sort of
action, and return the result of that action as a value.
User-defined functions have many benefits. Like stored procedures, they allow modular programming,
meaning that you can call them from anywhere in your program. If you need to modify the function, you
can do so in only one place. User-defined functions generally execute quickly. For more about user-
defined functions, see Lesson 17, “Building and Working with User-Defined Functions.”

What Is a Trigger?
A trigger is a special type of stored procedure that executes when data changes in a database table. There
are three events that cause a trigger to execute. They include Insert, Update, and Delete statements
that occur when data is modified in a table or view. Triggers have several uses. An example is a trigger
that executes when the user tries to delete a customer. The trigger checks to see if the customer is active. If
the customer is active, the trigger prohibits the user from deleting that customer. Lesson 18, “Creating and
Working with Triggers” covers the intricacies of triggers.
Summary
A database is similar to a house. Without the proper foundation, it will fall apart. This lesson introduced
the various system objects, providing you with a sense of what each object does and why it is important.
You learned a little about tables, database diagrams, views, stored procedures, functions, and triggers,
and the role that each plays in a SQL Server databases. Don’t be concerned if you are still unsure as to
how you use each of these objects. We will spend quite a bit of time delving into each one in detail
throughout the remaining lessons.

Q&A
Q. Describe the difference between a trigger and a standard stored procedure.
A. Triggers execute automatically in response to changes to data; you must explicitly invoke a stored
procedure.
Q. What is a database diagram used for?
A. You use a database diagram to define and represent relationships between the tables in a database.

Workshop

Quiz
1. Stored procedures can have both input and output parameters (true/false).
2. You can usually update the results of a view (true/false).
3. How do we refer to a column in a table?
4. What is another name for a row in a table?

Quiz Answers
1. True.
2. True.
3. We refer to a column in a table as a field.
4. Another name for a row in a table is a record.

Activities
Each lesson in this book will provide you with an opportunity to practice the techniques that you have
learned in the lesson. The section containing these exercises is referred to as “Activities.” Because you
don’t have enough information yet to build tables or any of the other objects you learned about in the
lesson, this lesson does not contain any activities.
Lesson 2. SQL Server Basics

There are some basics you should know when getting started with SQL Server. Knowledge of these basics
will help you to make decisions about whether the product is right for you and will help you get started
working with it. This lesson covers: The available versions of SQL Server 2014
Components included with SQL Server
The basics of working with SQL Server Management Studio How to connect to a database server
How to install the sample files

Versions of SQL Server 2014 Available


Microsoft recognizes that there is a plethora of database users with a large variety of disparate needs and
has released the following six versions of SQL Server 2014:
SQL Server 2014 Express Edition
SQL Server 2014 Web Edition
SQL Server 2014 Business Intelligence Edition SQL Server 2014 Standard Edition
SQL Server 2014 Enterprise Edition

SQL Server 2014 Express Edition


SQL Server 2014 Express provides a great means of getting started with SQL Server. It offers a robust,
reliable, stable environment that is free and easy to use. It provides the same protection and information
management provided by the more sophisticated versions of SQL Server. Other advantages of SQL Server
Express include the following:
Is easy to install
Has a lightweight management and query editing tool Includes support for Windows authentication
Features “Secure by Default” settings
Has royalty-free distribution
Offers rich database functionality, including triggers, stored procedures, functions, extended
indexes, and Transact-SQL support Includes XML support
SQL Server 2014 Express has a few disadvantages that make it unusable in many situations, including the
following:
Support for only 1GB of RAM
Support for a 10GB maximum database size Support for only one CPU
Absence of the SQL Agent Job Scheduling Service Absence of the SQL Profiler
Absence of the Database Tuning Advisor

SQL Server 2014 Web Edition


SQL Server Web Edition is designed to support the workloads associated with Internet databases. It
enables you to easily deploy web pages, applications, websites, and services. Other valuable features
include the fact that it supports 64GB of RAM and a 524-petabyte (PB) database size. The main
disadvantage of SQL Server 2014 Web Edition is that it does not include the SQL Profiler.
SQL Server 2014 Business Intelligence Edition
SQL Server 2014 Business Intelligence Edition enables you to deploy secure, scalable, and manageable
self-service corporate business intelligence solutions. Valuable features include the fact that it supports
128GB of RAM and a 524PB database size.

SQL Server 2014 Standard Edition


SQL Server Standard Edition provides an affordable option for small- and medium-sized businesses. It
includes all functionality required for noncritical e-commerce, data warehousing, and line-of-business
solutions. The advantages of SQL Server 2014 Standard Edition include the following:
Supports up to 128GB of RAM
Supports a database size up to 524PB
Has database mirroring
Includes failover clustering
Includes the Database Tuning Advisor
Includes the full-featured Management Studio Ships with the Profiler
Includes the SQL Agent Job Scheduling Service The disadvantages of SQL Server 2014 Standard
Edition are that it:
Supports only four CPUs
Does not support online indexing
Does not support online restore
Does not support fast recovery

SQL Server 2014 Enterprise Edition


SQL Server 2014 Enterprise Edition includes all of the tools you need to manage an enterprise database
management system. It offers a complete set of enterprise management and business intelligence features
and provides the highest levels of scalability and availability of all the SQL Server 2014 editions. It
supports an unlimited number of CPUs and provides all of the features unavailable in the other versions of
SQL Server 2014.

SQL Server Components


SQL Server includes numerous components that facilitate the process of creating, working with, and
maintaining SQL Server databases. The components covered in this lesson include the following:
SQL Server Management Studio
SQL Profiler
SQL Server Agent
Database Tuning Advisor
SQL Server Management Studio is covered later in detail in the “Introduction to Microsoft SQL Server
Management Studio” section. The other components are covered here.

SQL Profiler
You use the SQL Profiler to create and manage traces and to analyze and replay trace results. Most often,
you use the SQL Profiler to troubleshoot database performance issues.
Using the SQL Profiler, you can accomplish the following:
Step through queries.
Diagnose slow-running queries.
Capture the T-SQL statements that are causing the problem.
Monitor performance.
When using the SQL Profiler, you can specify exactly which database events you want to capture. For
example, you can trace when TSQL statements start and complete, when stored procedures start and
complete, and a plethora of other events (see Figure 2.1). You can save your traces so that you can run
them at any time. Lesson 23, “Performance Monitoring,” covers the details of working with the SQL
Server Profiler.

FIGURE 2.1 The SQL Profiler allows you to easily monitor database events.

SQL Server Agent


The SQL Server Agent enables you to easily schedule administrative tasks called jobs. A job is a series
of actions that the agent performs at specified times, when the agent starts, one time, or when the CPU
utilization of the server is considered idle.
You generally use the SQL Server Agent to perform backups, update indexes, or perform other tasks that
either protect or maintain your database and its objects. The SQL Server Agent appears as a node of the
Object Explorer. When you expand the node, it appears as in Figure 2.2. Using this node, you can view,
create, and manage jobs. Lesson 22, “Maintaining the Databases That You Build,” covers the details of
the SQL Server Agent.
FIGURE 2.2 The SQL Agent enables you to set up and maintain SQL Server jobs that perform a series
of tasks.

Database Engine Tuning Advisor


The Database Engine Tuning Advisor enables you to optimize database performance without requiring
you to have an expert understanding of the database and SQL Server. The Database Engine Tuning
Advisor can perform the following tasks:
Recommend the best mix of indexes
Recommend indexed views when applicable
Analyze the effects of any proposed changes Recommend ways to tune the database
Provide reports that summarize the effects of implementing recommendations Figure 2.3 shows the
Database Tuning Advisor. Lesson 22 covers the Database Tuning Advisor in additional detail.
FIGURE 2.3 The Database Engine Tuning Advisor enables you to optimize the performance of your
database.

Introduction to Microsoft SQL Server Management Studio


Management Studio is a tool that enables you to create, work with, and manage database objects. In the
sections that follow, you explore the various nodes available in Management Studio and find out what is
available under each node.

The Databases Node


The Databases node is the first node in SQL Server Management Studio. Within the Databases node are
one or more subnodes. The first subnode is System Databases. There are additional subnodes for each
database contained on the server (see Figure 2.4). The sections that follow cover each of the system
databases under the System Databases subnode.
FIGURE 2.4 Within the Databases node are one or more subnodes.

The Master Database


The master database is the “database of all databases.” It keeps track of logon accounts, linked servers,
system configuration settings, and more. It also contains initialization settings for SQL Server.

The Model Database


Model is a special database. Anything you place in Model is automatically propagated to all the
databases you create thereafter. This means that, for example, you can add a State table to Model. That
State table then appears in all the new databases you build. You work with Model just as you work with
any other database. You can include almost any object in Model. This means that you easily can propagate
tables, views, stored procedures, triggers, functions, and more. This not only provides you with
standardization between databases, but provides you with a great jump start on creating the databases you
need. If you modify Model, you do not affect any existing databases. All new databases will be affected
by your changes.
The MSDB Database
The MSDB (stands for Microsoft Database) database is used by SQL Server, SQL Server Management
Studio, and SQL Server Agent. All three of them use it to store data, including scheduling information and
backup and restore history information. For example, SQL Server maintains a complete backup and
restore history in MSDB. There are several ways that you can add to or modify information stored in the
MSDB database. They include:
Scheduling tasks
Maintaining online backup and restore history Replication

The TempDB Database


TempDB is a system database that acts as a resource to all users working with a particular instance of
SQL Server. TempDB holds the following objects:
Temporary user objects such as temporary tables, temporary stored procedures, temporary table
variables, or cursors Internal objects used by the database engine to perform tasks such as sorting
Row versions that are generated in data modification transactions

The Security Node


As its name implies, the Security node enables you to manage SQL Server security. Using the Security
node, you can work with logins, add to and remove people from server roles, and create credentials. This
lesson provides an introduction to security. For more information, see Lesson 19, “Authentication,” and
Lesson 20, “SQL Server Permissions Validation.”

The Logins Node


Logins represent the users and roles that have access to your system. Two types of icons appear under the
Logins node. One is granting a role access to the database, and the other is granting a user access to the
database.

The Server Roles Node


Server Roles are predefined roles supplied by SQL Server. Each Server Role possesses a pre-defined set
of rights. Figure 2.5 shows the available Server Roles. You cannot add or remove Server Roles.
FIGURE 2.5 Each Server Role possesses a predefined set of rights.

The Credentials Node


A credential is a record that contains the authentication information required for SQL Server to connect to
an outside resource. Most credentials are made up of a Windows login and password.

Server Objects Node


Server Objects refer to a set of objects used at the server level (not at the database level). These objects
include backup devices, linked servers, and server triggers.

Backup Devices
Backup devices include the tapes and disks you use to back up or restore your SQL Server. When creating
a backup, you must designate the backup device you want to use (see Figure 2.6). You select from a list of
backup devices you have created.
FIGURE 2.6 When creating a backup, you must first designate the backup device you want to use.

Linked Servers
Linked servers enable you to work with other SQL Servers, as well as databases other than SQL Server
databases, right from within Management Studio. This offers a few advantages:
The capability to get remote server access The capability to issue distributed queries, updates,
commands, and transactions on heterogeneous data sources across the enterprise The capability to
address diverse data sources in a similar manner

Server Triggers
Server triggers are DDL (Data Definition Language) triggers. They execute in response to changes being
made to the structure of the database. They are great for both auditing and regulating database operations.
For example, if SQL Server determined that there were more than a specified number of records in a
table, it would not allow users to remove fields from the table.
The Replication Node
Data replication is the capability of a system to automatically make copies of its data and application
objects in remote locations. You can easily propagate any changes to the original or data changes to the
copies to all the other copies. Data replication allows users to make changes to data offline at remote
locations. SQL Express synchronizes changes to either the original or the remote data with other instances
of the database.
The original database is the design master. You can make changes to definitions of tables or other
application objects only at the design master. You use the design master to make special copies called
replicas. Although there is only one design master, replicas can make other replicas. The process of the
design master and replicas sharing changes is synchronization.
To see an example of data replication at work, say you have a team of salespeople who are out on the
road all day. At the end of the day, each salesperson logs on to one of the company’s servers through
Terminal Services. The replication process sends each salesperson’s transactions to the server. If
necessary, the process sends any changes to the server data to the salesperson.
This example illustrates just one of the several valuable uses of replication. In a nutshell, data replication
is used to improve the availability and integrity of data throughout an organization or enterprise. The
practical uses of data replication are many.

Management Node
The Management node contains tools that help you to manage your SQL Server. These tools include the
capability to view both the SQL Server Logs and the Activity Monitor.

SQL Server Logs


SQL Server 2014 adds entries for certain system events to the SQL Server Error Log and to the Microsoft
Windows application log. You can use these logs to identify the sources of problems. Using the SQL
Server Management Studio Log File Viewer, you can integrate SQL Server, SQL Server Agent, and the
Windows logs into a single list, making it easy to review all related events.

Activity Monitor
You use the Activity Monitor component of SQL Server Management Studio to get information about
users’ connections to the database engine and the locks they hold.

Connecting to a Database Server


Before you can work with a database server and the objects it contains, you must first connect to it.
Notice that when you launch Management Studio, the Connect to Server dialog box appears (see Figure
2.7). Generally, all you need to do is to verify that the server name is correct and then click Connect.
FIGURE 2.7 The Connect to Server dialog box enables you to specify connection information for the
database.
Another method you can use to connect to a database server is to click Connect in the Object Explorer and
then select Database Engine (see Figure 2.8). The Connect to Server dialog box appears, enabling you to
modify the Server Name and Authentication mode.
FIGURE 2.8 You can invoke the Connect to Server dialog box from the Object Explorer.

Installing the Sample Files


This course utilizes the AdventureWorks2014 sample database for almost all its examples. You must
install the database before you can work with it.
There are many different websites that provide a link that enables you to download the
AdventureWorks2014 database. One of such links is
https://msftdbprodsamples.codeplex.com/releases/view/125550. This link downloads a file called
Adventure Works 2014 Full Database Backup.zip. Take the following steps to install the
AdventureWorks2014 database on your computer: 1. Double-click the zip file to open it. A file called
AdventureWorks2014.bak appears.
2. Place the AdventureWorks2014.bak file in the desired folder on your computer or network (see
Figure 2.9).
FIGURE 2.9 Place the AdventureWorks2014.bak file in a folder on your computer or network.
3. In Management Studio, right-click the Databases node and select Restore Database. The Restore
Database dialog box displays (see Figure 2.10).
FIGURE 2.10 The Restore Database dialog box enables you to specify information about the database
you want to restore.
4. Click to select Device and then click the ellipsis (…). The Select Backup Device dialog box
displays (see Figure 2.11).
FIGURE 2.11 The Select Backup Device dialog box enables you to designate the backup you want to
restore.
5. Click Add. The Locate Backup File dialog box displays. Locate the folder and file that contains the
backup file (see Figure 2.12) and then click OK. The Select Backup Devices dialog box displays.

FIGURE 2.12 Locate the folder and file containing the backup.
6. Click OK.
7. Click OK one more time. You should receive a message that the file restored properly.
8. Right-click the Databases node and select Refresh. You should now see the AdventureWorks2014
database (see Figure 2.13).

FIGURE 2.13 Once restored, the AdventureWorks2014 database should appear in the Databases node.

Q&A
Q. Discuss the advantages of SQL Server Express.
A. SQL Server Express is free and is easy to use. It provides the same protection and information
management provided by more sophisticated versions of SQL Server. It is easy to install, provides
rich database functionality, and sports deep integration with Visual Studio 2013.
Q. Name some limitations of SQL Server Express.
A. SQL Server Express limits you to 1GB of RAM, 10GB maximum database size, and support for
only one CPU. Furthermore, it does not come with either a job scheduling server or a database
tuning advisor.
Workshop

Quiz
1. Name the version of SQL Server designed for small businesses or departments in larger
enterprises.
2. What versions of SQL Server support 524PB databases?
3. SQL Server Enterprise Edition enables you to utilize all memory installed on the server
(true/false).
4. You are prompted for authentication model during the installation of the SQL Server Express
database engine (true/false).
5. Name the management tool you use to manage your databases.
6. Name the tree view that enables you to view the objects managed by your SQL Server.

Quiz Answers
1. SQL Server 2005 Standard Edition.
2. Standard, Business Intelligence, and Enterprise.
3. True.
4. True.
5. SQL Server Management Studio.
6. Object Explorer.

Activities
Download SQL Server Express Edition. Install both the database engine and SQL Server Express
Management Studio. Launch Management Studio and practice expanding and contracting the nodes of the
Object Explorer. Select different nodes and view the summary information. Finally, take the steps in this
lesson to install the sample AdventureWorks2014 database.
Lesson 3. Creating a SQL Server Database

Databases are at the heart of every SQL Server system. They contain the tables, database diagrams,
views, stored procedures, functions, and triggers that comprise the system. This lesson covers: How to
create a SQL Server database How to set database options
How to work with the Transaction Log How to attach to an existing database

Creating the Database


Before you can build tables, views, stored procedures, triggers, functions, and other objects, you must
create the database in which they will reside. A database is a collection of objects that relate to one
another. An example would be all the tables and other objects necessary to build a sales order system. To
create a SQL Server database, follow these steps:
1. Right-click the Databases node and select New Database. The New Database dialog box appears
(see Figure 3.1).

FIGURE 3.1 The New Database dialog box enables you to create a new database.
2. Enter a name for the database.
3. Scroll to the right to view the path for the database.
4. Click the Ellipsis button. The Locate Folder dialog box appears.
5. Select a path for the database (see Figure 3.2).

FIGURE 3.2 You can opt to accept the default path, or you can designate a path for the database.
6. Click OK to close the Locate Folder dialog box.
7. Click to select the Options page and change any options as desired (see Figure 3.3).
FIGURE 3.3 The Options page of the New Database dialog box enables you to set custom options for
the database.
8. Click OK to close the New Database dialog box and save the new database. The database now
appears under the list of databases (see Figure 3.4) under the Databases node of SQL Server
Management Studio. If the database does not appear, right-click the Databases node and select
Refresh.
FIGURE 3.4 The new database appears under the list of databases in the Databases node.

Defining Database Options


In the previous section, you created a new SQL Server database. You accepted all the default options
available on the General page of the New Database dialog box. Many important options are available on
the General page. They include the Logical Name, File Type, Filegroup, Initial Size, Autogrowth, Path,
and File Name (see Figure 3.5).
FIGURE 3.5 Several important features are available on the General page of the New Database dialog
box.
The logical name is the name that SQL Server will use to refer to the database. It is also the name you
will use to refer to the database when writing programming code that accesses it.
The File Type is Data or Log. As its name implies, SQL Server stores data in data files. The file type of
Log indicates that the file is a transaction log file.
The initial size is very important. You use it to designate the amount of space you will allocate initially to
the database.

Note
I like to set this number to the largest size that I ever expect the data database and log file to
reach. Whereas disk space is very cheap, performance is affected every time that SQL
Server needs to resize the database.

Related to the initial size is the Autogrowth option. When you click the build button (ellipsis) to the right
of the currently selected Autogrowth option, the Change Autogrowth dialog box appears (see Figure 3.6).
FIGURE 3.6 The Change Autogrowth dialog box enables you to designate options that affect how the
database file grows.
The first question is whether you want to support autogrowth at all. Some database designers initially
make their databases larger than they ever think they should be and then set autogrowth to false. They want
an error to occur so that they will be notified when the database exceeds the allocated size. The idea is
that they want to check things out to make sure everything is okay before allowing the database to grow to
a larger size.
The second question is whether you want to grow the file in percentage or in megabytes. For example, you
can opt to grow the file 10% at a time. This means that if the database reaches the limit of 5,000
megabytes, then 10% growth would grow the file by 500 megabytes. If instead the file growth were fixed
at 1,000 megabytes, the file would grow by that amount regardless of the original size of the file.
The final question is whether you want to restrict the amount of growth that occurs. If you opt to restrict
file growth, you designate the restriction in megabytes. Like the Support Autogrowth feature, when you
restrict the file size, you essentially assert that you want to be notified if the file exceeds that size. With
unrestricted file size, the only limit to file size is the amount of available disk space on the server.
File Groups
One great feature of SQL Server is that you can span a database’s objects over several files, all located
on separate devices. We refer to this as a file group. By creating a file group, you improve the
performance of the database because multiple hardware devices can access the data simultaneously.

The Transaction Log


SQL Server uses the transaction log to record every change that is made to the database. In the case of a
system crash, you use the transaction log, along with the most recent backup file, to restore the system to
the most recent data available. The transaction log supports the recovery of individual transactions, the
recovery of all incomplete transactions when SQL Server is once again started, and the rolling back of a
restored database, file, filegroup, or page forward to the point of failure. Specifying information about the
transaction log is similar to doing so for a database. Follow these steps:
1. While creating a new database, you can also enter information about the log file. To begin, enter a
logical name for the database. I recommend you use the logical name of the database along with the
suffix _log.
2. Specify the initial size of the log file.
3. Indicate how you want the log file to grow.
4. Designate the path within which you want to store the database.
5. Continue the process of creating the database file.

Warning
Do not move or delete the transaction log unless you are fully aware of all the possible
ramifications of doing so.

Attaching to an Existing Database


There are times when someone will provide you with a database that you want to work with on your own
server. To work with an existing database, all you have to do is attach to it. Here’s the process:
1. Right-click the Databases node and select Attach. The Attach Databases dialog box appears (see
Figure 3.7).
FIGURE 3.7 The Attach Databases dialog box enables you to attach to existing .mdf database files.
2. Click Add. The Locate Database Files dialog box appears (see Figure 3.8).
FIGURE 3.8 The Locate Database Files dialog box enables you to select the database to which you
want to attach.
3. Locate and select the .mdf to which you want to attach.
4. Click OK to close the Locate Database Files dialog box.
5. Click OK to close the Attach Databases dialog box. The database appears in the list of user
databases under the Databases node of SQL Server Management Studio.

Summary
The ability to create a database is fundamental to working with SQL Server. The process of creating a
database involves understanding what a log file is and how to configure it. After you have created both
the database and the log file, you are ready to create and work with the other database objects.

Q&A
Q. What objects does a SQL Server database contain?
A. A SQL Server database contains the tables, database diagrams, views, stored procedures,
functions, and other objects required to support the database’s operations.
Q. Explain what a log file is and why it is important.
A. The log file keeps track of all transactions that occur as the database is used. It is necessary when
restoring system information.
Q. Explain why you would want to attach to an existing database.
A. The ability to attach to an existing database allows you to easily utilize a database from another
server.

Workshop

Quiz
1. What is autogrowth?
2. The autogrowth feature improves the performance of a database (true/false).
3. You attach to a backup file (true/false).
4. It is always okay to delete a log file (true/false).
5. What are the two options for growing a database?

Quiz Answers
1. Autogrowth provides the ability for a database or log file to grow automatically as necessary.
2. False. The autogrowth feature degrades performance. It is best to set the sizes of the database and
log files to values larger than you expect you will need.
3. False. You attach to a database file (.mdf).
4. False.
5. By percentage or in megabytes.

Activities
Create a new SQL Server database. Designate sizes for both the database and the log file, indicating you
do not want to allow autogrowth. View the database in the Object Explorer. Notice that the database does
not yet contain any user objects.
Lesson 4. Working with SQL Server Tables

At the foundation of every SQL Server database are the tables contained within it. The tables store the
data in your database. The views, stored procedures, and functions that are covered in this book all
manipulate table data. In this lesson, you learn: How to create a SQL Server table How to add fields
to a SQL Server table How to set properties of the fields you add How to add and modify table
indexes

Creating SQL Server Tables


Tables are made up of rows and columns. We refer to columns as fields. Each field has a unique name and
contains a specific piece of information about the row. Each table in a SQL Server database must have a
unique name.
To create a table:
1. Within Management Studio, right-click the Tables node of the database to which you want to add a
table and select New Table. The Table Designer appears (see Figure 4.1).

FIGURE 4.1 The Table Designer enables you to enter the column names, data types, length, and other
properties for each field in the table.
2. Enter the column names and data types for each field in the table.
3. Designate whether each field allows nulls.
4. Use the Column Properties tab in the table designer to enter other properties for the table. For
example, you use the Length property of a varchar field to designate the maximum length string that
the field will hold.

Adding Fields to the Tables You Create


One of the most important properties of a column in a table is the data type. If you do not select the correct
data type for a field, the rest of your design efforts will be futile. The data type determines what data you
can store in the field. Table 4.1 outlines the available field types and the type of information that each data
type can contain.
TABLE 4.1 Field Types and Appropriate Uses

Working with Constraints


Constraints limit or control the types of data that the user can enter into your tables. There are seven main
categories of constraints. They include primary key constraints, foreign key constraints, default
constraints, Not Null constraints, check constraints, rules, and unique constraints. The text that follows
covers each of these constraint types in detail.

Primary Key Constraints


A primary key constraint is a column or a set of columns that uniquely identify a row in the table.
Although you can designate more than one field as the primary key, each table can have only one primary
key.
Every table in your database should have a primary key constraint. Furthermore, it is best if your primary
key meets the following criteria: Short
Stable
Simple
Short means that it should be composed of as few fields as possible, and the smaller the field type is, the
better. In fact, the optimal primary key is a single int field. Stable means that the data within the field
never changes. A great candidate for a primary key is an identity column. The “Identity Columns” section
of this lesson covers identity columns in detail. Simple means that it is easy to remember and deal with.
For example, an int field is simple, whereas a char field containing a long string of complex
characters is not.
To add a primary key to a table:
1. Use the gray selectors on the left side of the Table Designer to select the fields that compose the
primary key (see Figure 4.2).

FIGURE 4.2 Use the gray selectors on the left side of the Table Designer to select the fields that
compose the primary key.
2. Click the Set Primary Key tool on the toolbar. The columns appear with a Key icon on the record
selector (see Figure 4.3).
FIGURE 4.3 The columns included in the primary key appear with a key icon on the record selector.

Foreign Key Constraints


A foreign key constraint consists of a column or of a set of columns that participates in a relationship with
a primary key table. The primary key is on the one side of the relationship, whereas the foreign key is on
the many side of the relationship. A table can have only one primary key, but it can have multiple foreign
keys. Each foreign key relates to a different primary key in a separate table. SQL Server looks up the
foreign key value in the primary key table to ensure that only valid data is included in the table. Lesson 5,
“Working with Table Relationships,” covers foreign key constraints in additional detail.

Default Constraints
A default constraint is a value that SQL Server automatically places in a particular field in a table. A
default value can be a constant, Null, or a function. All fields except identity and time stamp fields can
contain default values. Each column can have one default constraint. You enter the default constraint in the
properties for the desired field (see Figure 4.4).
FIGURE 4.4 You enter the default constraint in the properties for the desired field.
Table 4.2 shows examples of default constraints.

TABLE 4.2 Examples of Default Constraints

Not Null Constraints


In certain situations, you may want to require the user to enter data into a field. The Not Null constraint
enables you to accomplish this task. To set a Not Null constraint, ensure that you uncheck the Allow Nulls
check box (see Figure 4.5).
FIGURE 4.5 To set a Not Null constraint, ensure that the Allow Nulls check box is unchecked.

Check Constraints
Check constraints limit the range of values a user can enter into a column. You can enter as many check
constraints as you want for a particular column. SQL Server evaluates the check constraints in the order in
which you entered them. To enter a check constraint:
1. Click the Manage Check Constraints tool on the toolbar. The Check Constraints dialog box appears.
2. Click Add to add a new constraint.
3. Provide a constraint name and a constraint expression.
4. Designate other options as necessary. The completed dialog box appears as in Figure 4.6.
FIGURE 4.6 The Check Constraints dialog box enables you to enter Check constraints for the table.
5. Click Close to close the dialog box and add the constraint.
Table 4.3 shows examples of check constraints.

TABLE 4.3 Examples of Check Constraints

Rules
Whereas Check constraints apply only to the table for which you enter them, you can apply rules to
multiple tables. Microsoft is phasing out their support for rules. They therefore do not allow you to create
new rules. Instead of using rules, you should use check constraints and triggers.

Unique Constraints
A unique constraint requires that each entry in a particular column be unique. Each table can have 249
unique constraints. You create a unique constraint by creating a unique index.
Creating an Identity Specification
Identity columns provide an autoincrementing value for a table. You should use an identity column as the
primary key field for any table that has no natural primary key that is short, stable, and simple. Identity
columns are often of the int data type. You use the properties of the field to designate a column as an
identity column (see Figure 4.7). Notice that after you designate a column as an identity column, you can
designate both the identity seed and the identity increment. The identity seed is the starting value for the
field. The identity increment is the value by which each automatically assigned value is incremented. For
example, an identity field with an identity seed of 100 and an identity increment of 5 assigns the values
100, 105, 110, and so on.

FIGURE 4.7 You use the field’s properties to designate a column as an identity column.

Adding Computed Columns


With computed columns, you can create a column that is based on data in other columns. SQL Server
automatically updates the computed column when the columns on which it depends are updated. An
example is an extended total that you base on the product of the price and quantity columns. To create a
computed column, enter the desired formula into the (Formula) property under the Computed
Column Specification key of the column (see Figure 4.8).
FIGURE 4.8 To create a computed column, enter the formula into the (Formula) property under the
Computed Column Specification key of the column.
Table 4.4 shows examples of computed columns.

TABLE 4.4 Examples of Computed Columns

Working with User-Defined Data Types


User-defined data types enable you to further refine the data types provided by SQL Server. A user-
defined data type is a combination of a data type, length, null constraint, default value, and rule. After you
define a user-defined data type, you can use it in any tables that you build. To create a user-defined data
type:
1. Expand the Programmability node for the database.
2. Expand the Types node under Programmability.
3. Right-click the User-defined Data Types node and select New User-defined Data Type. The New
User-defined Data Type dialog box appears (see Figure 4.9).

FIGURE 4.9 The User-defined Data Type Properties dialog box enables you to create or modify a
user-defined data type.
4. Enter the required information, such as the name, data type, default, and rule associated with the
user-defined type (see Figure 4.9) and click OK.
To apply a user-defined data type to a field:
1. Go into the design of the table to whose field you want to apply the data type.
2. Open the Data Type drop-down for the field to which you want to apply the data type (see Figure
4.10).
FIGURE 4.10 You can select a user-defined data type as the data type for a field.
3. Select the user-defined data type.

Adding and Modifying Indexes


You use indexes to improve performance when the user searches a field. Although it’s generally best to
include too many indexes rather than too few, indexes do have downsides. Indexes speed up searching,
sorting, and grouping data. The downside is that they take up hard disk space and slow the process of
editing, adding, and deleting data. Although the benefits of indexing outweigh the detriments in most
cases, you should not index every field in each table. Create indexes only for fields or combinations of
fields by which the user will search, sort, or group. Do not create indexes for fields that contain highly
repetitive data. A general rule is to provide indexes for all fields regularly used in searching and sorting
and as criteria for queries.
To create and modify indexes:
1. Modify the design of the table.
2. Select the Manage Indexes and Keys tool on the toolbar. The Indexes/Keys dialog box appears (see
Figure 4.11).
FIGURE 4.11 The Indexes/Keys dialog box enables you to determine the properties of the index.
3. Enter a name for the index.
4. Select the type of index you want to create. Select Clustered to designate the index as clustered.
You can have only one clustered index per table. The data is stored physically based on the order of
the clustered index.
5. Click Add.
6. Click within Columns and then click the ellipsis (…). You see the Index Columns dialog box (see
Figure 4.12).

FIGURE 4.12 The Index Columns dialog box enables you to select the field or fields on which you
want to base the index.
7. Click to select the field or fields on which you want to base the index.
8. Designate whether each field is included in ascending or descending order in the index.
9. Click OK to close the dialog box. You return to the Indexes/Keys dialog box.
10. If desired, click Create Unique to designate the index as a unique constraint.
11. The completed Indexs/Keys dialog box appears as in Figure 4.13. Click OK to close the dialog box
and create the index.

FIGURE 4.13 The Indexes/Keys dialog box enables you to manage table indexes.
To view all indexes associated with a table, you must first save your table (see the next section, “Saving
Your Table”): 1. Click to expand the Indexes node for a table (see Figure 4.14).
FIGURE 4.14 The Indexes node for a table allows you to view the indexes associated with that table.
2. Right-click the index you want to modify and click Properties. The Index Properties dialog box
appears.
3. Make the desired changes to the index.
4. Click OK when you are finished.

Saving Your Table


To save your table:
1. Click the Save button on the toolbar. The Choose Name dialog box appears.
2. Select a name for your table and click OK.
3. Close the table design, if desired, by clicking the “x” on the tab for the table.
4. You may notice that the table does not immediately appear in the Object Explorer. To make it
appear, right-click the Tables table and select refresh. Your table shows up in the list in the Object
Explorer (see Figure 4.15).
FIGURE 4.15 After refreshing the list of tables in the Object Explorer, the new table appears.

Summary
Tables and the relationships between them are the foundation for any application you build. It is therefore
important that you set up your tables with all the necessary properties and then establish the proper
relationships between them. This lesson began by covering all the important aspects of designing database
tables. You then learned about important topics such as constraints, identity columns, and indexes. Now
that you have explored the various ways you can refine the tables you build, in the next lesson you see
how to use database diagrams to relate the tables in your database.

Q&A
Q. What is the difference between a check constraint and a rule?
A. Both check constraints and rules limit the range of values that a user can enter into a column.
Whereas check constraints apply only to the table for which you enter them, you can apply rules to
multiple tables.
Q. Explain what a primary key is and describe the ideal criteria for a primary key.
A. A primary key is a column or a set of columns that uniquely identify a row in a table. A primary key
should be short, stable, and simple.
Q. Describe a foreign key and indicate how many foreign keys each table can contain.
A. A foreign key constraint consists of a column or a set of columns that participate in a relationship
with a primary key table. The primary key is on the one side of the relationship, whereas the foreign
key is on the many side of the relationship. A table can have multiple foreign keys.

Workshop

Quiz
1. What is a default constraint?
2. What is a Not Null constraint?
3. Provide an example of a computed column.
4. A column can have only one check constraint (true/false).
5. Why is the data type you select for a field important?
6. What is an identity column?
7. What is the best use of an identity column?

Quiz Answers
1. A default constraint is a value that SQL Server automatically places in a particular field in a table.
2. A Not Null constraint enables you to require that the user enter data into a field.
3. An extended price that is equal to the price times the quantity.
4. False.
5. The data type determines what data you can store in a field.
6. Identity columns provide an autoincrementing value for a table.
7. The best use of an identity column is as the primary key for a table. This is because it is short,
stable, and simple.

Activities
Create a table that will store customer information. Add a field called CustomerID that will be the
primary key of the table. Make it an identity field. Add a field called CompanyName. Make it
VarChar(40). Add a Not Null constraint to the field. Add a field called Address and another field
called City. Make them both VarChar(35). Add a field called State. Make it Char(2). Add a
check constraint to ensure that the state is CA, UT, AZ, WY, OR, or WA. Give it a default value of CA.
Add a field called IntroDate. Make it a DateTime field and give it a default value of today’s date.
Add a check constraint to ensure that the date entered is on or after today’s date. Finally, add a field
called CreditLimit. Make it a Money field. Give it a default value of $5,000. Add a check constraint
to ensure that the amount entered is between zero and $10,000. Save the table and try entering data into it.
Test the various defaults and constraints that you added to the table’s structure.
Lesson 5. Working with Table Relationships

After you add the tables to your database, you next establish relationships between them. This helps to
ensure the integrity of the data that users enter into the system. In this lesson, you learn:
What relationships are and why you would want to use them
How to work with database diagrams
How to work with table relationships
How to designate table and column specifications
How to add a relationship name and description
How to determine when foreign key relationships constrain the data entered in a column
How to designate INSERT and UPDATE specifications

An Introduction to Relationships
Three types of relationships can exist between tables in a database: one-to-many, one-to-one, and many-
to-many. Setting up the proper type of relationship between two tables in your database is imperative. The
right type of relationship between two tables ensures:
Data integrity
Optimal performance
Ease of use in designing system objects
This lesson discusses many reasons for these benefits. Before you can understand the benefits of
relationships, though, you must understand the types of relationships available.

One-to-Many
A one-to-many relationship is by far the most common type of relationship. In a one-to-many
relationship, a record in one table can have many related records in another table. A common example is
a relationship set up between a Customers table and an Orders table. For each customer in the Customers
table, you want to have more than one order in the Orders table. On the other hand, each order in the
Orders table can belong to only one customer. The Customers table is on the one side of the relationship,
and the Orders table is on the many side. For this relationship to be implemented, the field joining the two
tables on the one side of the relationship must be unique.
In the Customers and Orders tables example, the CustomerID field that joins the two tables must be unique
within the Customers table. If more than one customer in the Customers table has the same customer ID, it
is not clear which customer belongs to an order in the Orders table. For this reason, the field that joins the
two tables on the one side of the one-to-many relationship must be a primary key or must have a unique
index. In almost all cases, the field relating the two tables is the primary key of the table on the one side
of the relationship. The field relating the two tables on the many side of the relationship is called a
foreign key.
One-to-One
In a one-to-one relationship, each record in the table on the one side of the relationship can have only
one matching record in the table on the other side of the relationship. This relationship is not common and
is used only in special circumstances. Usually, if you have set up a one-to-one relationship, you should
have combined the fields from both tables into one table. The following are the most common reasons
why you should create a one-to-one relationship:
The number of fields required for a table exceeds the number of fields allowed in a SQL Server
table.
Certain fields that are included in a table need to be much more secure than other fields included in
the same table.
Several fields in a table are required for only a subset of records in the table.
The maximum number of fields allowed in a SQL Server table is 1,024. There are very few reasons (if
any) why a table should ever have more than 1,024 fields. In fact, before you even get close to 1,024
fields, you should take a close look at the design of your system. On the very rare occasion when having
more than 1,024 fields is appropriate, you can simulate a single table by moving some of the fields to a
second table and creating a one-to-one relationship between the two tables.
The second reason to separate data that logically would belong in the same table into two tables involves
security. An example is a table containing employee information. Many users of the system might need to
access certain information, such as employee name, address, city, state, ZIP code, home phone, and office
extension. Other fields, including the hire date, salary, birth date, and salary level, might be highly
confidential. Although you can easily solve this problem with views, in which you create a view with
only those fields that all the users can see, you may opt instead to store the secure fields in a table
separate from the less-secure fields.
The last situation in which you would want to define one-to-one relationships occurs when certain fields
in a table will be used for only a relatively small subset of records. An example is an Employee table and
a Vesting table. Certain fields are required only for vested employees. If only a small percentage of a
company’s employees are vested, it is not efficient in terms of performance or disk space to place all the
fields containing information about vesting in the Employee table. This is especially true if the vesting
information requires a large volume of fields. By breaking the information into two tables and creating a
one-to-one relationship between them, you can reduce disk-space requirements and improve performance.
This improvement is particularly pronounced if the Employee table is large.

Many-to-Many
In a many-to-many relationship, records in both tables have matching records in the other table. You
cannot directly define a many-to-many relationship; you must develop this type of relationship by adding a
table called a junction table. You relate the junction table to each of the two tables in one-to-many
relationships. An example is an Orders table and a Products table. Each order probably contains multiple
products, and each product is found on many different orders. The solution is to create a third table called
Order Details. You relate the Order Details table to the Orders table in a one-to-many relationship based
on the OrderID field. You relate the Order Details table to the Products table in a one-to-many
relationship based on the ProductID field.
Creating and Working with Database Diagrams
One way that you can establish and maintain relationships between SQL Server tables is to create a
database diagram. It is important to understand how to create, add tables to, edit, and remove tables from
a database diagram. The sections that follow cover these topics.

Creating a Database Diagram


To create a database diagram:
1. Right-click the Database Diagrams node and select New Database Diagram. You see the dialog box
in Figure 5.1.

FIGURE 5.1 If you haven’t yet created any database diagrams for a database, you are prompted as to
whether you want to create one.
2. Click Yes to proceed. The Add Table dialog box opens (see Figure 5.2).
FIGURE 5.2 In the Add Table dialog box, you select the tables you want to include in the database
diagram.
3. Designate the tables you want to add to the database diagram and click Add. Click Close. The
diagram appears as in Figure 5.3.
FIGURE 5.3 After adding tables to the database diagram, they appear in the Database Diagram
window.
4. Click and drag from the field(s) in the Primary Key table that you want to relate to the field(s) in
the Foreign Key table. The Tables and Columns dialog box displays (see Figure 5.4).
FIGURE 5.4 In the Tables and Columns dialog box, you designate which tables and columns will
participate in the relationship.
5. Provide a relationship name and verify that the desired relationship has been established. Click OK
to close the dialog box. The Foreign Key Relationship dialog box opens (see Figure 5.5).

FIGURE 5.5 The Foreign Key Relationship dialog box enables you to designate properties for the
relationship.
6. This dialog box contains several important options, which are covered throughout the remainder of
the lesson. Designate any properties for the relationship and click OK. You are returned to the
database diagram.
7. When you close the database diagram, SQL Server first prompts you as to whether you want to save
your changes (see Figure 5.6). Click Yes to commit the changes to the underlying tables. The
Choose Name dialog box displays.

FIGURE 5.6 SQL Server prompts you as to whether you want to save changes to the underlying tables.
8. Enter a name for the database diagram and click OK. The Save dialog box lets you know which
tables you will affect (see Figure 5.7). Click Yes to proceed and update the designated tables. The
database diagram should now appear under the Database Diagrams node of SQL Server
Management Studio.

FIGURE 5.7 The Save dialog lets you know which tables your changes will affect.
Editing a Database Diagram
To edit a database diagram, you must first open it:
1. If you just created the database diagram and it does not appear in the list of existing database
diagrams, right-click the Database Diagrams node and select Refresh.
2. After the diagram appears, right-click the diagram and select Modify. The Relationships dialog box
appears.
To edit the relationship between two tables in a database diagram:
1. Right-click a table in the database diagram whose relationships you want to modify and select
Relationships (see Figure 5.8). The Foreign Key Relationships dialog box opens (see Figure 5.9).

FIGURE 5.8 To edit a relationship, right-click a table in the diagram and select Relationships.
FIGURE 5.9 In the Foreign Key Relationships dialog box, you indicate the relationship you want to
modify.
2. Click to select the relationship you want to modify.
3. Modify any of the desired properties (the remaining sections in this lesson cover these properties in
detail).
4. Click Close.

Adding Tables to a Database Diagram


To add tables to the database diagram:
1. Right-click anywhere in the Relationships window and select Add Table. The Add Table dialog
box opens.
2. Select the tables you want to add to the diagram and click Add.
3. Click Close. SQL Server adds the requested tables to the diagram.

Removing Tables from a Database Diagram


To remove tables from the database diagram:
1. Right-click the table you want to remove and select Remove from Diagram.
2. It is important to note that SQL Server removes the table from the diagram but does not remove the
relationship from the database.
Note
It is important to understand the correlation between the database diagram and the actual
relationships you have established within the database. A database can contain multiple
database diagrams. Each database diagram lets you view and modify the existing
relationships. When you establish relationships, SQL Server creates the actual relationship
between the tables. You can delete the tables from the database diagram (by right-clicking
and selecting Remove Table from Diagram), but the relationships still exist (permanently
removing relationships is covered in the section, “Deleting a Foreign Key Relationship,”
later in this lesson). The Database Diagram window provides a visual blueprint of the
relationships you have established. If you modify the layout of the diagram by moving around
tables, adding tables to the diagram, or removing tables from the diagram without changing
any relationships, SQL Server still prompts you to save the changes to the diagram when you
close the diagram window. In that case, SQL Server is not asking whether you want to save
the relationships you have established; it is simply asking whether you want to save the
visual layout of the window.

Working with Table Relationships


It is easy to view all the foreign key relationships in which a table is participating. Follow these steps:
1. Right-click the table and select Design. The design of the table appears (see Figure 5.10).
FIGURE 5.10 While the design of the table is visible, you are able to select the Relationships tool on
the toolbar.
2. Click the Relationships tool on the toolbar. You then see the Foreign Key Relationships dialog box
(see Figure 5.11).
FIGURE 5.11 The Foreign Key Relationships dialog box enables you to work with the relationships
associated with a table.
3. Click a relationship to select it. The properties of that relationship appear.

Adding a Foreign Key Relationship


With the Foreign Key Relationships dialog box, you can also add an index. Simply click the Add button. A
new relationship appears with a default name and without a description. Before you take any further
action, you should supply the Tables and Columns Specification covered in the section “Designating
Table and Column Specifications.” You must designate the table and column specification before SQL
Server will accept the new relationship.

Deleting a Foreign Key Relationship


Deleting a foreign key relationship is easy. Follow these steps:
1. While in the Foreign Key Relationships dialog box, select the relationship you want to remove.
2. Click the Delete button. SQL Server removes the relationship without warning.

Warning
When you remove a foreign key relationship, you are removing the data integrity protection it
affords you. This means, for example, that after you have removed the foreign key
relationship between customers and orders, the user can add orders for customers that do not
exist.
Designating Table and Column Specifications
By entering a Tables and Columns specification, you designate the foreign key table that will participate
in the relationship, the field in the foreign key table that will participate in the relationship, and the field
in the current table that will participate in the relationship. To work with the Tables and Columns
Specification, follow these steps:
1. In the Foreign Key Relationships dialog box, click the right arrow to expand the Tables and
Columns Specification property.
2. Click the Build button (…) that appears to the right of the Tables and Columns Specification
property. The Tables and Columns dialog box opens (see Figure 5.12).

FIGURE 5.12 The Tables and Columns dialog box, showing the relationship between the Customers
table and the Orders table.
3. If you want, modify the relationship name. You generally want to rename the relationship to more
accurately reflect the relationship you are creating (for example, FK_tblOrders_tblCustomers).
4. Click to select the primary key table that will participate in the relationship. For example, if you
are creating foreign keys for the Orders table, you would designate the Customer table as the
primary key table.
5. Use the drop-down on the left (under the primary key table) to select the field(s) that will
participate in the relationship. For example, in the foreign key relationship between Orders and
Customers, the CustomerID in the Customers table participates in the relationship.
6. Use the drop-down on the right (under the foreign key table) to select the field(s) in the current
table that will participate in the relationship. In the relationship between the Orders table and the
Customers table, the foreign key field participating in the relationship would be the CustomerID
field.
7. Click OK to complete the process. SQL Server returns you to the Foreign Key Relationships dialog
box.
Adding a Relationship Name and Description
It is helpful to provide a descriptive name for each relationship you add, as well as a brief description.
This way when you are viewing a relationship in the Foreign Key Relationships dialog box, you can
easily see the nature of the relationship you have selected.
To enter or change a name for the relationship, simply click the (Name) property for the relationship.
Enter or change the name as you desire.
To enter a description for the relationship, click the Description property for the index. Enter a short
description of your choice.

Determining When Foreign Key Relationships Constrain the Data Entered in a


Column
As you can see establishing a relationship is quite easy. Establishing the right kind of relationship is a
little more difficult. When you attempt to establish a relationship between two tables, SQL Server makes
some decisions based on a few predefined factors:
It establishes a one-to-many relationship if one of the related fields is a primary key or has a unique
index.
It establishes a one-to-one relationship if both the related fields are primary keys or have unique
indexes.
It cannot create a relationship if neither of the related fields is a primary key and neither has a
unique index.
As covered earlier in this lesson, referential integrity consists of a series of rules that SQL Server
applies to ensure that the relationships between tables are maintained properly. At the most basic level,
referential integrity rules prevent the creation of orphan records in the table on the many side of the one-
to-many relationship. After establishing a relationship between a Customers table and an Orders table, for
example, all orders in the Orders table must be related to a particular customer in the Customers table.
Before you can establish referential integrity between two tables, the following conditions must be met:
The matching field on the one side of the relationship must be a primary key field or must have a
unique index.
The matching fields must have the same data types. They also must have the same size. Number
fields on both sides of the relationship must have the same size (int, for example).
Both tables must be part of the same database.
If you opt to set the Check Existing Data on Creation option to Yes, existing data within the two
tables cannot violate any referential integrity rules. All orders in the Orders table must relate to
existing customers in the Customers table, for example.
After you establish referential integrity between two tables, SQL Server applies the following rules:
You cannot enter a value in the foreign key of the related table that does not exist in the primary key
of the primary table. For example, you cannot enter a value in the CustomerID field of the Orders
table that does not exist in the CustomerID field of the Customers table.
You cannot delete a record from the primary table if corresponding records exist in the related
table. For example, you cannot delete a customer from the Customers table if related records exist
in the Orders table (records with the same value in the CustomerID field) unless you designate a
Delete Rule (see the section that follows).
You cannot change the value of a primary key on the one side of a relationship if corresponding
records exist in the related table. For example, you cannot change the value in the CustomerID field
of the Customers table if corresponding orders exist in the Orders table unless you designate an
Update rule in the Foreign Key Relationships dialog box for the relationship (see the “Designating
Insert and Update Specifications” section that follows).
If any of the previous three rules is violated and referential integrity is being enforced between the tables,
an appropriate error message is displayed, as shown in Figure 5.13.

FIGURE 5.13 An appropriate error message appears if referential integrity is violated.


SQL Server’s default behavior is to prohibit the deletion of parent records that have associated child
records and to prohibit the change of a primary key value of a parent record when that parent has
associated child records. You can override these restrictions by using the INSERT and UPDATE
specification, covered in the next section.
For now, let’s see how you can establish referential integrity between the tables in your database. The
process is as follows:
1. From the Foreign Key Relationships dialog box, select the relationship for which you want to
establish referential integrity.
2. Set the Enforce Foreign Key Constraint property to Yes. This step alone is all you need to establish
referential integrity.
3. If you want to check existing data when you save your changes to ensure that they do not violate the
referential integrity rules, set the Check Existing Data on Creation or Re-enabling option to Yes.
4. If you are utilizing replication and want to enforce referential integrity during the synchronization
process, set the Enforce for Replication property to Yes.

Designating Insert and Update Specifications


SQL Server enables you to define rules that dictate what will happen when the user deletes or updates a
record. You can find these rules under the INSERT and UPDATE Specification node of the Foreign Key
Relationships dialog box. The text that follows explores this node and why and how you should use it.

The Delete Rule


By setting the Delete rule, you determine what happens when the user deletes a record on the one side of a
one-to-many relationship. For example, by setting the Delete rule to Cascade, you establish the rule so
that the user can delete a record on the one side of a one-to-many relationship, even if related records
exist in the table on the many side of the relationship. The user can delete a customer even if the customer
has existing orders, for example. Referential integrity is maintained between the tables because SQL
Server automatically deletes all related records in the child table.
If you attempt to delete a record from the table on the one side of a one-to-many relationship and no
related records exist in the table on the many side of the relationship, you are able to delete the record. On
the other hand, if you attempt to delete a record from the table on the one side of a one-to-many
relationship and related records exist in the child table, you will delete the record from the parent table as
well as any related records in the child table.

Tip
Setting the Delete rule to Cascade is not always appropriate. It is an excellent feature, but
you should use it prudently. Although it is usually appropriate to cascade delete from an
Orders table to an Order Details table, for example, it generally is not appropriate to
cascade delete from a Customers table to an Orders table. This is because you generally do
not want all your order history deleted from the Orders table if for some reason you want to
delete a customer. Deleting the order history causes important information, such as your
profit and loss history, to change. It therefore is appropriate to prohibit this type of deletion
and handle the customer in some other way, such as marking him as inactive or archiving his
data. On the other hand, if you delete an order because it was canceled, you probably want
the corresponding order detail information to be removed as well. In this case, the Cascade
option is appropriate. You need to make the appropriate decision in each situation based on
business needs. The important thing is to carefully consider the implications of each option
before making your decision.
The Update Rule
With the Update rule set to Cascade, the user can change the primary key value of the record on the one
side of the relationship. When the user makes an attempt to modify the field joining the two tables on the
one side of the relationship, the change is cascaded down to the foreign key field on the many side of the
relationship. This is useful if the primary key field is modifiable. For example, a purchase number on a
purchase order master record may be updateable. If the user modifies the purchase order number of the
parent record, you would want to cascade the change to the associated detail records in the purchase
order detail table.

Note
There is no need to select the Cascade option when the related field on the one side of the
relationship is an identity field. An identity field can never be modified. The Cascade option
has no effect on identity fields.

Note
Other options for the Delete and Update rules include No Action, Set Null, and Set Default.
No Action, the default value, does nothing and therefore does not allow the deletion of parent
records that have children or the modification of the key field(s) of parent records that have
children. Set Null sets the value of the foreign key field to Null. Finally, Set Default sets the
value of the foreign key field to its default value.

Summary
Even if your table design is sound, a database set up without proper relationships compromises both data
integrity and application performance. It is therefore important that you establish the proper relationships
between the tables in your database. This lesson began with a discussion of the types of relationships
available. You then learned about important topics such as how to establish relationships, how to
designate table and column specifications, how to determine when foreign key relationships constrain the
data entered in a column, and how to designate INSERT and UPDATE specifications.

Q&A
Q. What is the Tables and Columns specification?
A. The Tables and Columns specification enables you to designate the foreign key table that will
participate in the relationship, the field in the foreign key table that will participate in the
relationship, and the field in the current table that will participate in the relationship.
Q. Describe three uses of a one-to-one relationship.
A. You use a one-to-one join when the number of fields required for a table exceeds the number of
fields allowed in a SQL Server table, when certain fields that are included in a table need to be
much more secure than other fields included in the same table or when several fields in a table are
required for only a subset of records in the table.
Q. Describe a many-to-many relationship and how you create one.
A. With a many-to-many relationship, records in both tables have matching records in the other table.
You cannot create a many-to-many relationship directly. You must develop a junction table and
relate the junction table to each of the two tables in one-to-many relationships.
Workshop

Quiz
1. Name the three types of relationships.
2. What is the most common type of relationship?
3. To create a relationship, matching fields must have the same data type (true/false).
4. By setting the Delete rule to Cascade, when a user deletes a row on the one side of the relationship,
SQL Server deletes the corresponding rows on the many side of the relationship (true/false).
5. The UPDATE rule is very useful when working with Identity columns (true/false).
6. List three advantages of establishing relationships between database tables.

Quiz Answers
1. One-to-one, one-to-many, and many-to-many.
2. One-to-many.
3. True.
4. True.
5. False. Because you cannot change the value of an identity column, the UPDATE rule is not
applicable to an identity column.
6. Data integrity, optimal performance, and ease of use in designing system objects.

Activities
Create a table that will store order information. Add a field called OrderID that will be the primary key
field of the table. Make its data type Int and make it an identity field. Add a field called CustomerID.
Give it the data type of Int. Add a Not Null constraint to the field. Add a field called OrderDate. Make
it a DateTime field. Add another field called ShippedBy. Make it an Int field. Finally, add a field called
FreightAmount. Make it a Money field. Now that you have created the table, establish a relationship
between it and the Customers table created in Lesson 4, “Working with SQL Server Tables.” Base the
relationship on the CustomerID field from each table. Make sure you set the Enforce Foreign Key
Constraint property of the relationship to Yes. Add some customers to the Customers table. Make note of
their CustomerIDs. Add orders to the Orders table for those customers. You should be able to add those
orders without a problem. Try adding orders for customers that do not exist. You should not be able to do
so because of the referential integrity you applied. Try deleting customers who have orders. Once again,
you should fail because of referential integrity. If you are feeling really ambitious, set the Delete Rule of
the relationship to Cascade. Then try deleting a Customer with orders. The process should delete the
customer and its corresponding orders.
Lesson 6. Getting to Know the SELECT Statement

Knowledge of the T-SQL language is vital to your success as a SQL Server administrator or developer.
You use the T-SQL language to manipulate the data in your database. Using T-SQL, you can select, insert,
update, and delete data. In this lesson, you learn: What T-SQL is
How to build a SELECT statement
How to work with a WHERE clause
How to order your output

Introducing T-SQL
T-SQL, or Transact-SQL, is the dialect of the Structured Query Language (SQL) incorporated in SQL
Server. To work effectively as a SQL Server developer, you must have a strong grasp of T-SQL.
Fortunately, T-SQL is easy to learn. When retrieving data, you simply build a SELECT statement.
SELECT statements are composed of clauses that determine the specifics of how the data is selected.
When they’re executed, SELECT statements select rows of data and return them as a recordset.

Note
In the examples that follow, keywords appear in uppercase. Values that you supply appear
italicized. Optional parts of the statement appear in square brackets. Curly braces, combined
with vertical bars, indicate a choice. Finally, ellipses are used to indicate a repeating
sequence.

Working with the SELECT Statement


The SELECT statement is at the heart of the SQL language. You use the SELECT statement to retrieve
data from one or more tables. Its basic syntax is the following:
Click here to view code image
SELECT column-list FROM table-list WHERE where-clause
ORDER BY order-by-clause The SELECT clause specifies what columns you want to retrieve
from the table that SQL Server returns to the result set. The basic syntax for a SELECT
clause is as follows: SELECT column-list

Selecting All Fields


The simplest SELECT clause looks like this:
SELECT * FROM Person.Person

This SELECT clause, combined with the FROM clause covered in the next section, retrieves all columns
from a table.

Selecting Specific Fields


You will not always want to retrieve all fields from a table. In fact, most often you need to retrieve data
only from specific fields.
The example that follows retrieves only the BusinessEntityID and FirstName columns from a table:
Click here to view code image
SELECT BusinessEntityID, FirstName FROM Person.Person

Adding an Expression
Not only can you include columns that exist in your table, but you also can include expressions in a
SELECT clause. Here’s an example:
Click here to view code image

SELECT BusinessEntityID, Title, FirstName + ' ' + MiddleName + ' ' +


LastName AS FullName FROM Person.Person This SELECT clause retrieves the BusinessEntityID
column, the Title column, and an alias called FullName, which includes an expression that
concatenates the FirstName, MiddleName, and LastName columns (see Figure 6.1).

FIGURE 6.1 A SELECT clause that includes an expression that concatenates the FirstName,
MiddleName, and LastName columns.
Note
The examples throughout this book are based on the AdventureWorks sample database. A
backup of this database is available at
http://msftdbprodsamples.codeplex.com/releases/view/125550. After you download the file,
you must restore the database so that you can follow along with the examples. Lesson 22,
“Maintaining the Databases You Build,” covers the process of restoring a database.

Note
After installing the AdventureWorks database, you will probably notice that all the table
names appear in the format schema-name.table-name. All objects in databases are contained
in schemas. There are many advantages to placing database objects in schemas. Throughout
the book, you will see examples such as Person.Address, with Person being the schema name
and Address being the table name. When an object is associated with a schema, you must
refer to the object along with its schema name.

Adding on the FROM Clause


The FROM clause specifies the tables or views from which the records should be selected. It can include
an alias that you use to refer to the table. The FROM clause looks like this:
FROM table-list [AS alias]

Here’s an example of a basic FROM clause:


FROM Person.Address

In this case, the name of the table is Address. If you combine the SELECT clause with the FROM clause,
the SQL statement looks like this: Click here to view code image
SELECT AddressID, AddressLine1 FROM Person.Address

This SELECT statement retrieves the AddressID and AddressLine1 columns from the Address table,
which is part of Person schema.

Using Table Aliases


Just as you can alias the fields included in a SELECT clause, you can also alias the tables included in the
FROM clause. The alias is used to shorten the name and to simplify a cryptic name, as well as for a
variety of other reasons. Here’s an example:
Click here to view code image

SELECT BusinessEntityID, FirstName FROM Person.Person AS Clients

Including the WHERE Clause


The WHERE clause limits the records retrieved by the SELECT statement. A WHERE clause can include
columns combined by the keywords AND and OR. The syntax for a WHERE clause looks like this:
Click here to view code image
WHERE expression1 [{AND|OR} expression2 [...]]
A simple WHERE clause looks like this:
WHERE PersonType = 'EM'

Using an AND to further limit the criteria, the WHERE clause looks like this:
Click here to view code image
WHERE PersonType = 'EM' AND LastName Like 'Ma%'

This WHERE clause limits the records returned to those in which the PersonType is equal to EM and the
LastName begins with Ma. Notice that T-SQL uses the percent (%) sign as a wildcard. Using an OR, the
SELECT statement looks like this: Click here to view code image
WHERE PersonType = 'EM' OR PersonType = 'SC'

This WHERE clause returns all records in which the PersonType is equal to either EM or SC. Compare that
with the following example: Click here to view code image
WHERE PersonType = 'EM' OR LastName Like 'Ma%'

This WHERE clause returns all records in which the PersonType is equal to EM or the LastName begins
with Ma. For example, the people with EM as their PersonType are returned from this WHERE clause, as
are the people whose LastName begins with Ma. The WHERE clause combined with the SELECT and
FROM clauses looks like this (see Figure 6.2): Click here to view code image
SELECT BusinessEntityID, PersonType, LastName FROM Person.Person
WHERE PersonType = 'EM' OR LastName Like 'MA%'
FIGURE 6.2 A SELECT clause that retrieves the BusinessEntityID, PersonType, and LastName
columns for all the people with either the PersonType ‘EM’, or a LastName that begins with ‘MA’.
Notice in Figure 6.2 that records with a PersonType of ‘MA’ appear regardless of their last name.
Records of people whose last names begin with ‘MA’ appear regardless of their PersonType.
Contrast this example to the following example:
Click here to view code image
SELECT BusinessEntityID, PersonType, LastName FROM Person.Person
WHERE PersonType = 'EM' AND LastName Like 'MA%'

The results appear in Figure 6.3.


FIGURE 6.3 Using the keyword AND, both conditions must be true for a row to appear in the result
set.
If you look at the records returned in Figure 6.3, you see that all records that appear in the result have
both a PersonType of ‘EM’ and a last name that begins with ‘MA’.

Rules When Filtering Data


You must follow several rules when building a WHERE clause. You must enclose the text strings for which
you are searching in apostrophes. You must also surround dates with apostrophes. Unlike text strings and
dates, you do not delimit numeric fields. Finally, you must include the keyword LIKE when utilizing
wildcard characters. Remember that T-SQL uses the percent symbol as the wildcard for zero or more
characters. The underscore (_) is the wildcard for a single character. Let’s take a look at some examples:
Click here to view code image
SELECT BusinessEntityID, PersonType, LastName FROM Person.Person
WHERE BusinessEntityID >= 200

In this example, because BusinessEntityID is a numeric field with the int data type, the criteria for
BusinessEntityID contains no apostrophes. With character (string) data, the process is different: Click
here to view code image
SELECT BusinessEntityID, PersonType, LastName FROM Person.Person
WHERE LastName = 'Martin'

Notice that the text string we are looking for is enclosed in apostrophes. You might be surprised that when
specifying criteria for dates, you also use apostrophes: Click here to view code image
SELECT BusinessEntityID, PersonType, LastName, ModifiedDate FROM Person.Person
WHERE ModifiedDate >= '1/1/2013'

Working with Dates and Times


The T-SQL language is rich with date and time functions you can use when specifying criteria. The text
that follows covers many of these powerful functions.
The GetDate() function returns the current date and time. Take a look at the simplest example:
SELECT GetDate()

This example returns one column containing the current date and time. A more complex example of using
the GetDate() function looks like this: Click here to view code image
SELECT ModifiedDate, CONVERT(int. ModifiedDate – GetDate())
FROM Person.Person

The T-SQL in this example returns the ModifiedDate from the Person table, along with the number of days
between the current date and the ModifiedDate. The results appear in Figure 6.4.
FIGURE 6.4 The GetDate() function returns the current date and time.
Another T-SQL date function is DAY. Its counterparts are the MONTH and YEAR functions. These
functions return the day, month, and year associated with a date. They look like this: Click here to view
code image
SELECT DAY(GetDate()), MONTH(GetDate()), YEAR(GetDate())

The results of executing this statement appear in Figure 6.5.


FIGURE 6.5 Use the DAY, MONTH, and YEAR functions to return the day, month, and year associated
with a date.
The DATEPART function extracts a part of a date. You use it to determine the day of the month, month of
the year, year of a date, day of the year, day of the week, week of the year, and other parts of a date. An
example of several uses of the DATEPART function appear in Figure 6.6.
FIGURE 6.6 The DATEPART function enables you to return various parts of a date.
With the DATEADD function, you add or subtract a specified period of time from a date. For example, you
can add a quarter to a date. Examples of the uses of the DATEADD function appear in Figure 6.7.
FIGURE 6.7 The DATEADD function enables you to add or subtract periods of time to or from a date.
Another powerful date-related T-SQL function is DATEDIFF. It allows you to determine the number of
days, months, years, or other time increments between two dates. Figure 6.8 illustrates some examples of
the DATEDIFF function.
FIGURE 6.8 With the DATEDIFF function, you can determine the interval of time between two dates.

Using IN and NOT


The IN and NOT keywords facilitate the process of determining what rows appear in the result of your
SELECT statement. The IN keyword allows you to select a series of values that will appear in the result.
The NOT keyword allows you to exclude what appears in the result. The following is an example of the
use of the IN keyword:
Click here to view code image
SELECT BusinessEntityID, PersonType, LastName, ModifiedDate FROM Person.Person
WHERE PersonType IN('EM','IN','VC') This SELECT statement returns the designated fields
from the Person table for all records where the PersonType is ‘EM’, ‘IN’, or ‘VC’. If you
want to retrieve all rows where the PersonType is not ‘EM’, ‘IN’, or ‘VC’, you simply add
the keyword NOT to the statement: Click here to view code image

SELECT BusinessEntityID, PersonType, LastName, ModifiedDate FROM Person.Person


WHERE PersonType NOT IN('EM','IN','VC') Another example of the use of the NOT keyword is
where you want to return all rows from the Person table where the ModifiedDate is not
between 1/1/2013 and 12/31/14. It looks like this: Click here to view code image

SELECT BusinessEntityID, PersonType, LastName, ModifiedDate FROM Person.Person


WHERE ModifiedDate NOT BETWEEN '1/1/2013' AND '12/31/2014'
Another keyword you might find useful is the NULL keyword. The NULL keyword allows you to
designate that you want to retrieve only those rows where the designated field does not contain data or
only those rows where the designated field does contain data. Here’s how it works: Click here to view
code image
SELECT BusinessEntityID, PersonType, LastName, ModifiedDate FROM Person.Person
WHERE Suffix IS NULL

This SELECT statement returns all rows where the Suffix field does not contain data. By adding the
keyword NOT, you can return only those rows where the Suffix field contains data.
Click here to view code image
SELECT BusinessEntityID, PersonType, LastName, ModifiedDate FROM Person.Person
WHERE Suffix IS NOT NULL

As you can see, by combining everything you have learned in this section, you can retrieve only the data
you want and need.

Using the ORDER BY Clause


The ORDER BY clause determines the order in which SQL Server sorts the returned rows. It’s an
optional clause and looks like this:
Click here to view code image
ORDER BY column1 [{ASC|DESC}], column2 [{ASC|DESC}] [,...]]

Here’s an example:
ORDER BY BusinessEntityID

The ORDER BY clause can include more than one field:


ORDER BY LastName, FirstName

When you specify more than one field, SQL Server uses the leftmost field as the primary level of sort.
Any additional fields are the lower sort levels. Combined with the rest of the SELECT statement, the
ORDER BY clause looks like this: Click here to view code image
SELECT BusinessEntityID, FirstName, LastName, ModifiedDate FROM Person.Person
WHERE ModifiedDate Between '1/1/2013' AND '12/31/2014'
ORDER BY ModifiedDate The results appear in order by ModifiedDate (see Figure 6.9).
FIGURE 6.9 A SELECT clause that retrieves the BusinessEntityID, FirstName, LastName, and
ModifiedDate columns for all the people whose ModifiedDate is between 1/1/2013 and 12/31/2014.
SQL Server orders the results by ModifiedDate.

Changing the Sort Direction


The ORDER BY clause enables you to determine whether the sorted output appears in ascending or
descending order. By default, output appears in ascending order. To switch to descending order, use the
optional keyword DESC. Here’s an example:
Click here to view code image
SELECT BusinessEntityID, FirstName, LastName, ModifiedDate FROM Person.Person
WHERE ModifiedDate Between '1/1/2013' AND '12/31/2014'
ORDER BY ModifiedDate DESC

This example selects the BusinessEntityID, FirstName, LastName, and ModifiedDate fields from the
Person table, ordering the output in descending order by the ModifiedDate field (see Figure 6.10).
FIGURE 6.10 A SELECT clause that retrieves the BusinessEntityID, FirstName, LastName, and
ModifiedDate columns for all the people with a ModifiedDate between 1/1/2013 and 12/31/2014.
SQL Server orders the results in descending order by ModifiedDate.

Summary
The T-SQL language is the foundation for most of what you do in SQL Server. It is therefore necessary to
have a strong understanding of the T-SQL language constructs. This lesson covered many of the basics of
the T-SQL language. You learned about the SELECT statement, the FROM keyword, the WHERE clause,
and the ORDER BY clause. We cover T-SQL in additional detail throughout the remainder of the book.

Q&A
Q. Why do you use a SELECT statement?
A. To retrieve data from one or more tables.
Q. Name the wildcard characters you can use when searching and explain the differences
between them.
A. The two wildcard characters are the percent (%) sign and the underscore (_). T-SQL uses the
percent symbol (%) as the wildcard for zero or more characters. The underscore (_) is the wildcard
for a single character.
Workshop

Quiz
1. Which keyword do you use to designate the tables you will include in the query?
2. You use an alias to permanently rename a field in a table (true/false).
3. What is the keyword you use if you want the data to appear in descending order?

Quiz Answers
1. You use FROM to designate the tables you will include in the query.
2. False. ALIAS provides only an alias for the field in the query output.
3. If you want the query output to appear in descending order, use the DESC keyword.

Activities
Build a simple SELECT statement based on the Person.Address table in the AdventureWorks2014 sample
database. Include the AddressID, AddressLine1, AddressLine2, City, StateProvinceID, and PostalCode
fields. Add a WHERE clause to limit the records returned in the result to those where the City is Seattle,
Redmond, or Newport Hills. Order the data in descending order by City.
Lesson 7. Taking the SELECT Statement to the Next Level

Lesson 6, “Getting to Know the SELECT Statement,” provided you with an introduction to the SQL
SELECT statement. This lesson takes your knowledge of the SELECT statement to the next level. In this
lesson, you learn: What the DISTINCT keyword is and why it’s valuable How to use the FOR XML
clause to return data as an XML document How to group and summarize data
How to apply criteria to summarized data
Limit the number of rows returned in the output

Adding the DISTINCT Keyword


The DISTINCT keyword ensures uniqueness of values in the column or combination of columns included
in the query result. Consider the following SQL statement:
Click here to view code image
SELECT City FROM Person.Address ORDER BY City

This statement returns one row for each address record (see Figure 7.1). The same city appears multiple
times in the output.
FIGURE 7.1 A SELECT statement that returns one row for each address record. The same city
appears multiple times in the output.
Contrast the statement used in the previous example with this:
Click here to view code image
SELECT DISTINCT City FROM Person.Address ORDER By City

This statement returns a list of unique cities from the list of addresses (see Figure 7.2).
FIGURE 7.2 A SELECT statement that returns a list of unique cities from the list of addresses.
The statement that follows returns a unique list of city and modified date combinations (see Figure 7.3):
SELECT DISTINCT City, ModifiedDate FROM Person.Address ORDER BY City Click
here to view code image
FIGURE 7.3 A SELECT statement that returns a list of city and modified date combinations from the
list of addresses.

Working with the FOR XML Clause


You use the FOR XML clause to return data as an XML document. When using the FOR XML clause, you
must specify the mode as RAW, AUTO, or EXPLICIT. With the RAW option, SQL Server takes the result
of the query and transforms each row in the result set into an XML element with a generic identifier.
Here’s an example:
Click here to view code image
SELECT BusinessEntityID, FirstName, MiddleName, LastName
FROM Person.Person
ORDER BY LastName, FirstName
FOR XML RAW

After you click the resulting link, the results appear as in Figure 7.4 (notice the generic row identifier).
With the AUTO option, SQL Server returns a simple nested XML tree. SQL Server represents each field in
each table specified in the SELECT clause as an XML element. Here’s an example: Click here to view
code image
SELECT BusinessEntityID, FirstName, MiddleName, LastName
FROM Person.Person
ORDER BY LastName, FirstName
FOR XML AUTO

FIGURE 7.4 The result of using the FOR XML RAW clause to return data.
When you click the resulting link, the results appear as in Figure 7.5 (notice the Person.Person
identifier). Finally, with the EXPLICIT option, you explicitly define the shape of the tree. You must
write your queries so that the columns listed in the SELECT clause are mapped to the appropriate element
attributes.
FIGURE 7.5 The result of using the FOR XML AUTO clause to return data.

Working with the GROUP BY Clause


You can use the GROUP BY clause to calculate summary statistics. The syntax of the GROUP BY clause
is:
Click here to view code image
GROUP BY group-by-expression1 [,group-by-expression2 [,...]]

You use the GROUP BY clause to dictate the fields on which SQL Server groups the query result. When
you include multiple fields in a GROUP BY clause, they are grouped from left to right. SQL Server
automatically outputs the fields in the order designated in the GROUP BY clause. In the following
example, the SELECT statement returns the product number, color, and total safety stock level for each
product number/color combination. The results are displayed in order by product number and color (see
Figure 7.3): Click here to view code image
SELECT ProductNumber, Color,
Sum(SaftetyStockLevel) AS TotalSafetyStock
FROM Production.Product
GROUP BY ProductNumber, Color
FIGURE 7.6 A SELECT statement that returns the product number, color, and total safety stock level
for each product number/color combination.
The GROUP BY clause indicates that SQL Server doesn’t display the detail for the selected records.
Instead, it displays the fields indicated in the GROUP BY uniquely. One of the fields in the SELECT
statement must include an aggregate function. SQL Server displays the result of the aggregate function
along with the fields specified in the GROUP BY clause.

Including Aggregate Functions in Your SQL Statements


You use aggregate functions to summarize table data. The aggregate functions available include COUNT,
COUNT_BIG, SUM, AVG, MIN, and MAX. The following sections discuss each of these aggregate
functions. You can find additional aggregate functions in the Books Online for SQL Server. You can
access Books Online by selecting View Help from the Help menu in SQL Server Management Studio.

Using the COUNT Function


You use the COUNT function to count the number of rows in a table. It looks like this:
Click here to view code image
SELECT COUNT(*) AS CountOfProducts FROM Production.Product
The example counts the number of rows in the Product table (see Figure 7.7).

FIGURE 7.7 A SELECT statement that counts the number of rows in the Product table.
As an alternative, you can count values in a particular column. The SQL statement looks like this:
Click here to view code image
SELECT COUNT(Color) AS CountOfColors FROM Production.Product This example counts the
number of colors found in the Product table (see Figure 7.8).
FIGURE 7.8 A SELECT statement that counts the number of colors found in the Product table.

Working with the COUNT_BIG Function


The COUNT_BIG function is identical to the COUNT function, except that it returns a bigint data type.
It looks like this:
Click here to view code image
SELECT COUNT_BIG(Color) AS CountOfColors FROM Production.Product

Exploring the SUM Function


The SUM function is available only for numeric columns. It adds the data in the columns. Here’s an
example:
Click here to view code image
SELECT SUM(Weight) AS TotalWeight FROM Production.Product

The example totals the Weight column for all rows in the Product table. When used with the GROUP BY
clause, the SUM function can easily total values for each grouping: Click here to view code image
SELECT Color, SUM(Weight) AS TotalWeight FROM Production.Product GROUP BY Color The
example totals the weight for each color (see Figure 7.9).
FIGURE 7.9 A SELECT statement that totals the weight for each color found in the Product table.

Working with the AVG Function


Just as you can easily total data, you can average data. The following statement finds the average freight
for all orders in the Orders table:
Click here to view code image
SELECT AVG(Weight) AS AvgWeight FROM Production.Product

When used with the GROUP BY clause, the AVG function can easily average values in each grouping:
Click here to view code image
SELECT Color, AVG(Weight) AS AvgWeight FROM Production.Product GROUP BY Color The result
provides the average weight for each color (see Figure 7.10).
FIGURE 7.10 A SELECT statement that provides the average weight for each color found in the
Product table.

Using the MIN Function


Another important aggregate function is MIN. You use the MIN function to find the minimum value in a
column. This statement finds the minimum weight in the Product table:
Click here to view code image
SELECT MIN(Weight) FROM Production.Product

When used with the GROUP BY clause, the MIN function can easily find the minimum values in each
grouping: Click here to view code image
SELECT Color, MIN(Weight) FROM Production.Product GROUP BY Color The result provides the
minimum weight for each color (see Figure 7.11).
FIGURE 7.11 A SELECT statement that provides the minimum weight for each color found in the
Product table.

Using the MAX Function


A related aggregate function is MAX. You use the MAX function to find the maximum value in a column.
This statement finds the maximum weight in the Product table (see Figure 7.12):
Click here to view code image
SELECT MAX(Weight) FROM Production.Product
FIGURE 7.12 You use the MAX function to find the maximum value in a column.
When used with the GROUP BY clause, the MAX function can easily find the maximum values in each
grouping: Click here to view code image
SELECT Color, MAX(Weight) FROM Production.Product GROUP BY Color The result provides the
maximum weight for each color (see Figure 7.13).
FIGURE 7.13 When used with the GROUP BY clause, the MAX function can easily find the maximum
value in each grouping.

Taking Advantage of the HAVING Clause


A HAVING clause is similar to a WHERE clause, but it differs in one major respect: SQL Server applies it
after it summarizes the data rather than beforehand. In other words, the WHERE clause is used to
determine which rows are grouped. The HAVING clause determines which groups are included in the
output. A HAVING clause looks like this:
Click here to view code image
HAVING expression1 [{AND|OR} expression2[...]]

In the following example, SQL Server applies the criteria > 1000 after it applies the aggregate function
SUM to the grouping. Therefore, SQL Server includes only colors with total weight greater than 1000 in
the output (see Figure 7.14).
Click here to view code image
SELECT Color,
Sum(Weight) AS TotalWeight
FROM Production.Product
GROUP BY Color
HAVING Sum(Weight)>1000
FIGURE 7.14 A SELECT statement that includes colors with total weight greater than 1000 in the
output.

Creating Top Values Queries


You use the TOP clause to limit the number of rows that SQL Server includes in the output. Here’s an
example:
Click here to view code image
SELECT TOP 10 Color, Weight FROM Production.Product
ORDER BY Weight DESC

This example shows the 10 highest weight amounts along with their corresponding colors (see Figure
7.15).
FIGURE 7.15 A SELECT statement that shows the colors associated with the highest 10 weight
amounts.
In addition to enabling you to select the top number of rows, T-SQL also enables you to select the top
percent of rows. Here’s an example: Click here to view code image
SELECT TOP 10 PERCENT Color, Weight FROM Production.Product
ORDER BY Weight DESC

Here the top 10% of weight amounts appear in the query result.

Summary
As mentioned in Lesson 6, the T-SQL language is integral to your success as a SQL Server administrator
or developer. This lesson started where Lesson 6 left off. It covered many important T-SQL language
constructs. You learned about the DISTINCT keyword and how to output XML. You also learned how to
group and aggregate data, producing counts, totals, averages, minimum values, and maximum values in a
grouping. The lesson also covered how to use HAVING to apply criteria to aggregated data. Finally, you
learned how to return only the top values from a result set.

Q&A
Q. Explain the difference between the HAVING clause and the WHERE clause.
A. SQL Server applies the HAVING clause after it summarizes the data; it applies the WHERE clause
before it summarizes the data.
Q. Explain the DISTINCT keyword.
A. The DISTINCT keyword ensures uniqueness of values in the column or combination of columns
included in the query result.
Q. Why would you use a Top Values query?
A. You use a Top Values query to limit the number of rows that appear in the output.

Workshop

Quiz
1. List the three modes of the FOR XML statement.
2. What is the purpose of aggregate functions?
3. Name four aggregate functions.
4. One of the aggregate functions is COUNT LARGE (true/false).
5. PERCENT is a valid keyword when the TOP clause is used (true/false).

Quiz Answers
1. The three modes of the FOR XML statement are RAW, AUTO, and EXPLICIT.
2. They summarize table data.
3. Sum, Count, Min, Max, Avg.
4. False. It is called COUNT BIG.
5. True.

Activities
Build a SELECT statement that counts, totals, averages, and finds the minimum and maximum
SalesLastYear by TerritoryID from the Sales.SalesPerson table. Modify the statement to return only the
territories where the total SalesLastYear is greater than 1 million. Finally, return the 100 highest
SalesLastYear and associated TerritoryID from the Sales.SalesPerson table.
Lesson 8. Building SQL Statements Based on Multiple Tables

Now that you’ve learned the basics of the T-SQL language, you’re ready to move on to more advanced
techniques. To really take advantage of what T-SQL has to offer, you must know how to return recordsets
that contain data based on multiple tables. In this lesson, you learn: What inner joins are and how to
implement them What outer joins are and how they differ from inner joins How to output data based
on multiple tables

Working with Join Types


When you build a system based on normalized table structures, you must join the tables back together to
see the data in a useable format. For example, if you have separated customers, orders, and order details,
you need to join these tables in a query to see the name of the customer who placed an order for a
particular item. Several types of joins are available. They include inner joins, outer joins, full joins, and
self-joins. This lesson covers the inner and outer join types. The next lesson, “Powerful Join Techniques,”
covers full joins and self-joins.

Using Inner Joins


An inner join is the most common type of join. When you use an inner join, only rows on the one side of
the relationship that have matching rows on the many side of the relationship are included in the output.
Here’s an example:
Click here to view code image

SELECT Person.BusinessEntityID,
FirstName, LastName, PhoneNumber
FROM Person.Person
INNER JOIN Person.PersonPhone
ON Person.BusinessEntityID = PersonPhone.BusinessEntityID

This example includes only those people who have phone numbers. The results appear in Figure 8.1.
FIGURE 8.1 An inner join that includes all people who have phone numbers.
At times, you need to join more than two tables in a SQL statement. The most common syntax is as
follows:
Click here to view code image

FROM table1 JOIN table2 ON condition1 JOIN table3 ON condition2

The following example joins the Person, PersonPhone, and PhoneNumberType tables:
Click here to view code image
SELECT Person.BusinessEntityID,
FirstName, LastName, PhoneNumber, Name as PhoneNumberType
FROM Person.Person
INNER JOIN Person.PersonPhone
ON Person.BusinessEntityID = PersonPhone.BusinessEntityID
INNER JOIN Person.PhoneNumberType
ON PersonPhone.PhoneNumberTypeID = PhoneNumberType.PhoneNumberTypeID

The results appear in Figure 8.2. Notice that data appears from all three tables.
FIGURE 8.2 An inner join that includes data from the Person, PersonPhone, and PhoneNumberType
tables.
In the example, the order of the joins is unimportant. The exception to this is when you combine inner and
outer joins. When you combine inner and outer joins, the SQL Server engine applies two specific rules.
First, the nonpreserved table in an outer join cannot participate in an inner join. The nonpreserved table is
the one whose rows may not appear. In the case of a left outer join from Customers to Orders, the Orders
table is considered the nonpreserved table. Therefore, it cannot participate in an inner join with
OrderDetails. The second rule is that the nonpreserved table in an outer join cannot participate with
another nonpreserved table in another outer join.

Creating Outer Joins


An outer join enables you to include rows from one side of the join in the output, regardless of whether
matching rows exist on the other side of the join. Two types of outer joins exist: left outer joins and right
outer joins. With a left outer join, SQL Server includes in the output all rows in the first table specified in
the SELECT statement. Here’s an example:
Click here to view code image
SELECT Person.BusinessEntityID,
FirstName, LastName, PhoneNumber
FROM Person.Person
LEFT OUTER JOIN Person.PersonPhone
ON Person.BusinessEntityID = PersonPhone.BusinessEntityID

Note
The word OUTER is assumed in the LEFT JOIN clause used when building a left outer
join.

In the previous example, people are included regardless of whether they have phone numbers. Notice that
if you look at the lower-right corner of Figure 8.3, you see that 19974 rows were returned from the
SELECT statement. This is because I added two records to the Person.Person table without adding any
records into the Person.PersonPhone table for the people that I added.

FIGURE 8.3 A left outer join that includes records from the Person table regardless of whether they
have phone numbers.
Contrast Figure 8.3 with Figure 8.4. The SELECT statement used in Figure 8.4 looks like this: Click here
to view code image
SELECT Person.BusinessEntityID,
FirstName, LastName, PhoneNumber
FROM Person.Person
INNER JOIN Person.PersonPhone
ON Person.BusinessEntityID = PersonPhone.BusinessEntityID

FIGURE 8.4 An inner join that excludes records from the Person table if those records don’t have
associated phone numbers.
Because the SELECT statement contains an inner join, the two people without phone numbers in
Person.PersonPhone do not appear in the result set. Therefore, only 19972 rows appear in the result.
With the right outer join shown next, phone numbers are included whether or not they have associated
people. If you have properly enforced referential integrity, this scenario should never exist.
Click here to view code image
SELECT Person.BusinessEntityID,
FirstName, LastName, PhoneNumber
FROM Person.Person
RIGHT OUTER JOIN Person.PersonPhone
ON Person.BusinessEntityID = PersonPhone.BusinessEntityID

Summary
In a world of normalized data, it is important that you understand how to use queries to join your tables
back together. This lesson showed you how to join table data. You learned about both inner and outer
joins. The examples provided clearly illustrated the differences between them.
Q&A
Q. Why must you join tables together in a query?
A. When you build a system based on normalized table structures, you must join the tables back
together to see the data in a useable format.
Q. Explain what an inner join is.
A. An inner join outputs just those rows on the one side of the join that have matching rows on the
many side of the join.
Q. Explain what an outer join is.
A. An outer join outputs rows on the one side of the join regardless of whether they have matching
rows on the many side of the join.
Q. What is the difference between a left outer join and a right outer join?
A. With a left outer join, SQL Server includes all rows in the output for the first table in the SELECT
statement. With a right outer join, SQL Server includes all rows in the output for the second table in
the SELECT statement.

Workshop

Quiz
1. When joining a Customer table and an Order table, all customers will always appear (true/false).
2. When joining a Customer table and an Order table with a left outer join, all customers will always
appear (true/false).

Quiz Answers
1. False. Only the customers who have associated orders appear.
2. False. This is true if the Customer table appears in the SELECT statement before the Order table.

Activities
Practice joining the Person and EmailAddress tables in the AdventureWorks sample database with an
inner join, a left outer join, and a right outer join. Add a few people without email addresses. Note that
the number of rows in the output differs for the various join types.
Lesson 9. Powerful Join Techniques

Now that you understand the mechanics of inner and outer joins, you are ready to delve into more
advanced join techniques. In this lesson, you learn: What full joins are and why you might need them
The power of self-joins
How to utilize union queries
What subqueries are and how to take advantage of them How to utilize the INTERSECT operator
What the EXCEPT operator can accomplish for you

Utilizing Full Joins


A full join combines the behavior of the left and right outer joins. It looks like this:
Click here to view code image
SELECT Person.BusinessEntityID,
FirstName, LastName, PhoneNumber
FROM Person.Person
FULL JOIN Person.PersonPhone
ON Person. BusinessEntityID = PersonPhone.BusinessEntityID

In this example, all people appear in the output regardless of whether they have phone numbers, and all
phone numbers appear in the output whether or not they are associated with people. The results appear in
Figure 9.1.
FIGURE 9.1 A SELECT statement that shows the result of joining the Person table to the PersonPhone
table using a full join.

Taking Advantage of Self-Joins


A self-join involves joining a table to itself. Although it is not the most common type of join, it valuable.
Imagine the scenario in which an Employee table contains a field called EmployeeID and another field
called SupervisorID. The SupervisorID field must contain a valid EmployeeID. It would not make sense
to have separate Employee and Supervisor tables because supervisors are employees. This is where the
self-join comes in. A self-join looks like this:
Click here to view code image
SELECT Employee.BusinessEntityID,
EmployeeInfo.FirstName AS EmployeeFName,
EmployeeInfo.LastName AS EmployeeLName,
SupervisorInfo.FirstName AS SupervisorFName,
SupervisorInfo.LastName AS SupervisorLName
FROM HumanResources.Employee AS Supervisor INNER JOIN
HumanResources.Employee AS Employee
ON Supervisor.BusinessEntityID = Employee.SupervisorID INNER JOIN
Person.Person AS EmployeeInfo
ON Employee.BusinessEntityID = EmployeeInfo.BusinessEntityID INNER JOIN
Person.Person AS SupervisorInfo
ON Supervisor.BusinessEntityID = SupervisorInfo. BusinessEntityID
In this example, the SupervisorID from the Employee table is joined to the BusinessEntityID field in an
alias of the Employee table (called Supervisor). The resulting employee and supervisor information is
output from the query (see Figure 9.2).

FIGURE 9.2 A SELECT statement that shows the result of joining the Employee table to itself.
If you take a close look at the results in Figure 9.2, you see that only employees who have supervisors
appear in the result. This is because our self-join is an inner join. The example that follows uses a right
outer join rather than an inner join to link the Person table to itself.
Click here to view code image
SELECT Employee.BusinessEntityID,
EmployeeInfo.FirstName AS EmployeeFName,
EmployeeInfo.LastName AS EmployeeLName,
SupervisorInfo.FirstName AS SupervisorFName,
SupervisorInfo.LastName AS SupervisorLName
FROM Person.Person AS SupervisorInfo INNER JOIN
HumanResources.Employee AS Supervisor
ON SupervisorInfo.BusinessEntityID = Supervisor.BusinessEntityID
RIGHT OUTER JOIN Person.Person AS EmployeeInfo
INNER JOIN HumanResources.Employee AS Employee
ON EmployeeInfo.BusinessEntityID = Employee.BusinessEntityID
ON Supervisor.BusinessEntityID = Employee.SupervisorID

The results appear in Figure 9.3. Notice that the employee with a BusinessEntityID of 1 has no supervisor
but does appear in the result.

FIGURE 9.3 A SELECT statement that uses an outer join when joining the Employee table to itself.

Exploring the Power of Union Queries


Union queries enable you to combine rather than join data from more than one table. A typical example of
a union query is one that combines data from a Product table and a DiscontinuedProduct table. Another
example is a query that combines data from a Customer table and a CustomerArchive table. Here’s an
example of a union query:
Click here to view code image
SELECT TransactionID, ProductID, TransactionDate, Quantity
FROM Production.TransactionHistory
UNION
SELECT TransactionID, ProductID, TransactionDate, Quantity
FROM Production.TransactionHistoryArchive This example outputs all rows from the
TransactionHistory table as well as from the TransactionHistoryArchive table (see Figure
9.4).
FIGURE 9.4 A SELECT statement that outputs all rows from the TransactionHistory table as well as
from the TransactionHistoryArchive table.
If you want to order the results, you must place the ORDER BY statement after the second SELECT
statement: Click here to view code image
SELECT TransactionID, ProductID, TransactionDate, Quantity
FROM Production.TransactionHistory
UNION
SELECT TransactionID, ProductID, TransactionDate, Quantity
FROM Production.TransactionHistoryArchive
ORDER BY Quantity DESC

In this example, SQL Server combines the results of both SELECT statements in descending order by
Quantity. The results appear in Figure 9.5.
FIGURE 9.5 A SELECT statement that outputs the results of a UNION query in descending order by
Quantity.
It is often helpful to be able to identify the source table for each row in the output. The SQL statement that
follows identifies how to accomplish this task.
Click here to view code image

SELECT TransactionID, ProductID, TransactionDate,


Quantity, 'C' as RecordSource
FROM Production.TransactionHistory
UNION
SELECT TransactionID, ProductID, TransactionDate,
Quantity, 'A' as Recordsource
FROM Production.TransactionHistoryArchive
ORDER BY Quantity DESC

Notice that in the example, the SQL statement adds a column called RecordSource. It sets the value of the
column to a different value within each SELECT statement. The results appear in Figure 9.6.
FIGURE 9.6 A SELECT statement that includes an indicator identifying which table that record came
from.
Notice in the figure that some rows contain ‘C’ in the RecordSource column, indicating that they come
from the TransactionHistory table. Other rows contain ‘A’ in the RecordSource column, indicating that
they come from the TransactionHistoryArchive table.

Working with Subqueries


A subquery is a query that SQL Server evaluates before it evaluates the main query. Here’s an example:
Click here to view code image
SELECT BusinessEntityID, FirstName, LastName FROM Person.Person WHERE
BusinessEntityID Not In(Select BusinessEntityID FROM Person.PersonPhone) In this example,
SQL Server executes the statement that selects data from the PersonPhone table before it
evaluates the statement that selects data from the Person table (see Figure 9.7). It
returns all people without records in the PersonPhone table.
FIGURE 9.7 A SELECT statement that returns all people without phones.
This is not a very efficient method of accomplishing the task of finding all the people without phones. A
better solution would be to use an outer join to solve this problem. You could modify the SQL statement to
look like this: Click here to view code image
SELECT Person.BusinessEntityID, FirstName, LastName
FROM Person.Person LEFT OUTER JOIN Person.PersonPhone
ON Person.BusinessEntityID = PersonPhone.BusinessEntityID
WHERE PersonPhone.BusinessEntityID Is Null This example uses a left outer join to select
all people who do not have phones. Because this uses a left outer join, people are
included whether or not they have phone records. Because the criteria designate that only
rows with a null BusinessEntityID appear in the output, only people without phone records
are included.

Using the INTERSECT Operator


An alternative technique to use when you want to only return rows in one table that have corresponding
rows in another table is to use the INTERSECT operator. The INTERSECT operator looks like this:
SELECT ProductID
FROM Production.Product
INTERSECT
SELECT ProductID
FROM Production.WorkOrder
ORDER BY ProductID

The results show only products that have work orders (see Figure 9.8).

FIGURE 9.8 A SELECT statement that returns all products with associated work orders.

Working with the EXCEPT Operator


The INTERSECT operator’s counterpart is the EXCEPT operator. The EXCEPT operator returns rows
from the first SELECT statement that are not returned by the second SELECT statement. This means
EXCEPT returns only rows, which are not available in the second SELECT statement. The EXCEPT
clause looks like this:
Click here to view code image
SELECT ProductID
FROM Production.Product
EXCEPT
SELECT ProductID
FROM Production.WorkOrder
ORDER BY ProductID

This example returns all Products that do not have associated work orders. The results appear in Figure
9.9.
FIGURE 9.9 A SELECT statement that returns all products without associated work orders.
Swapping the order of the tables returns a totally different result. The example that follows returns the
work orders that aren’t associated with a product. With referential integrity in place, this statement will
never return any rows.
SELECT ProductID
FROM Production.WorkOrder
EXCEPT
SELECT ProductID
FROM Production.Product
ORDER BY ProductID

Summary
This lesson began with a discussion of full joins. You then learned how to create self joins, which allow
you to join a table to itself. The lesson moved on to union queries, which allow you to combine data from
two tables as if they were within one table. After exploring subqueries, you learned about the
INTERSECT and EXCEPT operators that enable you to build queries that mimic the behavior of inner
and outer joins.
Q&A
Q. Explain what a full join is.
A. A full join combines the behavior of a left outer join and a right outer join. An example is where
you show all customers whether or not they have orders and all orders whether or not they are
associated with a customer.
Q. Describe what a subquery does.
A. SQL Server Express evaluates a subquery before it evaluates the main query.
Q. Provide an example of where a self-join is useful.
A. You can use a self-join to determine the name of the supervisor associated with each employee.
Q. Provide an example of where a union query is useful.
A. You can use a union query to combine data from a sales table and a sales history table, displaying
the results in a report.

Workshop

Quiz
1. A union query joins two tables (true/false).
2. What operator simulates an inner join?
3. Subqueries are the most efficient way to return rows in one table that do not have associated rows
in another table (true/false).

Quiz Answers
1. False. Union queries allow you to combine two tables.
2. INTERSECT.
3. False. Outer joins and the EXCEPT operator are far more efficient techniques to use when you need
to return rows in one table that do not have associated rows in another table.

Activities
Create a SQL statement that uses a full join to join the Product and WorkOrder tables. Add some people to
the Person table. You will need to create new BusinessEntityIDs in the Person.BusinessEntity table first.
Then create a subquery that finds all people in the Person table who do not have records in the
PersonPhone table. Build a SQL statement with an outer join that returns the sample people. Finally,
accomplish the same task using the EXCEPT operator.
Lesson 10. Modifying Data with Action Queries

Not only can you use T-SQL to select data, you can also use it to update data. T-SQL gives you the ability
to update, insert into, and delete data from tables. In this lesson, you learn: How to use the UPDATE
statement to update table data
How to use the INSERT statement to insert data into an existing table How to use the SELECT
INTO statement to insert data into a new table How to use the DELETE statement to selectively
delete data from a table How to use the TRUNCATE statement to remove all data from a table

The UPDATE Statement


As its name implies, an UPDATE statement updates table data. The format of the UPDATE statement is as
follows:
Click here to view code image

UPDATE tablename SET column1=value1, [column2=value2....]

The example that follows updates the contents of the Customers table, changing the city to Venice Beach
for all rows in which the city is Westlake Village: Click here to view code image
UPDATE Person.Address
SET City = 'Venice Beach'
WHERE City = 'Westlake Village'

A valuable technique lies in the ability to update data in one table based on the values of data in another
table. Here’s an example: Click here to view code image
UPDATE Production.Product
SET Product.ListPrice =
ProductListPriceHistory.ListPrice
FROM Production.Product
INNER JOIN Production.ProductListPriceHistory
ON Product.ProductID =
ProductListPriceHistory.ProductID
WHERE GetDate()
BETWEEN ProductListPriceHistory.StartDate
AND ProductListPriceHistory.EndDate This SQL statement updates the ListPrice in the
Product table based on data in the ProductListPriceHistory table. To do this, it joins
the two tables on ProductID. It only updates the ListPrice in the Product table where
there are corresponding records in the ProductListPriceHistory table and where the
current date is between the StartDate and EndDate field values. The results of executing
this SQL statement are shown in Figure 10.1.
FIGURE 10.1 An UPDATE statement that updates the Product table based on values in the
ProductListPriceHistory table.

The INSERT Statement


You use the INSERT statement to insert data into an existing table. The INSERT statement has the
following format:
Click here to view code image
INSERT [INTO] table_or_view [(col1, col2...)] VALUES (value1, value2) Here’s an example:

INSERT INTO Person.Address


(AddressLine1,
City, StateProvinceID,
PostalCode,ModifiedDate)
VALUES
('34 Elm Street',
'Venice Beach', 9,
90291, '1/26/15') In this example, the designated values are inserted into the specified
fields in the Address table.

If a column is not provided in the list of values being inserted, one of the following conditions must be
true for the omitted column for the record to be inserted successfully: The column has an Identity
property, in which case the next available identity value is used.
The column has a default value, in which case the default value is automatically inserted into the
field.
The column has a timestamp data type, in which case the current timestamp value is used.
The column allows nulls, in which case a null value is used.
The column is computed, in which case the computed value is used.
In addition to being able to specify values you want to insert into a record in a table, you can also insert
data from another table. Here’s an example: Click here to view code image
INSERT INTO
[Production].[TransactionHistoryArchive]
(TransactionID, ProductID,
ReferenceOrderID,ReferenceOrderLineID,
TransactionDate, TransactionType,
Quantity, ActualCost,
ModifiedDate)
SELECT TransactionID, ProductID,
ReferenceOrderID, ReferenceOrderLineID,
TransactionDate, TransactionType,
Quantity, ActualCost,
ModifiedDate
FROM Production.TransactionHistory
WHERE TransactionDate < '1/1/2014'

In this example, all records from the TransactionHistory table with a TransactionDate before 1/1/2014 are
inserted into the TransactionHistoryArchive table. The results are shown in Figure 10.2.
FIGURE 10.2 An INSERT statement that inserts records from the TransactionHistory table into the
TransactionHistoryArchive table.

The SELECT INTO Statement


Whereas the INSERT statement inserts data into an existing table, the SELECT INTO statement creates
a new table. Here’s an example:
Click here to view code image
SELECT
TransactionID, ProductID,
ReferenceOrderID,ReferenceOrderLineID,
TransactionDate, TransactionType,
Quantity, ActualCost,
ModifiedDate
INTO Production.TransactionsOld
FROM Production.TransactionHistory
WHERE TransactionDate < '1/1/2014'

In this example, all transactions with a TransactionDate before 1/1/2014 are inserted into a new table
called TransactionsOld. The resulting table is shown in Figure 10.3.
FIGURE 10.3 A SELECT INTO statement that inserts records from the TransactionHistory table into
a new table called TransactionsOld.

The DELETE Statement


You use the DELETE statement to remove rows from a table. The format of the DELETE statement is as
follows:
Click here to view code image
DELETE [FROM] table-name [WHERE search_conditions]

Here’s an example:
Click here to view code image
DELETE FROM Production.TransactionHistory
WHERE TransactionDate < '1/15/2014'

This example removes all rows from the TransactionHistory table in which the TransactionDate is before
1/15/2014. The results of executing the SQL statement are shown in Figure 10.4.
FIGURE 10.4 A DELETE statement that deletes records from the TransactionHistory table where the
TransactionDate is prior to 1/15/2014.

The TRUNCATE Statement


The TRUNCATE statement removes all rows from a table. It executes more quickly than a DELETE
statement that does not contain a WHERE clause. Unlike the DROP statement, which removes a table
entirely, the TRUNCATE statement retains the structure of the table while deleting all of its data. It looks
like this:
Click here to view code image
TRUNCATE TABLE Production.TransactionsOld

Summary
An important use of T-SQL lies in its ability to modify table data. Using T-SQL, you can insert, update,
and delete table data. In this lesson, you learned the syntax to perform these important tasks.

Q&A
Q. Explain the difference between INSERT and SELECT INTO.
A. INSERT adds data to an existing table; SELECT INTO creates a new table containing the data
you are inserting.
Q. Explain the difference between a DELETE statement and a TRUNCATE statement.
A. A DELETE statement allows you to selectively remove data from a table; the TRUNCATE statement
unconditionally removes all rows from a table.
Q. Describe the difference between TRUNCATE and DROP.
A. TRUNCATE removes all data from the table while retaining the table structure; DROP removes the
table from the database.

Workshop

Quiz
1. Name the five action keywords available in T-SQL.
2. You can insert data into a view (true/false).
3. What keyword do you use when inserting data into a new table?
4. What statement do you use to most efficiently remove all data from the Person.Person table?

Quiz Answers
1. INSERT, SELECT INTO, UPDATE, DELETE, TRUNCATE.
2. True. You can insert data into a view just as you can insert data into a table. The INSERT statement
affects all tables underlying the view.
3. INTO.
4. TRUNCATE TABLE Person.Person.

Activities
Write and execute T-SQL that inserts all employees in the HumanResources.Employee table where
SupervisorID is equal to 3 into a new table called tblEmployeesSpecial. View the table data to validate
that your T-SQL code ran successfully. Insert additional data into the tblEmployeesSpecial table from the
HumanResources.Employee table where the SupervisorID is equal to 4. View the table data to validate
your T-SQL code. Update all the VacationHours amounts in the tblEmployeesSpecial table, increasing
them by eight. Review the table data to make sure that your T-SQL code executed as expected. Delete all
rows in the tblEmployeesSpecial table where the SupervisorID is equal to 3. Review the table data to
ensure that all the rows with SupervisorID 3 are removed. Truncate the tblEmployeesSpecial table. Open
it up and note that the data is unavailable. Finally, DROP the tblEmployeesSpecial table. Note that it is no
longer displayed in the list of available tables.
Lesson 11. Getting to Know the T-SQL Functions

The T-SQL language contains numerous functions you can incorporate into the T-SQL statements you
build. These functions perform a variety of important tasks. This lesson covers some of the commonly
used numeric, string, date/time, and null-related functions. For additional information on the plethora of T-
SQL functions available, consult Books Online (online help for SQL Server) or MSDN. To access Books
Online from Management Studio, select View Help from the Help menu. In this lesson, you learn: How
to work with some of the numeric functions available in T-SQL
How to work with some of the string functions available in T-SQL
How to work with some of the date/time functions available in T-SQL
How to use T-SQL to work with nulls

Working with Numeric Functions


Important numeric functions include IsNumeric and ROUND. The sections that follow examine these
functions and provide examples of their uses.

Using the IsNumeric Function


The IsNumeric function returns information on whether a value is numeric. Here’s an example:
Click here to view code image

SELECT City, PostalCode, IsNumeric(PostalCode) FROM Person.Address The SELECT statement


returns each customer’s City, PostalCode, and information on whether the postal code is
numeric (see Figure 11.1).
FIGURE 11.1 A SELECT statement that uses the IsNumeric function to determine whether the
postal code is numeric.
As you can see in the figure, the postal codes for Ottawa and Burnaby are not numeric, whereas the postal
codes for the other cities are numeric.

Exploring the ROUND Function


As its name implies, the ROUND function rounds an expression to a specified length. Here’s an example:
Click here to view code image
SELECT ProductID, Name, ListPrice, Round(ListPrice, 0) FROM Production.Product This SQL
statement returns the ProductID, Name, ListPrice, and the ListPrice rounded to whole
numbers from the Production.Product table (see Figure 11.2).
FIGURE 11.2 A SELECT statement that utilizes the SQL ROUND function.
Notice in the figure that the list price of 133.34 is rounded to 133.00, whereas the list price of 196.92 is
rounded to 197.00. This is because all values less than .5 are rounded down, and all values .5 and higher
are rounded up.

Taking Advantage of String Functions


Important string functions include LEFT, RIGHT, LEN, REPLACE, REVERSE, REPLICATE, STUFF,
SPACE, SUBSTRING, LOWER, UPPER, LTRIM, and RTRIM.

Using the LEFT Function


The LEFT function extracts a designated number of characters from the left of a string:
Click here to view code image
SELECT ProductDescriptionID,
Description, LEFT(Description, 10)
FROM Production.ProductDescription

This example selects the ProductDescriptionID, the Description, and the ten leftmost characters from the
Production.ProductDescription table (see Figure 11.3).
FIGURE 11.3 A SELECT statement that utilizes the LEFT function.

Working with the RIGHT Function


The RIGHT function works similarly but extracts the designated rightmost characters from a string. The
same example using the RIGHT function looks like this:
Click here to view code image
SELECT ProductDescriptionID,
Description, RIGHT(Description, 10)
FROM Production.ProductDescription

This example returns the ProductDescriptionID, Description, and the ten rightmost characters from the
Description (see Figure 11.4).
FIGURE 11.4 A SELECT statement that utilizes the RIGHT function.

Exploring the LEN Function


The LEN function returns the length of a string. It looks like this:
Click here to view code image
SELECT ProductDescriptionID,
Description, LEN(Description)
FROM Production.ProductDescription

This example returns the ProductDescriptionID, Description, and the length of the description for each
row in the ProductDescription table (see Figure 11.5).
FIGURE 11.5 A SELECT statement that utilizes the LEN function.

Using the REPLACE Function


The REPLACE function replaces all occurrences of one string with another. Here’s an example:
Click here to view code image
SELECT ProductDescriptionID,
Description, REPLACE(Description, 'Bike', 'Bicycle')
FROM Production.ProductDescription

This example selects the ProductDescriptionID and Description from the ProductDescription table. It
includes an additional column that replaces all occurrences of the word Bike in the Description field
with the word Bicycle (see Figure 11.6).
FIGURE 11.6 A SELECT statement that utilizes the REPLACE function to replace all occurrences of
the word Bike with the word Bicycle.

Using the REVERSE Function


The REVERSE function returns the reverse image of a string. Here’s an example:
Click here to view code image
SELECT ProductDescriptionID,
Description, REVERSE(Description)
FROM Production.ProductDescription

This example selects the ProductDescriptionID and Description from the ProductDescription table. It
includes an additional column that displays the reverse of the characters in the Description field (see
Figure 11.7).
FIGURE 11.7 A SELECT statement that utilizes the REVERSE function.

Using the REPLICATE Function


The REPLICATE function replaces all occurrences of one string with another. Here’s an example:
Click here to view code image
SELECT ProductDescriptionID,
REPLICATE('0', 5 – DATALENGTH(RTRIM(ProductDescriptionID)))
+ RTRIM(ProductDescriptionID) AS PadZero
FROM Production.ProductDescription This example selects the ProductDescriptionID and the
result of an expression that pads the ProductDescription field with leading zeros from
the ProductDescription table. It accomplishes this by replicating the correct number of
leading zeros based on the length of the trimmed ProductDescriptionID so that all
ProductDescriptionID values are five digits in length (see Figure 11.8).
FIGURE 11.8 A SELECT statement that replicates the value 0 so that all ProductDescriptionID values
are the same length.

Taking Advantage of the STUFF Function


The STUFF function starts at a specific position and replaces a specified number of characters with other
specified characters. Here’s an example:
Click here to view code image
SELECT ProductDescriptionID,
Description,
STUFF(Description, 5, 10, '**********' ) AS Stuffed
FROM Production.ProductDescription This example selects the ProductDescriptionID and
Description from the Production.ProductDescription table. It includes an additional
column that replaces the fifth through fourteenth characters with asterisks (see Figure
11.9).
FIGURE 11.9 A SELECT statement that utilizes the STUFF function.

Using the SPACE Function


The SPACE function returns a specified number of spaces. Here’s an example:
Click here to view code image
SELECT FirstName + SPACE(1) + LastName
FROM Person.Person

This example returns the FirstName and LastName separated by one space from the Person.Person table
(see Figure 11.10).
FIGURE 11.10 A SELECT statement that utilizes the SPACE function.

Using the SUBSTRING Function


The SUBSTRING function extracts specified characters from a string. Here’s an example:
Click here to view code image
SELECT ProductDescriptionID, Description,
SUBSTRING(Description, 6,10)
AS PartOfDescription
FROM Production.ProductDescription This example returns the ProductDescriptionID,
Description, and the sixth through fifteenth characters of the Description field from the
Production.ProductDescription table (see Figure 11.11).
FIGURE 11.11 A SELECT statement that returns the ProductionDescriptionID, Description, and the
sixth through fifteenth characters of the Description from the ProductDescription table.

Using the LOWER Function


The LOWER function returns the lowercase version of a string. It looks like this:
Click here to view code image
SELECT ProductDescriptionID, Description, LOWER(Description)
FROM Customers Production.ProductDescription

The example returns the contents of the ProductDescriptionID and Description fields and then the
lowercase version of the contents of the Description field (see Figure 11.12).
FIGURE 11.12 A SELECT statement that returns the lowercase version of the contents of the
Description field.

Using the UPPER Function


The UPPER function returns the uppercase version of a string. It looks like this:
Click here to view code image
SELECT ProductDescriptionID, Description, UPPER(Description)
FROM Customers Production.ProductDescription

The example returns the contents of the ProductDescriptionID and Description fields and then the
uppercase version of the contents of the Description field (see Figure 11.13).
FIGURE 11.13 A SELECT statement that returns the uppercase version of the contents of the
Description field.

Working with the LTRIM Function


The LTRIM function returns the string without leading spaces. It looks like this:
Click here to view code image
SELECT ProductDescriptionID, LTRIM(Description)
FROM Production.ProductDescription

The example returns the contents of the ProductionDescriptionID field and then the contents of the
Description field with any leading spaces removed.

Working with the RTRIM Function


The RTRIM function returns the string without trailing spaces. It looks like this:
Click here to view code image
SELECT ProductDescriptionID, RTRIM(Description)
FROM Production.ProductDescription

The example returns the contents of the ProductDescriptionID field and then the contents of the
Description field with any trailing spaces removed.

Exploring the Date/Time Functions


Important date/time functions include GETDATE, MONTH, DAY, YEAR, DATEPART, DATENAME,
DATEADD, and DATEDIFF. The sections that follow cover these functions.

Using the GETDATE Function


The GETDATE function returns the system date and time. It looks like this:
SELECT GETDATE()

Learning About the MONTH Function


The MONTH function returns the month portion of a date. It looks like this:
Click here to view code image
SELECT Description, DiscountPct,
StartDate, MONTH(StartDate)
FROM Sales.SpecialOffer

This SQL statement returns the Description, Discount Percent, Start Date, and the month of the Start Date
from the SpecialOffer table (see Figure 11.14).
FIGURE 11.14 A SELECT statement that returns the month portion of the start date.

Exploring the DAY Function


The DAY function returns the day portion of a date. It looks like this:
Click here to view code image
SELECT Description, DiscountPct,
StartDate, DAY(StartDate)
FROM Sales.SpecialOffer

This SQL statement returns the Description, Discount Percent, Start Date, and the month of the Start Date
from the SpecialOffer table (see Figure 11.15).
FIGURE 11.15 A SELECT statement that returns the day portion of the start date.

Working with the YEAR Function


The YEAR function returns the year portion of a date. It looks like this:
Click here to view code image
SELECT Description, DiscountPct,
StartDate, YEAR(StartDate)
FROM Sales.SpecialOffer

This SQL statement returns the Description, Discount Percent, Start Date, and the month of the Start Date
from the SpecialOffer table (see Figure 11.16).
FIGURE 11.16 A SELECT statement that returns the year portion of the start date.

Exploring the Powerful DATEPART Function


You use the DATEPART function to extract a part of a date. The first parameter to the DATEPART
function is an abbreviation designating the part of the date you want to extract. The second parameter is
the date from which you want to extract it. Here’s an example:
Click here to view code image
SELECT Description, StartDate,
DATEPART(qq, StartDate) AS Quarter,
DATEPART(DAYOFYEAR, StartDate) as DOY
FROM Sales.SpecialOffer This example selects the Description, the Start Date, the quarter
of the Start Date, and the day of the year of the Start Date from the SpecialOffer table
(see Figure 11.17).
FIGURE 11.17 A SELECT statement that returns the quarter and day of the year of the StartDate from
the SpecialOffer table.

Using the DATENAME Function


The DATENAME function returns a string representing a part of a date. It also receives two parameters.
The first is the abbreviation indicating the part of the date you want to extract. The second is the date from
which you want to extract it. Here’s an example:
Click here to view code image
SELECT Description, StartDate,
DATENAME(dw, StartDate) as DOW
FROM Sales.SpecialOffer

This example returns the Description, the Start Date, and a text description of the day of the week of the
Start Date (see Figure 11.18).
FIGURE 11.18 A SELECT statement that returns a text description of the day of the week of the
StartDate.

Working with the DATEADD Function


You use the DATEADD function to add or subtract time from a date. The first parameter is the time period
you want to add or subtract (for example, day, month, year). The second parameter is the number of that
time period you want to add or subtract (for example, 1 day, 3 months, or 5 years). The final parameter is
the date to which you want to add it or from which you want to subtract it. Here’s an example:
Click here to view code image
SELECT Description, StartDate,
DATEADD(mm, 1, StartDate) AS Add1Month,
DATEADD(dd, -100, StartDate) AS Subtract100Days
FROM Sales.SpecialOffer This returns the description, the start date, the date one month
after the start date, and the date 100 days before the start date (see Figure 11.19).
FIGURE 11.19 A SELECT statement that returns the dates before and after the StartDate.

Using the DATEDIFF Function


The DATEDIFF function returns the difference between two dates. It receives three parameters. The first
is the time period in which you want the difference to appear (days, months, and so on). The second and
third parameters are the dates whose difference you want to evaluate. Here’s an example:
Click here to view code image
SELECT Description, StartDate, EndDate,
DATEDIFF(dd, StartDate, EndDate) AS DayDiff,
DATEDIFF(mm, StartDate, EndDate) AS MonthDiff
FROM Sales.SpecialOffer This example returns the Description, Start Date, End Date, the
number of days between the Start Date and the End Date, and the number of months between
the Start Date and the End Date (see Figure 11.20).
FIGURE 11.20 A SELECT statement that returns the number of days and months between the StartDate
and EndDate.

Working with Nulls


Several functions help you deal with nulls in your table data. They include ISNULL, NULLIF, and
COALESCE. The sections that follow cover these functions.

Exploring the ISNULL Function


The ISNULL function returns information on whether the value in an expression is null. It receives two
parameters. The first parameter is the expression you want to evaluate. The second is the value you want
to return if the expression is null. The ISNULL function looks like this:
SELECT Description, MinQty,
MaxQty, ISNULL(MaxQty, 100)
FROM Sales.SpecialOffer

This example returns the Description, Minimum Quantity, and Maximum Quantity field values. If the
Maximum Quantity is null, the fourth column contains the value 100. Otherwise, the fourth column
contains the actual Maximum Quantity value for the record (see Figure 11.21).
FIGURE 11.21 A SELECT statement that handles nulls in the MaximumQuantity field.

Taking Advantage of the NULLIF Function


The NULLIF function replaces specified values with nulls. It receives two parameters. The first is the
name of the expression you want to replace. The second is the value you want to replace with nulls.
Here’s an example:
Click here to view code image
SELECT AVG(MinQty) AS WithZero,
AVG(NULLIF(MinQty, 0)) AS NoZero
FROM Sales.SpecialOffer This example calculates the average Minimum Quantity amount in
the SpecialOffer table and then the average Minimum Quantity amount eliminating 0 values
from the calculation (see Figure 11.22).
FIGURE 11.22 A SELECT statement that calculates the average minimum quantity amount in the
SpecialOffer table, with and without including zero values in the calculation.

Working with the COALESCE Function


The COALESCE function returns the first non-null expression in a series of expressions. SQL Server
evaluates the first expression. If it is null, it evaluates the second expression. If the second expression is
null, it evaluates the third expression. This continues until the function reaches the last expression. Here’s
an example:
Click here to view code image
SELECT Title, MiddleName, FirstName,
COALESCE(Title, MiddleName, FirstName)
FROM Person.Person

This example returns the Title if it is not null. If the Title is null, it evaluates the contents of the
MiddleName field. If it is non-null, the contents of the MiddleName field are returned. Otherwise, it
evaluates the FirstName field (see Figure 11.23).
FIGURE 11.23 A SELECT statement that uses the COALESCE function to appropriately handle nulls
in the Title and MiddleName fields.

Summary
The T-SQL language provides you with a rich function library. Using this rich library of T-SQL functions,
you can manipulate your data in ways you probably haven’t even dreamed of. In this lesson, you learned
many of the commonly used numeric, string, and date-time functions. You also learned how functions can
help you with the process of handling null values in your data.

Q&A
Q. Explain what the STUFF function does.
A. The STUFF function starts at a certain position and replaces a specified number of characters with
other specified characters.
Q. Explain what the DATEPART function does.
A. The DATEPART function extracts part of a date. You designate the part of the date you want to
extract and the date from which you want to extract it.
Q. Explain the ISNULL function.
A. The ISNULL function returns information about whether the value in an expression is null. It
receives the expression you want to evaluate and the value you want to return if the expression is
null. It returns the specified value.

Workshop

Quiz
1. What function extracts specified characters from a string?
2. The NOW function returns the system date and time (true/false).
3. Name the two parameters to the DATEPART function.
4. What function finds the difference between two dates?
5. The NULLIF function determines whether a value is null (true/false).

Quiz Answers
1. The SUBSTRING function extracts specified characters from a string.
2. False. The GETDATE function returns the system date and time.
3. The first parameter is an abbreviation designating the part of the date you want to extract. The
second parameter is the date from which you want to extract it.
4. The DATEDIFF function.
5. False. The ISNULL function determines whether a value is null.

Activities
Practice executing T-SQL statements that contain functions. First, find the leftmost four characters of each
person’s LastName in the Person.Person table of the AdventureWorks2014 database. Next, find the fourth
through the eighth characters of the AddressLine1 field in the Person.Address table. Find the rightmost
four characters of the AddressLine1 field. Next replace all occurrences of the AddressLine1 of “Street”
with the word “Court.” Find the month of each ModifiedDate in the Person.Person table. Then extract the
quarter of each ModifiedDate in the Person.Address table. Find the difference in days between the
StartDate and the EndDate in the Production.ProductCostHistory table. Finally, use a SELECT statement
to display “No Address2” for all rows in the Person.Address table where the AddressLine2 field is null.
Lesson 12. Working with SQL Server Views

A view is a saved SELECT statement. A view can retrieve data from one or more tables. After you create
a view, you can select data from it just as you can select it from a table. In this lesson, you learn: What
views are and why you would want to use them How to use the SQL Server Management Studio Query
Builder to create a view How to use T-SQL to create or modify a view

An Introduction to Views
Views can only select data. They cannot update it (although you can update the data in the result of a
view). For example, a T-SQL UPDATE statement in a stored procedure updates data. Although you cannot
use a T-SQL UPDATE statement in a view, you can update the results returned from a SELECT statement.
Views have several advantages. They enable you to
Join data so that users can work with it easily.
Aggregate data so that users can work with it easily.
Customize data to users’ needs.
Hide underlying column names from users.
Limit the columns and rows with which a user works.
Easily secure data.
Although a normalized database is easy to work with and maintain from a programmer’s viewpoint, it is
not always easy for the user to work with. For example, if users look at the HumanResources.Employee
table, they see only the BusinessEntityID associated with the employee. If they want to see the employee’s
name, they must join the HumanResources.Employee table with the Person.Person table. This is not a
particularly easy task for users to accomplish. Using a view, you can join the HumanResources.Employee
table and the Person.Person table. You provide the view to the user. The user can build forms, queries,
and reports that are based on the view without having to understand how to join the underlying tables.
Just as a view can join data, it can also aggregate data. You can very easily create a view that contains the
total order amounts for each customer. The user can use the view as the foundation for forms, queries, and
reports they build. Once again, it is not necessary for the user to understand the syntax required to
aggregate the data.
Another advantage of views is their capability to customize data to the users’ needs. For example, a
column in a view can combine the first name and last name of a customer, or it can combine the
customer’s city, state, and ZIP Code. Users do not need to understand how to combine this information.
Instead, they use the view as the foundation for the forms, queries, and reports they need.
Developers often use column names that are not particularly intuitive for users. This is another situation
where views come to the rescue. You can easily build a view that aliases column names. Users will never
see the underlying column names. You simply provide them with access to the view, and they can easily
build forms, queries, and reports.
The number of fields in a table can be overwhelming to users. Most of the time, there are certain fields
that users need for the majority of the work they do. You can create views containing only the critical
fields, which simplifies the process when users build forms, queries, and reports based on the table data.
A major advantage of views is the security they provide. You can grant logins and roles the rights to
views without granting those logins and roles rights to the underlying tables. An example is an employee
table. You can create a view that includes the EmployeeID, FirstName, LastName, Extension, and other
nonsensitive fields. You can then grant rights to the view. Although the users have no rights to the
Employee table and therefore no access to fields such as the employee salary, they gain rights to the rows
and columns included in the view.
SQL Server views are very powerful. Using user-defined functions, you can parameterize views. Using
the TOP syntax, you can order view results. All these features make SQL Server views extremely
powerful!

Creating a Simple View


A view is actually a SELECT statement with a CREATE VIEW statement that causes SQL Server to save
it as a view. You can use a few different methods to create a SQL Server view. This lesson discusses the
following methods:
You can use the Microsoft SQL Server Management Studio Query Builder to create a view.
You can use T-SQL to create a view.
The sections that follow cover each of these options.

Using the Microsoft SQL Server Management Studio Query Builder to Create a
View
The Management Studio Query Builder facilitates the process of creating a view. To create a view,
follow these steps:
1. Right-click the Views node of the database in which you want the view to appear and select New
View. The Add Table dialog box appears (see Figure 12.1).

FIGURE 12.1 The Add Table dialog enables you to add tables, views, functions, and synonyms to
your view.
2. Click each table, view, function, and synonym you want to add to the view and click Add. In the
example shown in Figure 12.2, the Sales.Customer and Sales.SalesOrderHeader tables are included
in the view.
FIGURE 12.2 The Sales.Customer and Sales.SalesOrderHeader tables appear joined in the View.
3. Click Close when you have finished adding objects to the view. Your screen should appear as in
Figure 12.3.
FIGURE 12.3 A new view that includes the Sales.Customer and Sales.SalesOrderHeader tables.
4. Click the check boxes to the left of the field names to select the fields you want to add to the view.
If you prefer, you can drag and drop fields to the column list on the query grid. Figure 12.4 shows a
view with the CustomerID, AccountNumber, SalesOrderID, OrderDate, and SalesOrderNumber
fields included.
FIGURE 12.4 A View with selected fields and criteria.
5. Specify any criteria that you want to apply to the view. To add criteria, enter the desired criteria in
the Criteria column of the appropriate field on the query grid. Adding criteria limits the records
returned when you execute the view. Figure 12.5 shows criteria limiting the selected records to
those with order date values between 6/1/14 and 6/30/14.
FIGURE 12.5 A view that limits the output to orders with order dates between 6/1/14 and 6/30/14.
6. Test the view using the Run button. The output should appear as in Figure 12.6.
FIGURE 12.6 The results of the view appear in the Output pane.
7. Attempt to close the view. SQL Server prompts you to save changes to the view.
8. The view appears in the list of views under the Views node. You can treat it much like a table.

Note
The views you create do not automatically appear on the Views node. To make them appear,
right-click the Views node and select Refresh.

Note
The view builder offers four panes: the diagram pane, the grid pane, the SQL pane, and the
results pane. The diagram pane shows you the tables included in the view. The grid pane
graphically presents you with the columns, aliases, tables, groupings, and criteria for the data
in the view. The SQL pane shows you the actual SQL statement that underlies the view. The
results pane provides you with the results of executing the view. You can easily hide and
show each of these panes with the Show/Hide Diagram Pane tool, Show/Hide Grid Pane
tool, Show/Hide SQL Pane tool, and Show/Hide Results Pane tool, respectively.
To use SQL Server Management Studio to modify a view:
1. Expand the Views node for the database until you can see the view you want to modify.
2. Right-click the view you want to modify and select modify. The view appears as in Figure 12.7.

FIGURE 12.7 Modifying a view is similar to building a new view.


3. Make the desired changes and then close and save the view.

Tip
You can easily drag and drop tables to the diagram pane of the view. Simply resize the View
and Object Explorer windows so that you can see both windows simultaneously and then
drag and drop the tables from the Tables node of the appropriate database to the diagram
pane of the view.

Using T-SQL to Create or Modify a View


In addition to using the Management Studio View Builder to build a view, you can use T-SQL to create a
view. Rather than building the view graphically, as outlined in the preceding section, you type the entire
CREATE VIEW statement from scratch. The syntax for a CREATE VIEW statement is as follows:
Click here to view code image
CREATE VIEW [DatabaseName] [<owner>] ViewName
[(column [,...n])]
[WITH <ViewAttribute> [,...n]]
AS
SelectStatement
[WITH CHECK OPTION]

<ViewAttribute> :: = [ENTCRYPTION|SCHEMASBINDING|VIEW_METADATA]

An example of a CREATE VIEW statement is the following:


Click here to view code image
CREATE VIEW vwUSACustomers
AS
SELECT CustomerID, FirstName, LastName, City
FROM Sales.vIndividualCustomer
WHERE CountryRegionName = 'United States'

The statement creates a view named vwUSACustomers, which selects the contents of the
BusinessEntityID, FirstName, LastName, and City fields from the Sales.vIndividualCustomer view for all
customers in the USA.
To type and execute the CREATE VIEW statement, follow these steps:
1. Click the New Query button on the toolbar. Your screen appears as in Figure 12.8.
FIGURE 12.8 The screen after clicking the New Query button on the toolbar.
2. Type the SQL statement into the available pane.
3. Click the Execute button on the toolbar. The results should appear as in Figure 12.9.
FIGURE 12.9 The results of using the Execute button to create a new view.
If you want use T-SQL to modify a view, you must use an ALTER VIEW statement rather than a CREATE
VIEW statement. An example of an ALTER VIEW statement is shown here: Click here to view code
image
ALTER VIEW vwUSACustomers
AS
SELECT CustomerID, FirstName, LastName, City
FROM Sales.vIndividualCustomer
WHERE CountryRegionName = 'Australia'

This example modifies the vwUSACustomers view, changing the criteria to return all the customers in
Australia.

Summary
Views are a critical part of any application you build. It is therefore important you understand how to
create and work with views. In this lesson, you learned how to create and modify simple views, using
both the SQL Server Management Studio and T-SQL.
Q&A
Q. Name some advantages of views.
A. Views enable you to join data, aggregate data, customize data to the user’s needs, hide underlying
column names from users, limit the columns and rows a user works with, and easily secure data.
Q. Explain why you would want to join data so that users can easily work with it.
A. A normalized database is not always easy for the user to work with. For example, only the
CustomerID is stored in the Orders table. The Company Name is stored in the Customers table. To
see both the Customer and Order information, the user must join the tables. Using a view, you can
join the tables for the user so that he or she can work with the view as if it were a single table.
Q. Explain what it means to customize data to a user’s needs.
A. Using a view, you can create a column that combines first, middle, and last name of an employee or
the city, state, and ZIP Code from an address. This makes it much easier for the user to work with
this data.
Q. How do views help you to secure data?
A. You can grant rights to logins and roles to the views you create. It is not necessary to grant rights to
the underlying tables. In this way, you can give users access to just desired columns and rows. For
example, you can give users rights to name and address data for the sales department in the
employee table.

Workshop

Quiz
1. Name two ways you can create a view.
2. What statement do you use to create a view?
3. The result of a view is updateable (true/false).
4. Name the four panes of the view builder.
5. You cannot drag and drop tables onto the diagram pane of the view (true/false).
6. What statement do you use to modify a view?

Quiz Answers
1. Using SQL Server Management Studio and using T-SQL.
2. CREATE VIEW.
3. True.
4. Diagram, grid, SQL, and results.
5. False. You can drag and drop from the Tables node of the appropriate databases to the diagram
pane of the view.
6. ALTER VIEW.
Activities
Create a view by using the Microsoft SQL Server Management Studio Query Builder. Include
BusinessEntityID, JobTitle, BirthDate, Gender, HireDate, VacationHours, and SickLeaveHours from the
HumanResources.Employee table. Sort the result in ascending order and return just the rows where the
HireDate is between 1/1/2013 and 12/31/2013. Close and save the view as vw2013Hires. Modify the
view and add the LoginID to the view. Create another view by using T-SQL. Include the
BusinessEntityID, SalesQuota, Bonus, SalesYTD, and SalesLastYear from the Sales.SalesPerson table.
Sort in descending order by SalesYTD and return just the rows where the SalesYTD is greater than 2
million. Close and save the view as vwBigHitters. Modify the view (using T-SQL) and add the
CommissionPct field to the view. Change the criteria for the SalesYTD to 3 million.
Lesson 13. Using T-SQL to Design SQL Server Stored Procedures

Stored procedures are at the heart of any client/server application. Using stored procedures, you can
guarantee that processing is completed on the server. Stored procedures have many other benefits as well,
including the following: Stored procedures help you to separate the client application from the
database’s structure.
Stored procedures help you to simplify client coding.
Stored procedures process at the server (reduces required bandwidth).
Stored procedures enable you to create reusable code.
Stored procedures enable you to perform error-handling at the server.
Stored procedures facilitate the security of data.
Because stored procedures are precompiled, they execute more quickly.
Stored procedures improve the application’s stability.
Stored procedures reduce network locking.
When you build a stored procedure, a query plan is created. This query plan contains the most
efficient method of executing the stored procedure given available indexes and so on.
In this lesson, you learn:
The basics of working with stored procedures
How to declare and work with variables
How to control the flow of the stored procedures you write

The Basics of Working with Stored Procedures


Creating stored procedures in SQL Server Management is easy. You can create a stored procedure using
the Query Editor or T-SQL.

Designing a Stored Procedure in the Query Editor


Although you may not be able to design an entire stored procedure in the Query Editor, you will probably
find it easiest to use the Query Editor to design the T-SQL statement you include in your stored procedure.
Take the steps that follow to build the SELECT statement you want to include:
1. Expand the Programmability node of the database you are working with so that you can see the
Stored Procedures node underneath it (see Figure 13.1).
FIGURE 13.1 The Stored Procedures node appears under the Programmability node.
2. Right-click the Stored Procedure node and select New, Stored Procedure. A template for a stored
procedure appears in the Query Editor (see Figure 13.2).
FIGURE 13.2 When you create a stored procedure, Management Studio provides you with a template
for that stored procedure.
3. Click and drag over the SELECT statement included in the template and press the Delete key to
delete it.
4. Right-click in that same location and select Design Query in Editor. The Add Table dialog box
appears (see Figure 13.3).
FIGURE 13.3 You replace the template SQL statement with the SQL statement generated by the Query
Editor.
5. Add the desired tables to the query by selecting each table and clicking Add.
6. Click Close to complete the process. The Query Designer should look similar to Figure 13.4.
FIGURE 13.4 The Query Designer appears with the selected tables.
7. Click to add the desired fields to the SELECT statement. Click OK when finished. The stored
procedure should appear as in Figure 13.5.
FIGURE 13.5 The generated SQL statement appears within the stored procedure template.
8. Modify the stored procedure, adding all of the functionality you want it to have.
9. After completing the stored procedure, click Execute to execute the CREATE PROCEDURE
statement.
10. You only need to save if you want to store the T-SQL behind the stored procedure in an external
file.
To make the generated stored procedure execute, you must provide the stored procedure with a name and
delete all of the superfluous template code, such as the declaration of parameters. An example of a stored
procedure that has been modified appears in Figure 13.6.
FIGURE 13.6 A stored procedure modified to properly execute.

Using T-SQL to Create a Stored Procedure


Sometimes you might not find it useful to use the Query Editor to get started in creating a stored
procedure. In that case, you simply create the stored procedure and begin modifying the template as
desired. Here are the steps involved:
1. Expand the Programmability node of the database you are working with so that you can see the
Stored Procedures node underneath it.
2. Right-click the Stored Procedure node and select New, Stored Procedure. A template for a stored
procedure appears in the Query Editor.
3. Type the body of the stored procedure.
4. After completing the stored procedure, click Execute to execute the CREATE PROCEDURE
statement.
5. You only need to save if you want to store the T-SQL behind the stored procedure in an external
file.
Executing the Stored Procedures You Build
Regardless of the method you use to create a stored procedure, Management Studio creates a new stored
procedure, available under the Stored Procedures node, which is part of the Programmability node. Use
the following steps to execute a stored procedure:
1. Click to expand the Programmability node.
2. Click to expand the Stored Procedures node.
3. If you don’t see the stored procedure you want to execute, right-click the Stored Procedures node
and select Refresh.
4. Right-click the stored procedure you want to execute and select Execute Stored Procedure. The
Execute Procedure dialog box appears (see Figure 13.7).

FIGURE 13.7 The Execute Procedure dialog box enables you to supply parameters and execute the
stored procedure.
5. Supply the values of any required parameters and click OK to execute the stored procedure. The
results appear as in Figure 13.8.
FIGURE 13.8 The result of executing a stored procedure that returns data from the Person.Person
table.

Declaring and Working with Variables


Just as you can create variables within the subroutines and functions you build, you can also declare
variables in your stored procedures. You use the keyword DECLARE to create a variable. The syntax
looks like this:
Click here to view code image
DECLARE @VariableName DataType [(length)], @VariableName DataType [(length)]

Here’s an example:
DECLARE @FirstName VarChar(35)

Uninitialized variables are assigned the value Null. You use a SELECT statement to assign a value to a
variable. It looks like this: SELECT @FirstName = 'Alexis'
The following is a stored procedure that illustrates the use of a variable:
Click here to view code image
DECLARE @strFirstName nvarchar (50)
SELECT @strFirstName = Upper(FirstName)
FROM Person.Person
WHERE LastName = 'Erickson'
SELECT @strFirstName This example declares a variable called @strFirstName. The code
stores the uppercase version of the FirstName associated with the last name Erickson into
the variable. The procedure returns the variable using a SELECT statement. Figure 13.9
illustrates the result of executing the sample stored procedure.

FIGURE 13.9 An example of a variable used in a stored procedure.

Controlling the Flow


Often you want specified statements in your stored procedure to execute only if certain conditions are
true. T-SQL contains several constructs that enable you to control the flow of your stored procedures.
These include BEGIN...END, IF...ELSE, GOTO, RETURN, CASE, and WHILE. The sections that
follow cover each of these constructs.

Using IF...ELSE
You use the IF...ELSE construct to make a decision within the stored procedure. This decision is
generally based on parameters supplied to the stored procedure. The IF...ELSE construct works like
this:
Click here to view code image
IF (SomeCondition)
BEGIN
--Execute multiple statements
END

With this version of the IF...ELSE construct, certain statements execute only if the condition is true.
No special statements execute if the condition is false. The construct that follows accommodates the
scenario when the condition is false: Click here to view code image
IF (SomeCondition)
BEGIN
--Execute multiple statements
END
ELSE
BEGIN
--Execute multiple statement
END

Here’s an example of an IF...THEN construct in action:


Click here to view code image
DECLARE @Locale VarChar(20), @Country VarChar(30)

SELECT @Country = CountryRegionName


FROM Sales.vIndividualCustomer
WHERE BusinessEntityID = 1700

IF @Country = 'United States'


BEGIN
SELECT @Locale = 'Domestic'
END
ELSE
BEGIN
SELECT @Locale= 'Foreign'
END

SELECT BusinessEntityID, @Country, @Locale


FROM Sales.vIndividualCustomer
WHERE BusinessEntityID = 1

The code begins by declaring two variables: @Locale and @Country. It stores the contents of the
CountryRegionName field for the BusinessEntityID 1700 into the @Country variable. It then evaluates
the contents of the @Country variable, storing the appropriate locale into the @Locale variable.
Finally, it returns the BusinessEntityID, the contents of the @Country variable, and the contents of the
@Locale variable for the customer with the BusinessEntityID 1700. Figure 13.10 provides an example
of executing the stored procedure.
FIGURE 13.10 An example of executing a stored procedure that includes an IF...ELSE construct.

Note
It is important to note that if you want to execute more than one statement under a specific
condition, you must enclose the statements within the BEGIN...END construct (see the
following section).

Working with BEGIN...END


The BEGIN...END construct enables you to group a series of statements together. Without the
BEGIN...END construct, only the first statement after the IF or the ELSE executes. Consider the
following example:
Click here to view code image
DECLARE @Locale VarChar(20), @Country VarChar(30)

SELECT @Country = CountryRegionName


FROM Sales.vIndividualCustomer
WHERE BusinessEntityID = 1700

IF @Country = 'United States'


BEGIN
SELECT @Locale = 'Domestic'
PRINT 'This is domestic'
PRINT ' '
PRINT 'Hello there'
END
ELSE
BEGIN
SELECT @Locale= 'Foreign'
PRINT 'This is foreign'
PRINT ' '
PRINT 'Hello there'
END

SELECT BusinessEntityID, @Country, @Locale


FROM Sales.vIndividualCustomer
WHERE BusinessEntityID = 1700

In this example, multiple statements execute if the condition is true, and multiple statements execute if the
condition is false. Without the BEGIN...END construct after the IF, the code renders an error. Figure
13.11 shows the Messages tab after executing this stored procedure.

FIGURE 13.11 An example of executing a stored procedure that includes multiple statements between
a BEGIN...END construct.
Exploring GOTO, RETURN, and Labels
You use the GOTO statement to jump to a label in your stored procedure. Programmers seem to use this
statement most commonly in error handling. The RETURN statement unconditionally exits the stored
procedure without executing any other statements. These three keywords are covered together because
they generally work as a group. Consider the following examples:
Click here to view code image

IF Month(GetDate()) > 6
BEGIN
PRINT 'In IF Statement'
GOTO MyLabel
END
SELECT FirstName, LastName FROM Person.Person

MyLabel:
SELECT Left(FirstName, 1) + '.' +
Left(LastName, 1) + '.'
FROM Person.Person This example evaluates to see whether the month associated with the
current date is greater than the value six. If it is, the statement In IF Statement
appears and code execution jumps to the label MyLabel without executing the first SELECT
statement. The procedure then selects the initials from the Person.Person table. If the
month associated with the current date is less than or equal to the value six, the
procedure first selects the first and last name from the Person.Person table. Code
execution then continues at the label where the procedure selects the initials from the
Person.Person table. Figure 13.12 shows an example of executing the code when the month
associated with the current date is greater than six. Figure 13.13 shows the sample
procedure where the month associated with the current date is less than or equal to six.
FIGURE 13.12 An example of executing a stored procedure that includes GOTO and a label.
FIGURE 13.13 An example of executing the same stored procedure with a different value for the
month of the current date.
As mentioned, a RETURN statement unequivocally exits from the procedure. Take a look at the procedure
that follows: Click here to view code image
IF Month(GetDate()) > 6
BEGIN
PRINT 'In IF Statement'
GOTO MyLabel
END
SELECT FirstName, LastName FROM Person.Person
RETURN

MyLabel:
SELECT Left(FirstName, 1) + '.' +
Left(LastName, 1) + '.'
FROM Person.Person In this example, if the month associated with the current date is
greater than the value six, the In IF Statement message appears, and then the procedure
executes the code in MyLabel, returning the initials associated with each name in the
Person.Person table. If the month associated with the current date is less than or equal
to the value six, the code selects the first and last name from the Person.Person table
and then exits the procedure. Because of the RETURN statement, the procedure does not
select the initials from the Person.Person table. Figure 13.14 shows an example of
executing the code when the month associated with the current date is less than or equal
to six. Figure 13.15 shows the sample procedure where the month associated with the
current date is greater than six.

FIGURE 13.14 An example of executing a stored procedure that includes the RETURN statement.
FIGURE 13.15 An example of executing the same stored procedure with a different value for the
month of the current date.

Working with the CASE Statement


Most developers use the CASE statement to compare a result from a SQL statement against a set of simple
responses. The CASE statement returns the appropriate value. The CASE statement looks like this:
Click here to view code image
CASE InputExpression
WHEN WhenExpression THEN ResultExpression
[...n]
[ELSE ElseResultExpression]
END

Here’s an example of this use of a case statement:


Click here to view code image
SELECT SalesOrderID, ShipDate,
CASE ShipMethodID
WHEN 1 THEN 'UPS'
WHEN 3 THEN 'FedEx'
WHEN 5 THEN 'U.S. Mail'
END AS Shipper,
Freight FROM Sales.SalesOrderHeader
WHERE ShipDate BETWEEN '1/1/13' AND '2/28/13'
AND Freight <= 50

The expression selects the SalesOrderID, ShipDate, and Freight fields from the Sales.SalesOrderHeader
table. The CASE statement evaluates the contents of the ShipMethodID field. It returns an appropriate
string depending on the value in the ShipMethodID field. Figure 13.16 illustrates this example.

FIGURE 13.16 An example of executing a CASE statement that evaluates a field, returning different
values depending on what the field contains.
The second use of the CASE construct looks like this:
Click here to view code image

CASE
WHEN Expression THEN TruePart
ELSE FalsePart
END

Here’s an example:
Click here to view code image
DECLARE @AverageFreight Money
SELECT @AverageFreight = AVG(Freight)
FROM Sales.SalesOrderHeader
SELECT SalesOrderID, ShipDate, Freight,
CASE
WHEN FREIGHT <= @AverageFreight THEN 'Low Freight'
WHEN FREIGHT = @AverageFreight THEN 'Average Freight'
ELSE 'High Freight'
END AS FreightRating
FROM Sales.SalesOrderHeader The example first declares the @AverageFreight variable. It
sets the variable equal to the average freight amount from the Sales.SalesOrderHeader
table. The CASE statement evaluates whether the freight of the current row is less than
the average freight amount. If so, the statement returns Low Freight. If it is equal to
the average freight amount, it returns Average Freight. Otherwise, it returns High
Freight. This value is combined with the SalesOrderID, ShipDate, and Freight amounts that
are also selected from the table. Figure 13.17 shows this use of the CASE statement in
action.

FIGURE 13.17 A CASE statement that uses the ELSE keyword.

Exploring the WHILE Statement


You use the WHILE statement when you want to set up a loop. The loop continues to execute until the
specified condition is met. The WHILE construct looks like this:
Click here to view code image

WHILE BooleanExpression
(SQLStatement | SQLBlock)

Here’s an example:
Click here to view code image
IF NOT EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[MyTable]')

CREATE TABLE MyTable


(
LoopID INT,
LoopText VarChar(25)
)

DECLARE @LoopValue INT


DECLARE @LoopText CHAR(25)

SELECT @LoopValue = 1

WHILE (@LoopValue < 100)


BEGIN
SELECT @LoopText = 'Iteration #' + Convert(VarChar(25), @ LoopValue)
INSERT INTO MyTable(LoopID, LoopText)
VALUES (@LoopValue, @LoopText)
SELECT @LoopValue = @LoopValue + 1
END

SELECT * FROM MyTable The routine first checks for the existence of a table called
MyTable, deleting it if it exists. It then creates a table called MyTable. The table
contains two fields: an INT field and a VARCHAR field. The routine then declares two
variables, an INT variable and a VARCHAR variable. It sets the value of the @LoopValue
variable to one. The code then loops from 1 to 100. As it loops, it sets the VARCHAR
variable equal to the text Iteration # combined with the contents of the @LoopValue
variable converted to a VARCHAR. Next, it inserts the contents of the @LoopValue and
@LoopText variables into the table. Finally, it increments the value of the @LoopValue
variable. Figure 13.18 shows the results of executing the WHILE statement.
FIGURE 13.18 With a WHILE statement, the loop continues to execute until the specified condition is
met.

Summary
Stored procedures have many benefits. In this lesson, you learned the ins and outs of working with stored
procedures. You learned the basics of stored procedures and how to declare and work with variables.
Finally, you learned numerous ways you can control the flow of the stored procedures you write.

Q&A
Q. What happens if you forget to use BEGIN and END with the IF...ELSE construct?
A. If you forget to place a BEGIN...END construct on the line immediately following the IF
statement or the ELSE statement, only the first statement after the IF or the ELSE executes.
Q. What does the RETURN statement do?
A. The RETURN statement unconditionally exits a stored procedure without executing any other
statements.
Q. Why would you use the CASE statement?
A. You use the CASE statement to compare a result from a SQL statement against a set of simple
responses. For example, a CASE statement might evaluate the contents of the ContactTitle
field and return an appropriate string based on those contents.

Workshop

Quiz
1. What is the main benefit of stored procedures?
2. What keyword do you use to assign a value to a variable?
3. What construct do you use to group a series of SQL statements together?
4. When is the GOTO statement most commonly used?
5. What does a GOTO statement do?

Quiz Answers
1. You guarantee the code will execute on the server.
2. The SELECT keyword.
3. BEGIN..END.
4. In error handling.
5. Jump to a label in your stored procedure.

Activities
Use SQL Server Management Studio to practice creating a stored procedure. First, use the Query Editor
to build a SQL statement that joins the Person.Person, Person.BusinessEntityContact, and
Person.ContactType tables. Include the FirstName and LastName from the Person table, the
ContactTypeID from the BusinessEntityContact table, and the Name from the ContactType table. Include
the resulting SQL statement in a procedure that determines whether the Name field in the ContactType
table that is associated with a person is Owner. If the Name is Owner, store Head Hancho into a variable
called @TitleName. If the Name is not Owner, store Peon into the @TitleName variable. Finally,
return the contents of the FirstName and LastName fields and the @TitleName variable for each record
in the Person table.
Lesson 14. Stored Procedure Techniques Every Developer Should
Know

The previous lesson covered the basics of working with stored procedures. To really be effective in
working with stored procedures, you must learn additional techniques. In this lesson, you learn about:
The SET NOCOUNT statement
How to use the @@ functions in the stored procedures that you build
How to work with input and output parameters
How to add error handling to your stored procedures

The SET NOCOUNT Statement


The SET NOCOUNT statement, when set to ON, eliminates the xx row(s) affected message in the
SQL Management Studio window. It also eliminates the DONE_IN_PROC communicated from SQL
Server to the client application. For this reason, the SET NOCOUNT ON statement, when included,
improves the performance of the stored procedure. Here’s an example:
Click here to view code image
CREATE PROCEDURE procPersonGetNoCount AS
SET NOCOUNT ON
SELECT BusinessEntityID, FirstName, LastName
FROM Person.Person
ORDER BY LastName, FirstName

If you execute this stored procedure from within SQL Server Management Studio, you’ll notice that the xx
row(s) affected message does not appear (see Figure 14.1). You might wonder how with SET
NOCOUNT ON in effect, you can return the number of rows affected to the client application. Fortunately,
this is easily accomplished with the @@RowCount system variable. The following section covers the
@@RowCount system variable as well as other system variables.
FIGURE 14.1 With a NOCOUNT statement, the xx row(s) affected message does not appear.

Using the @@ Functions


Developers often refer to the @@ functions as global variables. In fact, they don’t really behave like
variables. You cannot assign values to them or work with them as you would work with normal variables.
Instead, they behave as functions that return various types of information about what is going on in SQL
Server.

Using the @@RowCount System Variable


The @@RowCount variable returns the number of rows returned by a selected statement or affected by a
statement that modifies data. It returns zero if no values are returned by the select statement or modified
by the action query. Here’s an example:
Click here to view code image

CREATE PROCEDURE procPersonGetNoCount AS


SET NOCOUNT ON
SELECT BusinessEntityID, FirstName, LastName
FROM Person.Person
ORDER BY LastName, FirstName
SELECT @@RowCount as NumberOfPeople
The example selects all employees who are sales representatives from the Employee table. It returns the
number of rows selected (see Figure 14.2).

FIGURE 14.2 The @@RowCount variable returns the number of rows returned by a selected
statement or affected by a statement that modifies data.

Note
You can also see the results of the SELECT @@RowCount statement if you change the
query results to display as text rather than as grid. To do this, select Query, Results To,
Results to Text.

Using the @@TranCount System Variable


The @@TranCount function is applicable when you are using explicit transactions. Transactions are
covered in Lesson 15, “Power Stored Procedure Techniques.” The BEGIN TRAN statement sets the
@@TranCount to one. Each ROLLBACK TRAN statement decrements @@TranCount by one. The
COMMIT TRAN statement also decrements @@TranCount by one. When you use nested transactions,
@@TranCount helps you to keep track of how many transactions are still pending.
Using the @@Identity System Variable
The @@Identity function retrieves the new value inserted into a table that has an identity column.
Here’s an example:
Click here to view code image

INSERT INTO Purchasing.ShipMethod


(Name, ShipBase, ShipRate)
VALUES ('Speedy Freight', 120, 150)
SELECT @@Identity

The example inserts a row into the ShipMethod table. It returns the identity value of the inserted row (see
Figure 14.3).

FIGURE 14.3 The @@Identity function retrieves the new value inserted into a table that has an
identity column.

Using the @@Error System Variable


The @@Error function returns the number of any error that occurred in the statement immediately
preceding it. Here’s an example:
Click here to view code image
INSERT INTO Sales.SalesOrderDetail
(CarrierTrackingNumber, OrderQty,
ProductID, SpecialOfferID,
UnitPrice, UnitPriceDiscount)
VALUES (1, 1, 1, 1, 100.00, .05)
SELECT @@Error

This example attempts to insert a row into the SalesOrderDetail table. If it is successful, @@Error
returns zero. If you attempt to insert a sales order detail record without supplying a value for the
SalesOrderID field, it returns error number 515, an error indicating that you cannot insert a NULL value
into a column (see Figure 14.4).

FIGURE 14.4 The @@Error function returns the number of any error that occurred in the statement
immediately preceding it.
It is important to note that @@Error returns the error number associated with the line of code
immediately preceding it. Consider this example:
Click here to view code image
INSERT INTO Sales.SalesOrderDetail
(CarrierTrackingNumber, OrderQty,
ProductID, SpecialOfferID,
UnitPrice, UnitPriceDiscount)
VALUES (1, 1, 1, 1, 100.00, .05)
SELECT @@Identity
SELECT @@Error

Although the INSERT statement renders an error, the @@Error function returns zero (see Figure 14.5)
because the SELECT @@Identity statement executes without error.

FIGURE 14.5 An example where the error number is not properly reported.

Working with Parameters


Some stored procedures have no interface. They are called, but they do not receive or return anything.
Other procedures are input only. These stored procedures have input parameters but no output parameters.
A third type of stored procedure has both input parameters and output parameters.

Input Parameters
An example of a stored procedure that has neither input nor output parameters is this one:
Click here to view code image

CREATE PROCEDURE procEmployeeGetYoungSalesReps


AS
SELECT BusinessEntityID, JobTitle,
BirthDate, HireDate,
VacationHours
FROM HumanResources.Employee
WHERE JobTitle Like 'Marketing %' AND
BirthDate >= '1/1/1981'
ORDER BY BirthDate

Contrast this stored procedure with the following:


Click here to view code image
CREATE PROCEDURE procEmployeeGetByTitleAndBirthDate
@JobTitle nVarChar(50),
@BirthDate DateTime
AS
SELECT BusinessEntityID, JobTitle,
BirthDate, HireDate,
VacationHours
FROM HumanResources.Employee
WHERE JobTitle = @JobTitle AND
BirthDate >= @BirthDate
ORDER BY BirthDate

The procedure receives two input parameters, @JobTitle and @BirthDate. The procedure uses
these input parameters as variables for the WHERE clause for job title and birth date. The easiest way to
execute this procedure from within SQL Server Management Studio is the following:
1. Right-click the procedure and select Execute Stored Procedure. The Execute Procedure dialog box
appears. Notice in Figure 14.6 that the dialog box prompts you for the two parameters.
FIGURE 14.6 The Execute Procedure dialog box prompts you for all parameters.
2. Enter the parameter values in the Value column and click OK. The results of executing the stored
procedure appear.
Another method that you can use to execute the stored procedure is using the New Query toolbar option:
1. Click the New Query toolbar button. A blank query window appears.
2. Type the name of the procedure you want to execute, followed by the parameter values. You must
separate each parameter with commas (see Figure 14.7).
FIGURE 14.7 A parameterized stored procedure that returns records if the criteria are met.
3. Click Execute or press F5. The procedure executes.
The parameters in this stored procedure are required. If you do not supply them when you call the
procedure, an error results (see Figure 14.8). The following is the same procedure with the job title set up
as an optional parameter.
FIGURE 14.8 An error occurs if you omit a required parameter.
Click here to view code image

CREATE PROCEDURE procEmployeeGetByTitleAndBirthDateOpt


@JobTitle nVarChar(50) = NULL,
@BirthDate DateTime
AS
IF @JobTitle IS NULL
BEGIN
SELECT BusinessEntityID, JobTitle, BirthDate,
HireDate, VacationHours
FROM HumanResources.Employee
WHERE BirthDate >= @BirthDate
ORDER BY BirthDate
END
ELSE
BEGIN
SELECT BusinessEntityID, JobTitle, BirthDate,
HireDate, VacationHours
FROM HumanResources.Employee
WHERE JobTitle = @JobTitle AND
BirthDate >= @BirthDate
ORDER BY BirthDate
END

You establish an optional parameter by supplying SQL Server with a default value for the parameter. In
this example, @JobTitle is an optional parameter, but @BirthDate is required. If you opt to omit the
@JobTitle parameter, you would call the stored procedure like this:
Click here to view code image
procEmployeesGetByTitleAndBirthDateOpt @BirthDate = '1/1/1960'

Notice that the example supplies the @BirthDate parameter as a named parameter. If you omit the
@JobTitle parameter when you call the procedure, the procedure sets its value to Null. The stored
procedure evaluates the value of the @JobTitle variable. If it is Null (it wasn’t supplied), the WHERE
clause omits the title from the selection criteria. If the user of the stored procedures supplies the
@JobTitle parameter, the procedure uses the @JobTitle parameter in the criteria for the WHERE
clause.

Output Parameters
So far, we have looked only at input parameters—parameters that the user of the stored procedure
supplies to the procedure. You can also declare output parameters in the stored procedures you build.
SQL Server returns output parameters to the caller (as their name implies). Here’s an example:
Click here to view code image
CREATE PROCEDURE procEmployeesGetByTitleAndBirthDateOutput
@JobTitle nVarChar(50) = NULL,
@BirthDate DateTime,
@MyMessage VarChar(50) = NULL OUTPUT
AS
IF @JobTitle IS NULL
BEGIN
SELECT BusinessEntityID, JobTitle, BirthDate,
HireDate, VacationHours
FROM HumanResources.Employee
WHERE BirthDate >= @BirthDate
ORDER BY BirthDate
SELECT @MyMessage = 'No Title'
END
ELSE
BEGIN
SELECT BusinessEntityID, JobTitle, BirthDate,
HireDate, VacationHours
FROM HumanResources.Employee
WHERE JobTitle = @JobTitle AND
BirthDate >= @BirthDate
ORDER BY BirthDate
SELECT @MyMessage = 'Job Title Supplied'
END
SELECT @MyMessage

In addition to receiving two parameters, this procedure also has an output parameter called
@MyMessage. The IF statement within the procedure sets the value of @MyMessage to the
appropriate string (see Figure 14.9). You will see additional examples of OUPUT parameters and their
uses as you move through the material. In particular, you will see examples of ADO code that utilize the
output parameters within the client/server applications you build.
FIGURE 14.9 The IF statement within the procedure sets the value of @MyMessage to the
appropriate string.

Note
To see the output parameter, you can also change the query results to display as text. To do
this, select Query, Results To, Results to Text.

Errors and Error Handling


So far, the examples in this lesson have contained no error handling. This means that they leave what
happens when an error occurs up to chance. Although T-SQL provides a means of handling errors, the
error handling model in T-SQL is not as powerful as that in many programming languages. Because there’s
no ON ERROR GOTO statement, you must handle errors as they occur.

Handling Runtime Errors


One alternative to handling errors as they occur is to prevent errors from occurring in the first place. The
SalesOrderDetail table in the AdventureWorks database requires that data be entered for the several of
the fields. The SalesOrderDetailID field is an IDENTITY column, so this is not of concern. Here’s the
error that occurs if a value is not supplied for the SalesOrderID field:
Click here to view code image
Msg 515, Level 16, State 2, Line 1
Cannot insert the value NULL into column 'SalesOrderID',
table 'AdventureWorks.Sales.SalesOrderDetail';
column does not allow nulls. INSERT fails.
The statement has been terminated.

Here’s an example of how you can prevent this error message from ever occurring:
Click here to view code image
CREATE PROCEDURE procOrderDetailAddHandleErrors
@SalesOrderID int = Null,
@CarrierTrackingNumber nvarchar(25) = Null,
@OrderQty smallint = 0,
@ProductID int = Null,
@SpecialOfferID int = Null,
@UnitPrice money = 0,
@UnitPriceDiscount money = 0
AS

IF @SalesOrderID Is Null
BEGIN
PRINT 'SalesOrderID Cannot be Null'
RETURN
END

IF @CarrierTrackingNumber Is Null
BEGIN
PRINT 'CarrierTrackingNumber Cannot be Null'
RETURN
END

IF @ProductID Is Null
BEGIN
PRINT 'ProductID Cannot be Null'
RETURN
END

IF @SpecialOfferID Is Null
BEGIN
PRINT 'SpecialOfferID Cannot be Null'
RETURN
END

INSERT INTO Sales.SalesOrderDetail


(SalesOrderID, CarrierTrackingNumber, OrderQty,
ProductID, UnitPrice, UnitPriceDiscount)
VALUES
(@SalesOrderID, @CarrierTrackingNumber, @OrderQty,
@ProductID, @UnitPrice, @UnitPriceDiscount)

In the example, several of the parameters are optional. The procedure begins by testing to see whether the
value of the @SalesOrderID is Null. If it is, a message is printed, and the RETURN statement exits
the procedure. This prevents the error message from ever occurring. The code repeats the process of
testing the value and printing a message for both the CarrierTrackingNumber and ProductID parameters.
Of course, you could add an output parameter that would report the problem back to the client application.
Returning Success and Failure Information from a Stored Procedure
As discussed in the previous section, it is important for the server to communicate to the client
application the success or failure information about what happened within the stored procedure. You can
select between two techniques to accomplish this task. The first method involves returning a recordset
with status information. Here’s an example:
Click here to view code image

CREATE PROCEDURE procOrderDetailAddHandleErrors2


@SalesOrderID int,
@CarrierTrackingNumber nvarchar(25),
@OrderQty smallint,
@ProductID int,
@UnitPrice money,
@UnitPriceDiscount money
AS
DECLARE @SalesOrderDetailID int,
@LocalError int,
@LocalRows int

INSERT INTO Sales.SalesOrderDetail


(SalesOrderID, CarrierTrackingNumber, OrderQty,
ProductID, UnitPrice, UnitPriceDiscount)
VALUES
(@SalesOrderID, @CarrierTrackingNumber, @OrderQty,
@ProductID, @UnitPrice,
@UnitPriceDiscount)

SELECT @SalesOrderDetailID = @@Identity,


@LocalError = @@Error, @LocalRows = @@RowCount
SELECT @SalesOrderDetailID, @LocalError, @LocalRows

The procedure first declares three variables: @SalesOrderID, @LocalError, and @LocalRows.
It then inserts an order into the SalesOrderDetail table. The statement immediately following the INSERT
statement populates the three variables with the identity value, error number (if any), and number of rows
affected.
In Figure 14.10, you can see that the @SalesOrderID parameter was not passed to the stored procedure.
Notice in the results that the identity value of the inserted row was NULL, the error number was 515, and
the number of rows affected was 0. This is because an error occurred and the row was never inserted.
FIGURE 14.10 The results of executing a stored procedure that returns error information.
The alternative to this technique is to use output parameters. Here’s an example:
Click here to view code image

CREATE PROCEDURE procOrderDetailAddHandleErrors3


@SalesOrderID int,
@CarrierTrackingNumber nvarchar(25),
@OrderQty smallint,
@ProductID int,
@UnitPrice money,
@UnitPriceDiscount money,
@SalesOrderDetailID int = 0 OUTPUT,
@LocalError int = 0 OUTPUT,
@LocalRows int = 0 OUTPUT
AS
INSERT INTO Sales.SalesOrderDetail
(SalesOrderID, CarrierTrackingNumber, OrderQty,
ProductID, UnitPrice, UnitPriceDiscount)
VALUES
(@SalesOrderID, @CarrierTrackingNumber, @OrderQty,
@ProductID, @UnitPrice, @UnitPriceDiscount)
SELECT @SalesOrderDetailID = @@Identity,
@LocalError = @@Error, @LocalRows = @@RowCount
SELECT @SalesOrderDetailID, @LocalError, @LocalRows
Notice that the procedure does not declare any variables. Instead, it contains three output parameters: one
for the SalesOrderDetailID, another for the error information, and the last for the number of rows
affected. The procedure populates the output parameters just as it populated the variables, with a
SELECT statement immediately following the INSERT statement.

Summary
You can use many techniques to make your stored procedures more powerful. In this lesson, you learned
many of them. You learned about the SET NOCOUNT statement and how to use the built-in @@ functions.
You also learned how to pass parameters to the stored procedures you build as well as how to return
values from your stored procedures. Finally, you learned how to add error handling to your stored
procedures.

Q&A
Q. Why would you use the SET NOCOUNT statement?
A. When it is set to ON, SET NOCOUNT eliminates the xx row(s) affected message in the
SQL Express Manager window and the DONE_IN_PROC communicated from SQL Server to the
client application. This improves the performance of the stored procedure.
Q. The @@ functions are actually variables (true/false).
A. False. You cannot assign values to them or work with them like normal variables. They are instead
functions that return information about SQL Server.
Q. Describe the parameters used when a stored procedure is used to insert data.
A. You generally have one input parameter for each field in the underlying table. It is also common to
have output parameters that return error and status information, as well as the identity value of the
row that the stored procedure inserted.

Workshop

Quiz
1. What does @@Identity do?
2. What keyword do you use to return a value from a stored procedure?
3. You use the ON ERROR GOTO statement to write error handling into the stored procedures that
you build (true/false).
4. What is the TSQL function you use to determine whether the caller has passed a parameter value to
a stored procedure?

Quiz Answers
1. Retrieves the new value inserted into an identity column.
2. The OUTPUT keyword.
3. False. The ON ERROR GOTO statement is not available in T-SQL stored procedures. You must
therefore handle errors as they occur.
4. The ISNULL keyword.
Activities
Build a stored procedure that inserts an order into the AdventureWorks Sales.SalesOrderDetail table.
Before you attempt to insert the row, write T-SQL to ensure that the SalesOrderID associated with the
order detail record is included in the Sales.SalesOrderHeader table. If the sales order associated with the
sales order detail is not included in the Sales.SalesOrderHeader table, return an error message to the
caller and exit the stored procedure. If the order does exist in the Sales. SalesOrderHeader table, add the
order. Return the Identity value of the new row to the caller using an output parameter.
Lesson 15. Power Stored Procedure Techniques

The previous lesson discussed several important stored procedure topics including how to take advantage
of @@ functions, parameters, and error handling. There are several additional techniques that are
extremely beneficial to know when working with stored procedures. In this lesson, you learn: How to
use stored procedures to modify data How to add transaction processing to your stored procedures

Modifying Data with Stored Procedures


Probably the most common use of a stored procedure is to modify the data in your database. You can
easily design stored procedures to insert, update, and delete data. The sections that follow cover stored
procedures that perform each of these tasks.

Inserting Data
Stored procedures are effective at inserting data into your databases. Stored procedures that insert data
generally contain several input parameters, one corresponding with each field in the underlying table.
They often contain output parameters containing status or error information. In fact, in the coverage of
error handling in Lesson 14, “Stored Procedure Techniques Every Developer Should Know,” you are
introduced to the process of inserting data into a table. Take a look at the following stored procedure:
Click here to view code image

CREATE PROCEDURE procOrderDetailAdd


@SalesOrderID int,
@CarrierTrackingNumber nvarchar(25),
@OrderQty smallint,
@ProductID int,
@SpecialOfferID int,
@UnitPrice money,
@UnitPriceDiscount money
AS
INSERT INTO Sales.SalesOrderDetail
(SalesOrderID, CarrierTrackingNumber, OrderQty,
ProductID, SpecialOfferID, UnitPrice, UnitPriceDiscount)
VALUES
(@SalesOrderID, @CarrierTrackingNumber, @OrderQty,
@ProductID, @SpecialOfferID, @UnitPrice, @UnitPriceDiscount) The procedure receives seven
input parameters, one for each field in the Sales.SalesOrderDetail table into which the
procedure inserts data. The INSERT INTO statement uses the input parameters as values to
insert into the table. As you can see, the previous example contains no output
parameters. The following procedure, which inserts data into the Sales.SalesOrderDetail
table, contains an output parameter called @SalesOrderDetailID: Click here to view code
image

CREATE PROCEDURE procOrderDetailAddOutput


@SalesOrderID int,
@CarrierTrackingNumber nvarchar(25),
@OrderQty smallint,
@ProductID int,
@SpecialOfferID int,
@UnitPrice money,
@UnitPriceDiscount money,
@SalesOrderDetailID int = 0 OUTPUT
AS
INSERT INTO Sales.SalesOrderDetail
(SalesOrderID, CarrierTrackingNumber, OrderQty,
ProductID, SpecialOfferID, UnitPrice, UnitPriceDiscount)
VALUES
(@SalesOrderID, @CarrierTrackingNumber, @OrderQty,
@ProductID, @SpecialOfferID, @UnitPrice, @UnitPriceDiscount)
SET @SalesOrderDetailID = @@IDENTITY

In addition to receiving six input parameters, this procedure uses the output parameter to house the
identity value of the inserted row. Notice that the code populates the @SalesOrderDetailID output
parameter with the value of the system function @@IDENTITY. The client application can use the output
parameter via ADO code you write.

Updating Data
Stored procedures are also excellent in their capability to update data. Here’s an example:
Click here to view code image
CREATE PROCEDURE procSalesOrderHeaderUpdate
@SalesOrderID int,
@NewFreight money
AS
UPDATE Sales.SalesOrderHeader
SET Freight = @NewFreight
WHERE SalesOrderID = @SalesOrderID

The procedure receives two input parameters. One is for the SalesOrderID of the order whose freight you
want to modify. The other parameter contains the new value for the freight. Notice that the UPDATE
statement sets the freight to the @NewFreight value where the SalesOrderID matches the customer
passed in as the @SalesOrderID parameter. Consider this more complex example: Click here to view
code image
CREATE PROCEDURE procSalesOrderDetailUpdate
@SalesOrderDetailID int,
@SalesOrderID int,
@CarrierTrackingNumber nvarchar(25),
@OrderQty smallint,
@ProductID int,
@SpecialOfferID int,
@UnitPrice money,
@UnitPriceDiscount money,
@ResultCode int = NULL Output,
@ResultMessage varchar(20) = NULL Output
AS
UPDATE Sales.SalesOrderDetail
SET SalesOrderID = @SalesOrderID,
CarrierTrackingNumber = @CarrierTrackingNumber,
OrderQty = @OrderQty,
ProductID = @ProductID,
SpecialOfferID = @SpecialOfferID,
UnitPrice = @UnitPrice,
UnitPriceDiscount = @UnitPriceDiscount
WHERE SalesOrderID = @SalesOrderID AND
SalesOrderDetailID = @SalesOrderDetailID

SET @ResultMessage =
Convert(varchar(20), @@RowCount) +
'Records Affected'
SET @ResultCode = 0

This example is more similar to the INSERT example. It receives one input parameter for each field in
the SalesOrderDetails table that you want to modify. It updates the fields in the SalesOrderDetails table
with the values of the input parameters for the customer with the SalesOrderDetailID designated in the
@SalesOrderDetailID parameter. It then sets the @ResultMessage output parameter to a string
containing the @@RowCount value. Finally, it sets the @ResultCode output parameter to zero. Figure
15.1 illustrates an example of successfully executing the procedure. Notice that the value of
@ResultCode is zero, indicating that no error occurred, and @ResultMessage indicates that one
record was affected.

FIGURE 15.1 A stored procedure that updates table data.

Deleting Data
Stored procedures are also very effective at deleting data. Here’s an example:
Click here to view code image
CREATE PROCEDURE procSalesOrderDetailDelete
@SalesOrderDetailID int
AS
DELETE FROM Sales.SalesOrderDetails
WHERE SalesOrderDetailID = @SalesOrderDetailID

This example receives one parameter: the SalesOrderDetailID of the sales order detail row you want to
delete. Notice that the DELETE statement contains a WHERE clause that references the
@SalesOrderDetailID input parameter.
Stored Procedures and Transactions
It is a good idea to place transactions in all the stored procedures you build. Transactions ensure that a
piece of work is completed in entirety or not at all. One of the classic examples is a banking transaction.
You want all the debits and credits to complete properly or not at all. This is where transactions come in.
When using a SQL Server backend, you should place all transaction processing inside your stored
procedures.

Types of Transactions
Two types of transactions exist: implicit transactions and explicit transactions. Implicit transactions
happen regardless of what you do in your programming code. Each time that you issue an INSERT,
UPDATE, or DELETE statement, SQL Server invokes an implicit transaction. If any piece of an INSERT,
UPDATE, or DELETE statement fails, the entire statement is rolled back. For example, if your DELETE
statement attempts to delete all the inactive customers, and somewhere in the process a record fails to
delete (for example, for referential integrity reasons), SQL Server does not delete any of the records.
Explicit transactions, on the other hand, are transactions you define and control. Using explicit
transactions, you package multiple statements within BEGIN TRANSACTION and COMMIT
TRANSACTION statements. In your error handling, you include a ROLLBACK TRANSACTION
statement. This ensures that all the statements complete successfully or not at all.

Implementing Transactions
As mentioned, you use the BEGIN TRANSACTION, COMMIT TRANSACTION, and ROLLBACK
TRANSACTION statements to implement transactions. The following is a stored procedure that utilizes a
transaction:
Click here to view code image
CREATE PROCEDURE procOrderDetailAddTransaction
@SalesOrderID int,
@CarrierTrackingNumber nvarchar(25),
@OrderQty smallint,
@ProductID int,
@SpecialOfferID int,
@UnitPrice money,
@UnitPriceDiscount money
AS
SET NOCOUNT ON
DECLARE @SalesOrderDetailID int, @LocalError int, @LocalRows int

BEGIN TRANSACTION

INSERT INTO Sales.SalesOrderDetail


(SalesOrderID, CarrierTrackingNumber, OrderQty,
ProductID, SpecialOfferID, UnitPrice, UnitPriceDiscount)
VALUES
(@SalesOrderID, @CarrierTrackingNumber, @OrderQty,
@ProductID, @SpecialOfferID, @UnitPrice, @UnitPriceDiscount)
SELECT @LocalError = @@Error, @LocalRows = @@RowCount

IF @LocalError <> 0 or @LocalRows = 0


BEGIN
ROLLBACK TRANSACTION
SELECT SalesOrderDetailID = Null,
Error = @LocalError,
NumRows = @LocalRows
END
ELSE
BEGIN
COMMIT TRANSACTION
SELECT @SalesOrderDetailID = @@Identity
SELECT SalesOrderDetailID = @SalesOrderDetailID,
Error = 0,
NumRows = @LocalRows
END

In the example, the BEGIN TRANSACTION starts the transaction. The procedure attempts to insert a
row into the Sales.SalesOrderDetail table. It populates the @LocalError variable with the value
returned from the @@Error function and the @LocalRows variable with the value returned from the
@@RowCount function. An IF statement evaluates whether either @LocalError is non-zero or
@LocalRows is zero. If either condition is true, the procedure was unsuccessful at inserting the row.
The ROLLBACK TRANSACTION statement is used to terminate the transaction, and the procedure
returns error information to the caller. If the error number equals zero, and the @LocalRows variable is
non-zero, you can assume that the process completed successfully. The COMMIT TRANSACTION
statement commits the changes, and the procedure returns the status and identity information to the caller
(see Figure 15.2).

FIGURE 15.2 A stored procedure that utilizes transactions and returns status information.
Summary
You can use many techniques to make your stored procedures more powerful. In this lesson, you learned a
few of them. You first learned how you can use stored procedures to modify data. Then you learned how
you can add transaction processing to the stored procedures you build.

Q&A
Q. What are three keywords that you can use to modify table data?
A. You can use INSERT, UPDATE, and DELETE to modify table data.
Q. What keywords do you use when working with transactions?
A. BEGIN TRANSACTION, COMMIT TRANSACTION, ROLLBACK TRANSACTION.
Q. Why would you use transactions?
A. You want a procedure to execute in entirety or not at all.

Workshop

Quiz
1. What keyword do you use to determine the identity value of the inserted row?
2. What keyword do you use to determine how many rows were inserted, updated, or deleted?
3. You use the EDIT keyword to modify table data (true/false).
4. What keyword do you use to limit the data you update or delete?
5. What keywords do you use to start a transaction?

Quiz Answers
1. @@Identity.
2. @@RowCount.
3. False. You use the UPDATE keyword to modify table data.
4. The WHERE keyword.
5. The BEGIN TRANSACTION keywords.

Activities
Build a stored procedure that updates the TaxRate field in the AdventureWorks Sales.SalesTaxRate table
for all rows where the TaxType field equals 1. Then build a stored procedure that deletes all rows from
Sales.SalesOrderDetail WHERE SalesOrderID = 43892. Finally, modify the first stored procedure so
that it contains transaction processing. If any errors occur or no rows are affected, the procedure should
return error information and roll back the transaction. If the procedure executes successfully, commit the
transaction.
Lesson 16. Stored Procedure Special Topics

You should be aware of some special topics when writing your stored procedures. In some cases,
understanding these topics can help you provide a more efficient solution to a problem. In other cases,
these topics address functionality available only with the techniques covered during this lesson. In this
lesson, you find out:
How to work with stored procedures and temporary tables
How to utilize cursors in the stored procedures you build
How stored procedures interact with the security of your database

Stored Procedures and Temporary Tables


SQL Server creates temporary tables in a special system database called TempDB. SQL Server creates
TempDB each time it starts and destroys it each time it shuts down. SQL Server uses TempDB to house
many temporary objects that it needs to run. You can use TempDB to share data between procedures or to
help you to accomplish complex tasks. You often will need to incorporate temporary tables into the stored
procedures that you write. Here’s an example of how you create and use a temporary table:
Click here to view code image
CREATE PROCEDURE procEmployeesGetTemp AS
BEGIN
CREATE TABLE #TempEmployees
(BusinessEntityID int NOT NULL PRIMARY KEY,
JobTitle varchar(50),
HireDate datetime,
VacationHours int)
INSERT INTO #TempEmployees
(BusinessEntityID, JobTitle, HireDate, VacationHours)
EXEC procEmployeesGetByJobTitleAndHireDate '1/1/2009', 'Production Technician – WC20'
SELECT BusinessEntityID, JobTitle, HireDate, VacationHours
FROM #TempEmployees
ORDER BY HireDate DESC
END

This procedure uses a second procedure called


procEmployeesGetByHireDateAndJobTitleAndHireDate. It looks like this:
Click here to view code image
CREATE PROCEDURE procEmployeesGetByJobTitleAndHireDate
@HireDate DateTime,
@JobTitle varchar(50)
AS
SELECT BusinessEntityID, JobTitle, HireDate, VacationHours
FROM HumanResources.Employee
WHERE HireDate >= @HireDate AND
JobTitle = @JobTitle
ORDER BY HireDate DESC

The procEmployeesGetByHireDateAndJobTitleAndHireDate procedure receives two


parameters. It uses those parameters for the WHERE clause for HireDate and JobTitle. The
procEmployeesGetTemp procedure creates a temporary table that holds customer information. It
inserts into the temporary table the results of executing the
procEmployeesGetByHireDateAndJobTitle procedure, passing it 1/1/2009 and Design
Engineer as the hire date and job title values. Finally, the procedure selects data from the temporary
table, ordering the result by HireDate in descending order. The results appear in Figure 16.1. Notice that
only employees with the title Production Technician – WC20 and a hire date on or after 1/1/2009 appear.

FIGURE 16.1 The stored procedure outputs data contained in a temporary table that is populated by
the results of executing a second stored procedure.

Stored Procedures and Cursors


A SQL Server SELECT statement outputs a complete result set. There are times when you will want to
process one row at a time, performing some operation on each row. Opening a cursor on a result set
allows you to process each row in the result set independently.
You use the DECLARE CURSOR statement to define a SQL Server cursor. The parameters to the
DECLARE CURSOR statement allow you to determine the behavior of the cursor. For example, you can
designate a cursor as read-only or as forward-only.
The OPEN statement populates the cursor with the data in the result set. FETCH returns a single row from
the result set. You use CLOSE to release the result set associated with the cursor and DEALLOCATE to
release all resources associated with the cursor. The following example illustrates the process of working
with a cursor:
Click here to view code image
CREATE PROCEDURE procEmployeesGetCursor
AS
BEGIN
DECLARE @BusinessEntityID int,
@HireDate datetime,
@JobTitle varchar(5)

DECLARE EmployeeCursor CURSOR FOR


SELECT BusinessEntityID, JobTitle, HireDate
FROM HumanResources.Employee
WHERE HireDate >= '1/1/2009'
ORDER BY HireDate DESC

OPEN EmployeeCursor

FETCH NEXT FROM EmployeeCursor INTO


@BusinessEntityID, @JobTitle, @HireDate

--As long as there are more rows to fetch


WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'BusinessEntityID: ' +
CONVERT(varchar(10), @BusinessEntityID) +
' – ' + UPPER(@JobTitle) +
' Hire Date = ' + CONVERT(varchar(10), @HireDate)
FETCH NEXT FROM EmployeeCursor
END

CLOSE EmployeeCursor
DEALLOCATE EmployeeCursor
END

The procedure procEmployeesGetCursor first declares variables used by the cursor. It then
retrieves data from the Employee table. After opening the EmployeeCursor cursor, it uses the FETCH
NEXT statement to retrieve the first row from the result set, placing its data into the three variables. The
@@FETCH_STATUS determines if there are more rows to fetch from the cursor. If there are, the code
prints data from the cursor. It then fetches the next row from the cursor. Finally, the code closes and
deallocates the cursor, freeing the resources associated with it. Figure 16.2 provides an example of
executing the stored procedure.
FIGURE 16.2 The stored procedure utilizes a cursor to loop through the Employee table, outputting
data from each row in the table.
The stored procedure used in the previous example provided a simple illustration of how you can use a
cursor to loop through records in a result set. The stored procedure that follows shows how you can use a
cursor to solve a real-life data problem. Specifically, it allows you to search for a specific string with any
text-type columns in a table. It looks like this:
Click here to view code image

CREATE PROCEDURE procGetString


@FindString varchar(8000)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @SQLCommand varchar(8000)
DECLARE @Where varchar(8000)
DECLARE @ColumnName sysname
DECLARE @Cursor varchar(8000)

SET @SQLCommand = 'SELECT * FROM Person.Address'


SET @Where = ''
SET @Cursor = 'DECLARE FindCursor CURSOR FOR SELECT COLUMN_NAME
FROM ' + DB_NAME() + '.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = ' + '"Person"' + ' AND
TABLE_NAME = ' + '"Address"' + ' AND
DATA_TYPE IN ("char", "nchar", "ntext",
"nvarchar", "text", "varchar")'

EXEC (@Cursor)

OPEN FindCursor
FETCH NEXT FROM FindCursor INTO @ColumnName

WHILE @@FETCH_STATUS = 0
BEGIN
IF @Where <> ''
BEGIN
SET @Where = @Where + ' OR '
END
SET @Where = @Where + ' [' + @ColumnName +
'] LIKE "'+ @FindString + '"
FETCH NEXT FROM FindCursor INTO @ColumnName
END

SET @SQLCommand = @SQLCommand + ' WHERE ' + @Where


EXEC (@SQLCommand)

CLOSE FindCursor
DEALLOCATE FindCursor
END

This procedure is designed to accept a string as a parameter. It then searches for that string in all text-type
columns within the Person.Address table. After declaring four variables, the procedure uses a SET
statement to assign the beginning of a SELECT statement to the @SQLCommand variable. The SET
statement is an alternative way (the other being SELECT) to assign a value to a variable.
Probably the most complex statement in the procedure is the SET statement that creates the DECLARE
CURSOR statement and assigns it to the @Cursor variable. This statement sets the @Cursor variable
equal to a string that declares a cursor that is responsible for looping through all the text-type columns
(char, nchar, ntext, nvarchar, text, and varchar) in the Person.Address table. The EXEC (@Cursor)
statement executes the contents of the @Cursor variable, thereby creating the FindCursor cursor.
As the code loops through the result set, it builds a WHERE clause containing all of the text-type fields and
the contents of the @FindString variable. Finally, it sets the @SQLCommand variable equal to the
SELECT clause concatenated with the WHERE clause. Figure 16.3 provides an example of the results of
executing the stored procedure passing the parameter %Wood%. Notice in the results that rows that contain
Wood in either the AddressLine1 field or the City field appear in the output.
FIGURE 16.3 The stored procedure utilizes a cursor to search for a string within any text-type field in
the Address table.

Stored Procedures and Security


Like views, stored procedures provide an excellent tool for securing your application’s data. You can
grant rights to a stored procedure without providing any rights to the underlying table(s). Consider the
following scenario. Imagine you create an unbound Access form where users can select various
customers. You then execute stored procedures to insert, update, and delete data. In this scenario, you can
grant users view rights to the Customers table. You do not need to grant them insert, update, or delete
rights to the table. Instead you grant them execute rights to the appropriate stored procedures. In this way,
you can allow your users to easily create queries and reports that use the Customer data (you granted them
view rights to the table). They can only insert, update, and delete data via the stored procedures that you
call from your application code.
Summary
There are some special topics you should be aware of when working with stored procedures. This lesson
began by talking about how you can use temporary tables to enhance the stored procedures that you build.
It then continued with a discussion of cursors where you saw two solid examples of how you can use
cursors to loop through and perform some operation on the result set of a SELECT statement. Finally, the
lesson discussed the implications of stored procedures on the security of your database and the data
contained within it.

Q&A
Q. Why would you create temporary tables?
A. You create temporary tables to share data between procedures or to help you to accomplish
complex tasks.
Q. What does a cursor do?
A. A cursor allows you to loop through a result set, performing some operation on each record
individually.
Q. What role do stored procedures take in allowing you to secure your table data?
A. Using stored procedures, you can grant rights to the stored procedure without granting any rights to
the underlying tables.

Workshop

Quiz
1. What database does SQL Server use for temporary tables?
2. With stored procedures, the user must have rights to the tables that are affected by the stored
procedure (true/false).
3. What keywords do you use to create a cursor?

Quiz Answers
1. TempDB.
2. False. They need rights to only the stored procedure.
3. DECLARE mycursor CURSOR FOR.

Activities
Build a stored procedure that creates a temporary table containing PurchaseOrderID, EmployeeID,
OrderDate, ShipDate, and Freight. Execute a second stored procedure that selects those fields from the
Purchasing.PurchaseOrderHeader table, ordering by EmployeeID and OrderDate. The first stored
procedure should pass the second stored procedure a parameter for the freight amount. The second stored
procedure receives the parameter for the freight amount. It selects all fields from the Orders table where
Freight is greater than the parameter value, ordering by EmployeeID and Freight. It returns the result into
the temporary table in the first stored procedure. Finally, have the first stored procedure display the
contents of the temporary table. For help, consult the example in the “Stored Procedures and Temporary
Tables” section of this lesson.
Lesson 17. Building and Working with User-Defined Functions

SQL Server user-defined functions add power and flexibility slightly different than that available with
views and stored procedures. SQL Server user-defined functions accept parameters, perform one or more
actions, and return a result. Three types of user-defined functions exist: scalar, inline table-valued, and
multi-statement table-valued. The sections that follow cover each of these types of user-defined functions
in detail. Used properly, SQL Server user-defined functions enhance your ability to create powerful
client/server applications. This lesson covers:
How to create and work with scalar functions
How to take advantage of inline table-valued functions
How to utilize multi-statement table-valued functions

Scalar Functions
Scalar functions return a single value of the type defined in the RETURNS clause. The body of the function
is between a BEGIN and END block. Scalar functions can return any data type except text, ntext, image,
cursor, or timestamp. Here’s an example of a scalar function:
Click here to view code image
CREATE FUNCTION dbo.FullName
(@FirstName nVarChar(10),
@LastName nVarChar(20))
RETURNS nVarChar(35)
BEGIN
RETURN (@LastName + ', ' + @FirstName)
END

This function receives two parameters: @FirstName and @LastName. It returns an nVarChar(35)
value. The return value is the combination of the @LastName and @FirstName input parameters
combined with a comma and a space. You could call the function like this:
Click here to view code image
SELECT FirstName, LastName, dbo.FullName(FirstName, LastName) as FullName
FROM Person.Person

The example displays the FirstName, LastName, and result of the FullName function (see Figure
17.1).
FIGURE 17.1 Scalar functions return a single value of the type defined in the RETURNS clause.
The next example of a scalar function is more complex. It calculates the total quantity for a specific
ProductID in the ProductInventory table. It looks like this:
Click here to view code image
CREATE FUNCTION ?.[GetTotalInventory](@ProductID int)
RETURNS int
AS
-- Returns the stock level for the product.
BEGIN
DECLARE @return int
SELECT @return = SUM(Quantity)
FROM Production.ProductInventory
WHERE ProductID = @ProductID
IF (@return IS NULL)
SET @return = 0
RETURN @return
END

The GetTotalInventory function receives an integer parameter called @ProductID and returns
an int. After declaring a variable called @return, it sums the contents of the Quantity field in the
Production.ProductInventory table where the ProductID equals the integer value passed as a parameter to
the function. It then returns the total quantity value for that ProductID. You call the function like this:
Click here to view code image
SELECT DISTINCT ProductID, ?.[GetTotalInventory](ProductID)
FROM Production.ProductInventory
WHERE ProductID BETWEEN 1 AND 4

This SELECT statement returns each unique combination of ProductIDs and return values from the
ProductInventory table for all the rows where the ProductID is between 1 and 4. Notice that each
ProductID found in the result is passed to the function. The results appear in Figure 17.2.

FIGURE 17.2 The results of executing the scalar function GetTotalInventory with the
DISTINCT keyword in the calling SQL statement.
The DISTINCT keyword prevents the contents of the ProductID field from repeating over and over again
for each row with a particular ProductID. Repeating the ProductID is not necessary because the
GetTotalInventory function sums the contents of the Quantity field for a given ProductID. If you omit the
DISTINCT keyword, the results are as they appear in Figure 17.3.
FIGURE 17.3 The results of executing the scalar function GetTotalInventory without the
DISTINCT keyword in the calling SQL statement.
The advantage of placing database functionality in a scalar function is that you write the logic once and
then you can call it from multiple SQL statements, views, and stored procedures. This is quite valuable if
you will use the functionality over and over again throughout your database.
The disadvantage of using scalar functions lie in the effect they have on the performance of the database.
If you call a scalar function in a SELECT clause or a WHERE clause of a SQL statement, the function
executes once for each row in the result set.
In conclusion, scalar functions can greatly simplify the use of complex expressions in your SQL
statements, views, and stored procedures. However, it is important that you evaluate the performance
implications they impose to ensure their benefits outweigh the costs.

Inline Table-Valued Functions


As their name implies, inline table-valued functions return a table. Inline table-valued functions have no
body. They simply return the result of a simple SELECT statement. Here’s an example:
Click here to view code image

CREATE FUNCTION dbo.EmpGetByTitle


(@Title nVarChar(30))
RETURNS Table
AS
RETURN SELECT FirstName, LastName,
JobTitle, VacationHours, HireDate
FROM vwEmployee WHERE JobTitle = @Title

This example receives a parameter called @Title. It returns a table containing selected fields from the
vwEmployee view where the ContactTitle equals the @Title parameter value. You would call the
function like this:
Click here to view code image

SELECT * FROM dbo.EmpGetByTitle('Design Engineer')

The example selects all fields from the table returned from the EmpGetByTitle function. Because the
example passes Design Engineer as a parameter, only the design engineers are included in the result
set (see Figure 17.4).

FIGURE 17.4 Inline table-valued functions return a table.


Multi-Statement Table-Valued Functions
Multi-statement table-valued functions are similar to inline table-valued functions. The main difference is
that like scalar functions, they have a body defined by a BEGIN...END block. Like inline table-valued
functions, they return a table. Here’s an example:
Click here to view code image

CREATE FUNCTION ?.[FindReports] (@EmpID INTEGER)


RETURNS @FindReports TABLE
(
EmployeeID int primary key NOT NULL,
FirstName nvarchar(255) NOT NULL,
LastName nvarchar(255) NOT NULL,
JobTitle nvarchar(50) NOT NULL,
RecursionLevel int NOT NULL
)
AS
BEGIN
WITH EMP_cte(EmployeeID, OrganizationNode, FirstName, LastName,
JobTitle, RecursionLevel) -- CTE name and columns
AS (
-- Get the initial list of Employees for Manager n
SELECT e.BusinessEntityID, e.OrganizationNode,
p.FirstName, p.LastName, e.JobTitle, 0
FROM HumanResources.Employee e
INNER JOIN Person.Person p
ON p.BusinessEntityID = e.BusinessEntityID
WHERE e.BusinessEntityID = @EmpID
UNION ALL
SELECT e.BusinessEntityID, e.OrganizationNode,
p.FirstName, p.LastName, e.JobTitle,
RecursionLevel + 1 -- Join recursive member to anchor
FROM HumanResources.Employee e
INNER JOIN EMP_cte
ON e.OrganizationNode.GetAncestor(1) =
EMP_cte.OrganizationNode
INNER JOIN Person.Person p
ON p.BusinessEntityID = e.BusinessEntityID
)
INSERT @FindReports
SELECT EmployeeID, FirstName, LastName, JobTitle, RecursionLevel
FROM EMP_cte
RETURN
END

This example is fairly complex. It uses a built-in function called GetAncestor to return a result set that
lists all the employees who report to a specific employee directly or indirectly. It is not necessary for you
to understand the intricacies of the TSQL within the function. What is important to understand is that after
building a recordset with a list of all employees that report to the employee whose EmployeeID is passed
as a parameter to the function, the function returns the results in a table. You call the function like this:
Click here to view code image
SELECT * FROM ?.[FindReports](2)

The results of calling the GetReports function appear in Figure 17.5. All employees who report to
EmployeeID 2 appear in the result set.
FIGURE 17.5 The results of using a multi-statement table-valued function to return all employees that
report to the specified employee.

Summary
This lesson introduced you to an alternative to stored procedures: user-defined functions. User-defined
functions are a close relative to stored procedures. They enable you to encapsulate complex functionality
into a reusable component. User-defined functions can return either a single value (scalar functions) or a
table (table-valued functions). Although scalar functions can help to simplify the SQL statements you
build, they can negatively impact performance. It is up to you to determine whether their benefits outweigh
their limitations. There are two types of table-valued functions. The first simply returns a table. The
second allows you to perform complex logic, which determines what data is returned in its result set.

Q&A
Q. What are the two main categories of user-defined functions?
A. Scalar functions and table-valued functions.
Q. Why can a scalar function cause performance problems?
A. The function executes for each record in the SELECT statement.
Q. What are the two types of table-valued functions?
A. Inline table-valued functions and multi-statement table-valued functions.

Workshop

Quiz
1. You can pass parameters to user-defined functions (true/false).
2. What type of function returns a single value?
3. What type of function allows you to perform multiple operations before returning a result set?
4. The statements in an inline table-valued function are between a BEGIN clause and an END clause
(true/false).

Quiz Answers
1. True.
2. Scalar functions return a single value.
3. Multi-statement table-valued functions allow you to perform multiple operations.
4. False. The statements between scalar functions and multi-statement table-valued functions are
between a BEGIN clause and an END clause.

Activities
Build a scalar function that combines the contents of the ProductNumber and Name fields from the
Production.Product table. Combine the fields by outputting the ProductNumber, a colon followed by a
space, and the Name (for example, BA-8327: Bearing Ball). The function should contain a parameter that
limits the output to those rows with a designated Color value.
Build an inline table-valued function that returns the ProductID, Name, ProductNumber, Color,
SafetyStockLevel, and ReorderPoint. Have the function use the same expression as just described to
concatenate the ProductNumber, a colon, a space, and the contents of the Name field. Include a parameter
that limits the output to those rows with a designated Color value.
Lesson 18. Creating and Working with Triggers

A trigger is specialized type of stored procedure, which functions like an event procedure and that runs
when data changes. You can create triggers that execute in response to inserts, updates, and deletes.
Developers use triggers to enforce business rules and even to perform tasks such as inserting data into an
audit log. This lesson explains:
How to create triggers
How to work with Insert, Update, and Delete triggers
What an Instead Of trigger is and why you’d want to use one
Downsides of triggers

Creating Triggers
Use the following steps to create or modify a trigger:
1. Click to expand the node for the table to which you want to add the trigger. The Triggers node
appears (see Figure 18.1).

FIGURE 18.1 The Triggers node shows you the existing triggers associated with a table.
2. Right-click the Triggers node and select New Trigger. A new query window appears, enabling you
to type the text for the trigger (see Figure 18.2).

FIGURE 18.2 The new query window allows you to type the T-SQL that comprises the trigger.
3. Type the T-SQL that comprises the trigger.
4. Execute the CREATE TRIGGER statement (see Figure 18.3). After refreshing the list of triggers, it
appears under the list of triggers associated with that table (see Figure 18.4).
FIGURE 18.3 You must execute the T-SQL to create the trigger.
FIGURE 18.4 Once created, a trigger appears under the list of triggers available for that table.
The syntax for a trigger is as follows:
Click here to view code image

CREATE TRIGGER TriggerName


On TableName
FOR [INSERT], [UPDATE], [DELETE]
AS
--Trigger Code

The trigger shown in Figure 18.4 prints the full name associated with the person who was added to the
table. Figure 18.5 shows the results of executing an INSERT INTO statement that inserts data into the
Person table.
FIGURE 18.5 The results of inserting a row into the Person table.

Creating an Insert Trigger


In the previous section, you saw a simple example of an insert trigger. Insert triggers are used to
determine what happens after a row is inserted into a table. Insert triggers are often used to validate data
being inserted or to insert information about the inserted row into an audit log.
The example we are going to explore inserts information into an audit log every time a row is inserted
into the Person table. To work with this example, you first need to create the audit log table. The TSQL
statement that follows creates this table:
CREATE TABLE tblAuditLog
(
BusinessEntityID int,
EmployeeName varchar(100),
AuditAction varchar(100),
AuditTimeStamp datetime
)

The insert trigger looks like this:


Click here to view code image
CREATE TRIGGER InsertPerson
ON Person.Person
FOR INSERT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @BusinessEntityID int
DECLARE @FullName varchar(100)
DECLARE @AuditAction varchar(100)
SELECT @BusinessEntityID = BusinessEntityID
FROM inserted
SELECT @FullName =
(SELECT FirstName + ' ' + MiddleName +
' ' + LastName
FROM inserted)
SELECT @AuditAction = 'Row Inserted'
INSERT INTO tblAuditLog
(BusinessEntityID, EmployeeName,
AuditAction, AuditTimeStamp)
VALUES
(@BusinessEntityID, @FullName,
@AuditAction, GetDate())
END

This trigger is a more sophisticated and utilitarian version of the trigger introduced in the first section of
the lesson. It first declares variables that will be populated with information about the inserted row. It
then establishes the values of those variables based on the data being inserted. Finally, it inserts the
contents of the variables, along with the current date and time, into the tblAuditLog table. Figure 18.6
shows the TSQL used to insert rows into the Person table. Figure 18.7 shows the resulting data added to
the audit log.
FIGURE 18.6 New rows inserted into the Person table.
FIGURE 18.7 Records added to tblAuditLog reflecting data inserted into the Person table.

Creating an Update Trigger


Whereas an Insert trigger executes when data is inserted into a table, an Update trigger executes any time
data in an existing row is modified. The following is an example of a trigger that inserts data into an audit
log whenever the user updates a row:
Click here to view code image
CREATE TRIGGER [Person].[UpdatePerson]
ON [Person].[Person]
FOR UPDATE
AS
BEGIN
SET NOCOUNT ON;

DECLARE @BusinessEntityID int


DECLARE @FullName varchar(100)
DECLARE @AuditAction varchar(500)

If UPDATE(FirstName)
BEGIN
SELECT @AuditAction = 'First Name Updated, '
END
If UPDATE(MiddleName)
BEGIN
SELECT @AuditAction = @AuditAction + 'Middle Name Updated, '
END

If UPDATE(LastName)
BEGIN
SELECT @AuditAction = @AuditAction + 'Last Name Updated, '
END

SET @AuditAction = LEFT(@AuditAction, LEN(@AuditAction) - 1)

INSERT INTO tblAuditLog


(BusinessEntityID, EmployeeName,
AuditAction, AuditTimeStamp)
SELECT i.BusinessEntityID,
i.FirstName + ' ' + i.MiddleName +
' ' + i.LastName,
@AuditAction,
GetDate()
FROM inserted i, deleted d
WHERE i.BusinessEntityID = d.BusinessEntityID

END

This example inserts data into an audit log whenever the user modifies data in the Person table. The
trigger uses the UPDATE function to determine which data was modified. While doing so, it builds a
string that indicates which fields were updated. Finally, the trigger inserts the BusinessEntityID, the full
name, the string containing the fields that were updated, and the current date into the tblAuditLog table.
Figure 18.8 shows the TSQL used to update rows in the Person table. Figure 18.9 shows the resulting data
added to the audit log.
FIGURE 18.8 UPDATE statements that invoke the UPDATE trigger.
FIGURE 18.9 Records added to tblAuditLog reflecting data updated in the Person table.

Creating a Delete Trigger


A Delete trigger executes in response to a record being deleted. The following is an example of a trigger
that inserts data into an audit log when a row is deleted:
Click here to view code image
CREATE TRIGGER [Person].[DeletePerson]
ON [Person].[Person]
AFTER DELETE
AS
BEGIN
DECLARE @BusinessEntityID int
DECLARE @FullName varchar(100)
DECLARE @AuditAction varchar(500)

SET @AuditAction = 'Record Deleted'

INSERT INTO tblAuditLog


(BusinessEntityID, EmployeeName,
AuditAction, AuditTimeStamp)
SELECT d.BusinessEntityID,
d.FirstName + ' ' + d.MiddleName +
' ' + d.LastName,
@AuditAction,
GetDate()
FROM deleted d

END

This example inserts data into an audit log when a record is deleted from a table. Notice that it inserts the
BusinessEntityID, employee first, middle, and last name, the contents of the AuditAction variable, and the
current date into the audit log. The resulting rows appear in Figure 18.10.

FIGURE 18.10 Records added to tblAuditLog reflecting data deleted from the Person table.
Another use of a Delete trigger is to abort a deletion when certain conditions are met. Here’s an example:
Click here to view code image

CREATE TRIGGER [Production].[NoDeleteActive]


ON [Production].[Product]
FOR DELETE
AS
BEGIN

SET NOCOUNT ON;


DECLARE @ErrorMessage varchar(100)
SELECT @ErrorMessage = 'Active Product Cannot be Deleted'

DECLARE @Discontinued datetime


SELECT @Discontinued =
(SELECT DiscontinuedDate FROM deleted)

IF @Discontinued IS NULL
BEGIN
ROLLBACK TRAN
RAISERROR (@ErrorMessage,
16, 1)
END
END

This trigger evaluates to see whether the product the user is attempting to delete is active
(DiscontinuedDate is null). If it is, SQL Server aborts the delete process and displays an error message.
Figure 18.11 illustrates the error message that occurs when an attempt is made to delete a record with no
value in the DiscontinuedDate.

FIGURE 18.11 Error message that occurs when a record without a value in the DiscontinuedDate field
is deleted.
Downsides of Triggers
Many developers avoid triggers entirely. Probably the biggest disadvantage of triggers is that although
they appear as a node under the table that they are associated with, they get buried in your database and
are difficult to debug and troubleshoot. Triggers also slow down database operations. Furthermore, they
often lock data for relatively long periods of time, increasing the chance of concurrency problems. For
these reasons, many developers opt to utilize stored procedures and functions to replace the role of
triggers in the applications that they build. In reality, triggers have their place. The examples shown in this
lesson provide practical uses of triggers.

Summary
Triggers are cousins of stored procedures. They are “special” stored procedures that execute
automatically in response to data being inserted, updated, or deleted. Although they do have their
limitations, triggers are an excellent tool to use when you want to insert data into an audit log when a
table’s data is in any way modified. You can also use triggers to control the insert, update, and delete
processes.

Q&A
Q. Explain what a trigger is.
A. A trigger is like an event procedure that runs when data changes. You create triggers that respond to
inserts, updates, and deletes.
Q. Explain why developers use triggers.
A. Developers use triggers to enforce business rules and even to perform tasks such as inserting data
into an audit log.
Q. Describe some disadvantages of triggers.
A. Triggers can be difficult to troubleshoot, can increase locking conflicts, and can degrade
performance when modifying data.

Workshop

Quiz
1. List three types of triggers.
2. You can use a trigger to cancel the deletion of a record (true/false).
3. You can use a trigger to increment and decrement a value such as an inventory balance when a
process modifies data (true/false).
4. Triggers only execute when the user of a database modifies its data (true/false).

Quiz Answers
1. Insert, Update, Delete.
2. True.
3. True.
4. False. One of the benefits of triggers is that they execute regardless of how the data is modified. In
other words, a trigger executes even as the result of a stored procedure modifying data.
Activities
Create three triggers on the Sales.SalesOrderDetail table. Have all three triggers (Insert, Update, and
Delete) add data to a table called tblSalesAuditLog. First create tblSalesAuditLog. Include
SalesOrderID, SalesOrderDetailID, CarrierTrackingNumber, OrderQty, ProductID, UnitPrice, and
LineTotal. When any process inserts data into the SaleOrderDetail table, add data from the appropriate
fields into the audit log. When any process updates data within the SalesOrderDetail table, add the
modified values (not the original values) into the tblSalesAuditLog table. Finally, when a process deletes
table data, insert the deleted data into the tblSalesAuditLog table.
Lesson 19. Authentication

Security is a critical aspect of a server database. It ensures that the data you enter into the database is
protected. This lesson covers: The basics of security
The types of authentication available
How to create logins
How to create roles

The Basics of Security


Security is necessary to prohibit access by unauthorized users and to ensure that authorized users have
only the rights you want them to have. SQL Server security is robust and offers you several alternatives
for your security model.
Let’s begin by contrasting SQL Server security to that of a desktop database such as Microsoft Access.
Access security is very limited and does not provide you with a lot of protection. You must grant read,
write, and delete permissions to the users of an Access database for the network share on which the
database resides. This makes the database vulnerable to hackers as well as the inadvertent actions of
users (for example, accidentally moving or deleting a file). Furthermore, user-level security is not
available in recent versions of Access. This means that you must “home-grow” Access security using
VBA code, and users must log on to both the operating system and Microsoft Access. Finally, operating
system features such as password aging, the logging of user activity, and the logging of invalid login
attempts are all unavailable with Microsoft Access.
On the other hand, SQL Server offers a robust and flexible security model. SQL Server security is tightly
integrated with Windows security. This means that SQL Server can utilize the users and roles you set up at
the operating system level. Within SQL Server, you determine the rights the users and roles have for the
various SQL Server objects. Not only are Windows users and roles available, but you can also take
advantage of operating system features such as password expiration and the logging of login attempts and
database activities.
The process of validating a user is known as authentication. The process of determining what a user can
do is called permissions validation. This lesson covers authentication. Lesson 20, “SQL Server
Permissions Validation,” covers permissions validation.

Types of Authentication
Authentication involves ensuring that a user is who he says he is. After SQL Server authenticates a user,
the user can perform any actions specifically granted to his login, as well as actions granted to any roles
of which the user is a member.
Two types of authentication exist:
SQL Server and Windows (Mixed authentication) Windows only
With SQL Server and Windows authentication, SQL Server supports both SQL Server and Windows
logins. With Windows-only authentication, SQL Server supports only Windows logins. When you install
SQL Server, you can configure the type of authentication that SQL Server uses. To modify the type of
authentication you want to use, follow these steps: 1. Launch SQL Server Management Studio.
2. Right-click the server whose authentication mode you want to modify and select Properties. The
Server Properties dialog box appears.
3. Click the Security node.
4. Modify the Server authentication, as shown in Figure 19.1.

FIGURE 19.1 The Security tab of the SQL Server Properties dialog box enables you to modify the
authentication type of the server.
Windows Only authentication has several advantages over SQL Server and Windows (Mixed)
authentication. These advantages include the following: Requirement for the user to log on only once
Central administration of logins
Enforceable minimum password length
Account lockout after unsuccessful login attempts More secure validation
Encryption of passwords
Auditing features
The main advantage of SQL Server and Windows (Mixed) authentication is that SQL Server and Windows
(Mixed) authentication enables you to support non-Windows users such as Novell users.
Creating Logins
If you select Windows authentication, SQL Server assumes a trust relationship with your Windows server.
It assumes that the user has already successfully logged in. Regardless of the authentication mode you
select, you must still create SQL Server logins.

Adding a Windows Login


To begin, we’re going to take a look at the process of creating a Windows login; the process is somewhat
different from creating a SQL login. Follow these steps to create a Windows login:
1. Click to expand the Security node for the server (see Figure 19.2).

FIGURE 19.2 To add a Windows login, click to expand the Security node for the server.
2. Right-click Logins and select New Login. The Login – New dialog box appears (see Figure 19.3).
FIGURE 19.3 The Login – New dialog box is where you to enter information about the new login.
3. Type the name for the login or click Search to locate the login.
4. If you click Search, the Select User or Group dialog box appears (see Figure 19.4). Make sure that
the object type and location are correct and then type the name of the user or group.

FIGURE 19.4 The Select User or Group dialog box enables you to search for a login.
5. Click Check Names to verify that the user or group exists.
6. Click OK to close the Select User or Group dialog box.
7. Make sure that Windows authentication is selected.
8. Specify the default database for the user (refer to Figure 19.3).
9. Click the Server Roles node to grant the user membership to server roles (see Figure 19.5).

FIGURE 19.5 You use the Server Roles node to grant the user membership to server roles.
10. Click the User Mapping node to designate to which databases the user has rights. The “Granting
Database Access to Logins” section of this lesson covers database access.
11. Click OK to close the dialog box and add the user.

Adding a SQL Server Login


When adding a SQL Server login, you are adding a login that does not exist anywhere else. The login is
independent of the operating system and its logins. Follow these steps to create a SQL Server login:
1. Click to expand the Security node for the server.
2. Right-click Logins and select New Login. The Login – New dialog box appears.
3. Type the name for the login.
4. Make sure you select SQL Server authentication.
5. Type a password for the user (see Figure 19.6). This case-sensitive password can contain from 1
through 128 characters, including letters, symbols, and digits.

FIGURE 19.6 When using SQL Server and Windows (Mixed) authentication, the SQL Server Login —
New dialog box prompts you to type a password for the user.
6. Confirm the password.
7. Specify the default database for the user.
8. Click the Server Roles node to grant the user membership to server roles.
9. Click the User Mapping node to designate to which databases the user has rights. The “Granting
Database Access to Logins” section of this lesson covers database access.
10. Click OK to close the dialog box.

Granting Database Access to Logins


Whether you use Windows Only authentication or SQL Server authentication, you need to determine to
which databases the user has rights and to which fixed database and user-defined database roles the user
belongs. You can grant database access for a login when adding the login (see previous text). To grant
database access for an existing login, follow these steps:
1. Click to expand the Security node for the server.
2. Click Logins. The available logins appear. Right-click the login you want to affect and select
Properties. The Login Properties dialog box appears.
3. Click to select the User Mapping node. The dialog box appears, as shown in Figure 19.7.

FIGURE 19.7 The User Mapping tab of the SQL Server Login Properties dialog box enables you to
designate the databases to which you want the user to have access.
4. Click the Map check box next to each database to which you want the user to have access.
5. Click the check box next to each database role (system- and user-defined) to which you want the
user to belong.
6. Click OK to commit your changes.

Understanding the SA Login


The SA Login is a special login within the SQL Server environment. If you install SQL Server in mixed
mode (Windows and SQL Server authentication), the SA login has unlimited powers. With mixed-mode
authentication, there is no way to modify or delete the SA account. It is therefore imperative you assign a
password to the SA account. Failure to do so renders any other security you apply to the server futile.
Creating Roles
Roles are the equivalent of Windows groups. You create roles and then grant users membership to those
roles. Users who are members of a role inherit the permissions assigned to that role. The process of
creating roles and assigning permissions to those roles greatly facilitates the process of administering
security. Rather than having to assign specific rights to each user of a system, you can instead assign rights
to groups of users.

Types of Roles
SQL Server offers four types of roles:
Fixed server roles
Fixed database roles
User-defined database roles
Application roles
Each of these types of roles serves a specific purpose. Generally you will use several types of roles in
combination. The sections that appear later in the lesson discuss each type of role in detail.

Fixed Server Roles


Fixed server roles are built into SQL Server and are in no way user-definable (you cannot add them,
modify them, or delete them). They enable their members to perform server-level administrative tasks.
The fixed server roles are the following:
Bulk Insert Administrators (bulkadmin)—Can execute bulk insert statements.
Database Creators (dbcreator)—Can create and alter databases.
Disk Administrators (diskadmin)—Can manage disk files.
Process Administrators (processadmin)—Can manage SQL Server processes.
Security Administrators (securityadmin)—Can manage server logins.
Server Administrators (serveradmin)—Can configure server-wide settings.
Setup Administrators (setupadmin)—Can install replication and can manage extended properties.
System Administrators (sysadmin)—Can perform any activity on that SQL Server instance. This
includes all activities of the other roles. In fact, if a user is a member of the sysadmin role, you
cannot prohibit him from performing any tasks on the server.
Server roles greatly facilitate the process of managing security. They accomplish this by allowing you to
compartmentalize the administrative tasks that users can perform and to grant them rights to perform only
those specific tasks.

Note
When you install SQL Server, the installation process adds the Windows Administrators
group to the sysadmin role. This means that all members of the Administrators group
instantly become members of sysadmin. Fortunately, you can remove this mapping from
Administrators to the sysadmin role. To remove the mapping, you must deny the
Administrators group from logging on to the SQL Server. You then grant the individual users
membership to the sysadmin role.
To assign a user to a fixed server role, follow these steps:
1. Expand the Security node until you can see the Server Roles subnode (see Figure 19.8).

FIGURE 19.8 The Server Roles subnode of the Security node enables you to assign users to a fixed
server role.
2. Right-click the role to which you want to grant users membership and select Properties. The Server
Role Properties dialog box opens (see Figure 19.9).
FIGURE 19.9 The Server Role Properties dialog box enables you to add users to a role.
3. Click Add to add a user to the role. The Select Server Login or Role dialog box appears (see
Figure 19.10).
FIGURE 19.10 The Select Server Login or Role dialog box is where you add logins to a role.
4. Click Browse to select the logins you want to add. The Browse for Objects dialog box opens (see
Figure 19.11).

FIGURE 19.11 The Browse for Objects dialog box enables you to select the users you want to add to
a role.
5. Click to check the objects you want to add to the role.
6. Click to close the Browse for Objects dialog box.
7. Click OK. SQL Server adds the selected users to the role.
Fixed Database Roles
Whereas fixed server roles enable you to assign rights to users that apply at the server level, fixed
database roles enable you to assign rights at the database level. Because fixed server roles apply at the
server level, they are found under the Security node. Because fixed database roles apply at a database
level, they are located under the specific database node of the database to which they apply.
As with fixed server roles, you cannot add, remove, or modify the rights granted to fixed database roles.
Fixed database roles facilitate the process of assigning permissions for a database. The fixed database
roles are as follows: db_accessadmin—Can add and remove Windows users and groups and SQL
Server users for the database.
db_backupoperator—Can back up the database.
db_datareader—Can view data in all user tables in the database.
db_datawriter—Can add, edit, and delete data in all user tables in the database.
db_ddladmin—Can add, modify, and drop database objects.
db_denydatareader—Cannot see any data in the database.
db_denydatawriter—Cannot modify any data in the database.
db_owner—Can perform the activities of any of the other roles. Can also perform all database
maintenance and configuration tasks.
db_securityadmin—Can manage role membership and statement and object permissions for the
database.
To assign a user to a fixed database role, perform these steps:
1. Expand the Database node of the desired database until you can see the Security subnode.
2. Click to expand the Roles node for the database.
3. Click to expand the list of Database Roles (see Figure 19.12).
FIGURE 19.12 The Database Roles subnode enables you to work with roles for that database.
4. Right-click the role to which you want to grant users membership and select Properties. The
Database Role Properties dialog box appears (see Figure 19.13).
FIGURE 19.13 The Database Role Properties dialog box enables you to add users to a database role.
5. Click Add to add a user to the role. The Select Database User or Role dialog box appears (see
Figure 19.14).

FIGURE 19.14 The Select Database User or Role dialog box enables you to add users to a role.
6. Click Browse. The Browse for Objects dialog box appears (see Figure 19.15).

FIGURE 19.15 The Browse for Objects dialog box enables you to select the users you want to add to
a role.
7. Click to select the logins you want to add and click OK. Click OK to close the Select Database
User or Role dialog box. SQL Server adds the selected users to the role.
The Public role is a special built-in fixed database role. Every user is a member of it. When you grant a
user access to a database, SQL Server adds the user to the Public database role. You can’t remove the
Public role, nor can you remove users of a database from the Public role. Any rights that you grant to the
Public role are automatically granted to all users of the database. The Public role therefore provides an
excellent means of easily granting all users rights to a particular object. On the other hand, if you
accidentally grant the Public role rights, those rights apply to all users of the database.

User-Defined Database Roles


At a database level, you are not limited to the predefined roles. In addition to the predefined roles, you
can add your own roles. SQL Server offers two types of user-defined roles. They are the following:
Standard role—Custom role that you use to facilitate the task of assigning rights to users of the
database.
Application role—Role used by an application.
To create a user-defined role, follow these steps:
1. Expand the Database node of the desired database until you can see the Roles subnode (see Figure
19.16).
FIGURE 19.16 The Roles subnode of the Database node enables you to create and work with user-
defined database roles.
2. Right-click the Roles subnode, select New, and then select New Database Role. The Database
Role – New dialog box appears, prompting you to enter the name of the new role (see Figure
19.17).
FIGURE 19.17 The Database Role — New dialog box enables you to enter the name of the new role.
3. Type the name of the role in the Role name text box.
4. Designate the schemas owned by the role.
5. Click Add to add a user to the role. The Select Database User or Role dialog box appears.
6. Select the logins you want to add (clicking Browse if necessary) and click OK. SQL Server adds
the selected users to the role and the role to the database.

Ownership
It is important to understand what ownership is and what the implications of ownership are. SQL Server
designates the creator of an object as its owner. The owner of an object has full permissions for that
object. Furthermore, the name of the object is actually owner.objectname—for example,
alexis.tblCustomers.
You cannot remove a user from a database as long as he owns objects within it. Ownership of an object is
implied. This means you cannot directly administer an object’s owner.
dbo is a special user account within each database. SQL Server maps the dbo to the sysadmin fixed server
role. This means that if you are a member of the sysadmin group and you create an object, SQL Server
flags the object as owned by dbo, not by you. You can refer to the object as dbo.objectname.
The sp_changeobjectowner system-stored procedure enables you to change an object’s owner.
Only members of the sysadmin fixed server role, the db_owner fixed database role, or a member of both
the db_ddladmin and db_securityadmin fixed database roles can execute the
sp_changeobjectowner stored procedure. It looks like this: Click here to view code image
EXEC sp_changeobjectowner 'tblCustomers', 'Brendan'

When you change an object’s owner, SQL Server drops all permissions for the object. To change the
owner back to dbo, you must fully qualify the owner name and object name. The syntax looks like this:
Click here to view code image
EXEC sp_changeobjectowner 'Brendan.tblCustomers', 'dbo'

Summary
You can create the best application and database in the world, but if it is not properly secured, someone
can easily sabotage it. This lesson explained the basics of security. You read about the types of
authentication available and about logins and roles. Lesson 20, “SQL Server Permissions Validation,”
covers security in additional detail.

Q&A
Q. Explain the difference between Windows Only authentication and SQL Server and Windows
(Mixed) authentication.
A. With Windows authentication, the user does not need to log on to the server more than one time.
Users you add to the SQL Server then gain the specified access to the server. With Windows
authentication, you also get all the benefits of the operating system login process. For example, you
can enforce minimum password length.
With SQL Server and Windows (Mixed) Authentication you can use SQL Server logins. You do not
have to have organized Windows domains, and finally, SQL Server and Windows (Mixed)
authentication enables you to support non-Windows users such as Novell users.
Q. Explain the SA Login and what it can do.
A. The SA Login is available only with Mixed Authentication and has unlimited powers! There is no
way to modify or delete the SA account. It is therefore imperative that you assign a password to the
SA account. Otherwise, any other security measures you take will be futile.
Q. Explain the interaction between sysadmin and the Windows Administrators group.
A. All members of the Windows Administrators group are added automatically to the sysadmin role
upon installation of SQL Server. Remember that sysadmin is all-powerful in working with your
server. Fortunately, you can remove this mapping. You must first deny the Administrators group
from logging on to the SQL Server. You then grant the individual users membership to the sysadmin
role as required.

Workshop

Quiz
1. Name four types of roles.
2. The SA user is available with both SQL Server and Windows authentication (true/false).
3. Name some benefits of Windows authentication.
4. If a login exists in Windows and you want them to be able to access the SQL Server, you don’t have
to do anything special (true/false).
5. You find fixed database roles under the database node of the database with which they are
associated (true/false).
6. What user is automatically the owner of an object?
7. Name the stored procedure that enables you to change an object’s ownership.

Quiz Answers
1. Server, Database, User-Defined, Application.
2. False. Only with Mixed authentication.
3. Single login, password expiration, central administration, more secure validation, password
encryption, account lockout after a certain number of attempts.
4. False. You still have to create them as a user in SQL Server.
5. True.
6. The user that creates the object.
7. sp_changeobjectowner.

Activities
Set up a server with Windows-Only authentication. Add three new logins. Grant each login access to the
AdventureWorks database. Assign one user to the Process Administrator fixed server role. Assign another
user to the db_datareader role of AdventureWorks. Create a user-defined role as part of the
AdventureWorks database. Assign all three logins to that role.
Lesson 20. SQL Server Permissions Validation

Lesson 19, “Authentication,” discussed SQL Server authentication, which is the process of ensuring that
only valid users work with your database. After users gain access to a database, it is important that they
have specific rights to objects within the database. This lesson covers: The types of permissions
available
How to work with table permissions
How to work with view permissions
How to work with stored procedure permissions How to work with function permissions
How to implement column-level security

Types of Permissions
When a user logs in to the server, SQL Server first authenticates him to ensure that he is a valid user. SQL
Server then grants the user permission to perform any task assigned to the user or to any roles of which the
user is a member.
SQL Server offers three types of permissions:
Object permissions—Permissions set for objects such as tables and views. These include
SELECT, INSERT, UPDATE, and DELETE permissions.
Statement permissions—Permissions applied to statements such as the CREATE VIEW statement.
These permissions define what rights the user has to the specified statement.
Inherited or implied permissions—These permissions refer to rights that a user has to an object
because he is a member of a role that has rights to that object or because the user is the owner of the
object.

Adding Database Users


If you want a user to have access to a database, you must first create a user account in the database by
following these steps:
1. Expand the Database node of the desired database until you can see the Users subnode (see Figure
20.1).
FIGURE 20.1 The Users subnode enables you to manage a database’s users.
2. Right-click the Users subnode and select New User. The Database User – New dialog box opens,
prompting you to enter the login name of the new user (see Figure 20.2).
FIGURE 20.2 The Database User – New dialog box prompts you to enter the new user’s login name.
3. Type the login name or click the ellipsis. If you click the ellipsis, the Select Login dialog box
appears (see Figure 20.3). Here you can type login names or click Browse. If you click Browse, the
Browse for Objects dialog box appears (see Figure 20.4).

FIGURE 20.3 The Select Login dialog box enables you to type login names.
FIGURE 20.4 The Browse for Objects dialog box enables you to select database users you want to
add.
4. Click to select the database users you want to add.
5. Click OK to close the dialog box.
6. Click OK to close the Select Login dialog box.
7. Click OK to close the Database User dialog box and add the user(s).

Working with Permission Statements


You can execute three different permission statements for the objects in your database:
GRANT—Grants permission.
WITH GRANT—Revokes permission. If you revoke permission for a user to an object, the user
still possesses any permissions implied by the roles of which the user is a member.
DENY—Revokes permission so that permission for that object cannot be inherited.

Administering Object Permissions


You can administer permissions for an object in one of two ways. The first way is via the object. This
method shows you the rights for all users and roles for a particular object. It works like this:
1. Right-click the object and select Properties. The Table Properties dialog box opens.
2. Click to select the Permissions page. The rights established for the selected object appear (see
Figure 20.5). Here you can assign users and roles rights for the object.
FIGURE 20.5 The Permissions page enables you to assign users and roles rights for the object.
3. Click Search to begin the process. The Select Users or Roles dialog box appears (see Figure 20.6).

FIGURE 20.6 The Select Users or Roles dialog box enables you to enter users or roles to which you
want to designate permissions.
4. Enter user and role names or click Browse to select the users and roles to which you want to grant
rights (see Figure 20.7).

FIGURE 20.7 The Browse for Objects dialog box enables you to select the users and roles for which
you are setting rights.
5. Click OK to close the Browse for Objects dialog box.
6. Click OK to close the Select Users or Roles dialog box. The Permissions page of the Table
Properties dialog box should look like what’s shown in Figure 20.8.
FIGURE 20.8 The Permissions page after selecting the users and roles to which you want to assign
rights.
7. Select a user or role in the list of users and roles.
8. For each type of permission, designate whether you want to Grant, With Grant, or Deny
permissions to the user or role, for that object. For example, in Figure 20.9, the user named AlisonJ
has been granted Insert rights to the HumanResources. Department table but has been denied Delete
rights.
FIGURE 20.9 The Permissions page enables you to assign users and roles rights for the object.
9. After granting all desired rights to all users and roles, click OK to close the Table Properties
dialog box. SQL Server applies the designated rights.
As an alternative, you can assign rights for all objects to a database user or role. Follow these steps:
1. Right-click the user or role and select Properties. The Database User dialog box appears.
2. Click to select the Securables page (see Figure 20.10). Here you can see a particular user or role
and manage rights to all objects for the user or role.
FIGURE 20.10 The Securables page enables you to select a user or role and then manage rights for its
objects.
3. Click Search to add the objects you want to secure. The Add Objects dialog box appears (see
Figure 20.11).

FIGURE 20.11 The Add Objects dialog box enables you to designate the types of objects you want to
secure.
4. Indicate whether you want to secure specific objects, all objects of specific types (for example,
tables), or all objects belonging to the schema. Make your selection and click OK.
5. If you click Specific Objects and click OK, the Select Objects dialog box opens (see Figure 20.12).

FIGURE 20.12 The Select Objects dialog box initiates the process of allowing you to select the types
of objects you want to secure.
6. Click Object Types. The Select Object Types dialog box opens (see Figure 20.13).

FIGURE 20.13 The Select Object Types dialog box enables you to select the types of objects you
want to secure for that user or role.
7. Click to select the types of objects you want to secure for that user. Click OK.
8. Click OK to return to the Select Objects dialog box.
9. Click Browse to locate the object names you want to secure. The Browse for Objects dialog box
opens, showing only the selected types of objects (see Figure 20.14).
FIGURE 20.14 The Browse for Objects dialog box shows you the selected types of objects.
10. Select the objects you want to secure and click OK. The Select Objects dialog box now looks like
in Figure 20.15.

FIGURE 20.15 The Select Objects dialog box appears with the types of objects you want to secure.
11. Click OK to close the Select Objects dialog box. The Securables page of the Database User dialog
box looks like in Figure 20.16. You are ready to assign rights to the selected objects.
FIGURE 20.16 The Securables page of the Database User dialog box appears with all the objects you
want to secure.

Note
If you select all objects of the types in Step 4, the Select Object Types dialog box opens.
Here you select the types of objects you want to find. You are then ready to assign rights to
the selected objects.

Getting to Know Table Permissions


You can grant ALTER, CONTROL, DELETE, INSERT, REFERENCES, SELECT, TAKE OWNERSHIP,
UPDATE, and VIEW DEFINITION rights for a table. These are each described as follows:
ALTER permissions—Allow the user to alter all properties of a table except ownership. Include
the capability to create, alter, and drop tables.
CONTROL permissions—CONTROL permissions confer ownership-like capabilities for an object.
The user can administer the object (assign rights, and so on) and has permissions for all objects
within it. For example, users who have CONTROL permissions to a database can fully manage that
database.
DELETE permissions—Allow the user to delete table data.
INSERT permissions—Allow the user to add data to the table.
REFERENCES permissions—Allow the user to create a foreign key constraint.
SELECT permissions—Allow the user to view the data in a table.
TAKE OWNERSHIP permissions—Allow the user to take ownership of the table on which it is
granted.
UPDATE permissions—Allow the user to update the data in the table.
VIEW DEFINITION permissions—Allow the user to access metadata for the table.
To assign permissions for a table, follow these steps:
1. Right-click the table for which you want to assign permissions and select Properties. The Table
Properties dialog box opens.
2. Click the Permissions page. The Table Properties dialog box appears as in Figure 20.17.

FIGURE 20.17 The Permissions page of the Table Properties dialog box before the users and roles to
which you are assigning rights have been designated.
3. Click Search to view the users and roles to which you want to assign rights for that table. The
Select Users or Roles dialog box opens.
4. Click Browse. The Browse for Objects dialog box opens.
5. Click to select the users and roles you want to affect.
6. Click OK. SQL Server returns you to the Select Users or Roles dialog box.
7. Click OK to close the Select Users or Roles dialog box and return to the Table Properties dialog
box. It should now look like Figure 20.18.

FIGURE 20.18 The Permissions page of the Table Properties dialog box after the users and roles to
which you are assigning rights have been designated.
8. Click to Grant, With Grant, or Deny ALTER, CONTROL, DELETE, INSERT, REFERENCES,
SELECT, TAKE OWNERSHIP, UPDATE, and VIEW DEFINITION rights as required.
9. Click OK when done. SQL Server applies the designated permissions.

Note
EXEC permissions are not applicable to a table. They are applicable only for stored
procedures and are therefore covered in the “Getting to Know Stored Procedure
Permissions” section of this lesson.
Getting to Know View Permissions
Permissions for a view override those for the underlying tables. Using views, you can easily apply both
row-level and column-level security. You can achieve column-level security by limiting the columns
included in the view. You can implement row-level security by adding a WHERE clause to the view.
Because the results of most views are updateable, the process of applying security for a view is similar to
that for a table. Follow these steps:
1. Right-click the view for which you want to assign permissions and select Properties. The View
Properties dialog box opens.
2. Click the Permissions page of the View Properties dialog. The View Properties dialog box should
look like Figure 20.19.

FIGURE 20.19 The View Properties dialog box enables you to assign ALTER, CONTROL, DELETE,
INSERT, REFERENCES, SELECT, TAKE OWNERSHIP, UPDATE, and VIEW DEFINITION
permissions for a View as required.
3. Click Search to add the users and roles who will gain rights to the view. The Select Users or Roles
dialog box opens.
4. Click Browse to designate the users and roles to which you want to assign rights. The Browse for
Objects dialog box opens.
5. Select the users and roles to which you want to assign rights for the view.
6. Click OK to close the Browse for Objects dialog box.
7. Click OK to close the Select Users or Roles dialog box. The Permissions tab of the View
Properties dialog box appears as shown in Figure 20.20.

FIGURE 20.20 The View Properties dialog box after giving a user rights to the vwEmployee view.
8. Click the check boxes to assign ALTER, CONTROL, DELETE, INSERT, REFERENCES,
SELECT, TAKE OWNERSHIP, UPDATE, and VIEW DEFINITION rights as required.
9. Click OK when finished.

Getting to Know Stored Procedure Permissions


As with rights for a view, rights assigned for a stored procedure override rights assigned for the
underlying tables and views. This is the case as long as the stored procedure has the same owner as the
tables referenced with it. Stored procedures have only five permissions: ALTER, CONTROL, EXECUTE,
TAKE OWNERSHIP, and VIEW DEFINITION. The most commonly assigned right, the EXECUTE
right, determines whether the user or role can execute the stored procedure.
Getting to Know Function Permissions
As with rights assigned for views and stored procedures, rights assigned for a user-defined function that
returns a table override rights assigned for the underlying tables and views. This is the case as long as the
function has the same owner as the tables referenced with it. Functions have the same permissions as
tables. The main limitation of functions is that they return read-only results.

Implementing Column-Level Security


SQL Server enables you to assign column-level permissions easily for tables and views. Column-level
permissions enable you to determine on a column-by-column basis whether the user has SELECT and
UPDATE rights for that particular column. INSERT and DELETE rights cannot be assigned at a column
level because they affect the entire row. To assign column-level permissions for tables and views, follow
these steps:
1. Right-click the table for which you want to assign permissions and select Properties. The Table
Properties dialog box opens.
2. Click the Permissions page to select it. You see the Permissions page of the dialog box.
3. Click Search to add the users and roles to which you want to apply column-level permissions. The
Select Users or Roles dialog box opens.
4. Click Browse to designate the users and roles to which you want to apply column-level
permissions.
5. Click to select your choices.
6. Click OK to close the dialog box.
7. Click OK to close the Select Users or Roles dialog box.
8. Click to grant SELECT or UPDATE rights to the selected user or role for that table or view. The
Column Permissions command button becomes enabled (see Figure 20.21).
FIGURE 20.21 The Column Permissions command button becomes enabled after you grant SELECT
or UPDATE rights to the selected user or role.
9. Click the Column Permissions button. The Column Permissions dialog box opens (see Figure
20.22). Indicate the SELECT or UPDATE rights for the individual columns as desired.
FIGURE 20.22 The Column Permissions dialog box lets you determine on a column-by-column basis
whether the user has SELECT and UPDATE rights for that particular column.
10. Click OK to close the Column Permissions dialog box and return to the Table Properties dialog
box.
11. Click OK to apply the permissions.

Summary
After a user gains access to a database, you must then determine what rights the user has to objects within
the database. This lesson explained permissions validation, the process of determining what a user can do
after gaining access to the database. You were shown how to designate permissions for the various types
of objects in the database, and you were introduced to the types of permissions available. Finally, you
walked through how to apply table and view security at a column-level.

Q&A
Q. Explain inherited permissions.
A. Inherited permissions refer to rights that a user has to an object because he is a member of a role
that has rights to that object or because he is the owner of the object.
Q. Explain the difference between WITH GRANT and DENY permissions.
A. WITH GRANT permissions revoke permission for an object unless that user is a member of a role
that has rights to that object. DENY permissions revoke permission so that permission for an object
cannot be inherited.
Q. Describe CONTROL permissions.
A. With CONTROL permissions, the user or role has ownership-like capabilities for the object. The
user can administer the object and has permission to all objects within it.
Workshop

Quiz
1. Name three types of permissions.
2. Name the permission statement that gives a user rights to an object.
3. Describe VIEW DEFINITION permissions.
4. Permissions for a view override those for the underlying table (true/false).
5. How can you implement row-level security with a view?
6. The results of views are not updateable (true/false).
7. What is the most commonly assigned right for a stored procedure?

Quiz Answers
1. Object, Statement, and Inherited or Implied.
2. GRANT.
3. VIEW DEFINITION permissions allow the user to access metadata for the table.
4. True.
5. By using a WHERE clause.
6. False. The results of most views are updateable.
7. EXECUTE.

Activities
Add three roles to the AdventureWorks database. Name one staff, another managers, and another system
administrators. Apply permissions for the HumanResources.Department table in the AdventureWorks
database. Give staff SELECT and INSERT rights to the table. Give management SELECT, INSERT,
UPDATE, and DELETE rights to the table. Give system administrators CONTROL permissions for the
table. Add three users, assigning each user to one of the three roles. Practice logging in as each user and
note what you can do within the HumanResources.Department table.
Lesson 21. Configuring, Maintaining, and Tuning SQL Server

The most attractive application can be extremely frustrating to use if its performance is less than
acceptable. As a developer, you must take precautions to try to assure that the SQL Server is as lean and
efficient as possible. This lesson explains:
How to select and tune your hardware
How to configure and tune SQL Server
How to maintain your databases
How to maintain your tables and other objects

Selecting and Tuning Hardware


Your choice of hardware can greatly affect the performance of your server. Areas of particular concern
are the amount of memory, processor speed, and hard disk configuration. The network architecture is also
an important factor. The sections that follow cover the details of each of these items.

Memory—The More RAM, the Better!


SQL Server uses memory (RAM) to hold all data pages, index pages, and log records. It also uses
memory to hold compiled queries and stored procedures. Needless to say, that memory is vital to the
performance of the server.
Clients are always asking me how much memory they should purchase for their server. My answer is, the
more, the better. In fact, RAM is the best investment you can make for your SQL Server. That aside, here
are some guidelines. A bare minimum amount of RAM for SQL Server Express is 512MB. Although all
other editions require 1GB of RAM, at least 4GB is recommended. SQL Server 2014 Express can take
advantage of 1GB. SQL Server 2014 Standard can utilize 128GB. Finally, SQL Server 2014 Enterprise
can utilize the operating system maximum!

Processor
Although it’s not as important as RAM, more processing power never hurts. SQL Server 2014 Express
can take advantage of one processor. SQL Server 2014 standard can take advantage of up to four
processors, and SQL Server 2014 Enterprise can take advantage of the operating system maximum.
Despite the advantages of multiple processors, if limited funds force a choice between more RAM and
multiple processors, more RAM is the most cost-effective choice.

Storage
Because SQL Server stores all of your data on disk, the type, configuration, and throughput of the storage
media you use are important factors. Today, there are three common interfaces for disk storage: Serial AT
Attachment (SATA), Serial Attached Small Computer System Interface (SAS), and Fibre Channel (FC).
SATA disks are prevalent on laptop and desktop computers because they are less expensive than SAS
drives. Rotational speed on the platters within each disk also have a significant effect on the speed of data
access. SATA drives commonly come in speeds of either 5,400RPM or 7,200RPM (Revolutions per
Minute). SAS drives commonly come in speeds of either 10,000RPM or 15,000RPM, which is part of the
reason why SAS drives can generally access data faster than SATA drives. Higher speeds are better.
SATA disks work well on individual computers because single users rarely need the advanced throughput
of multiple Input/Output (I/O) paths for accessing data on the disk. Servers for small offices might also
use SATA disks when there are not many users and those users do not constantly access very large files or
continuously access numerous small files on the server. Generally speaking, you should only store SQL
Server data on SATA disks for development, testing, or for a very small number of users.
SAS disks improve on the performance of the old SCSI standard. Simultaneous multiple I/O gives SAS
disks a large performance advantage over SATA disks in addition to their higher rotational speeds. The
FC standard is used primarily in enterprise environments for high capacity and highly available Storage
Area Network (SANs). SANs employ multiple disks that are configured as storage volumes (drive
letters). The multiple disks that comprise a SAN provide redundancy and resiliency from disk failures as
part of a Redundant Array of Independent Disks (RAID) configuration.
A data protection RAID configuration can and should be used whenever downtime needs to be avoided
due to disk failure. For example, RAID Level 1 consists of two disks where one disk mirrors its data onto
the second disk. If one of the disks fail, the system can still operate normally using the other disk. You can
also employ disk duplexing, which is the same concept as disk mirroring, but each disk has its own disk
controller so that the disk controller is not a single point of failure. RAID Level 5 uses between 3 and 32
disks. The more disks, the higher capacity of the storage array. In a RAID Level 5 configuration, one disk
can fail, and the system continues to operate normally. If more than one disk fails at the same time, data is
lost. Ideally, SQL Server system and transaction log files should both be mirrored or duplexed. This
means that they should be mirrored and on separate disk controllers wherever possible. At a minimum, all
SQL Server database and transaction log files should be stored in a data protection RAID configuration,
such as RAID Levels 1, 5, 6, or 10.
A new breed of data storage has emerged recently, which greatly speeds up data access over conventional
“hard disks.” Solid State Disks (SSDs) are all electronic, similar to Random Access Memory (RAM)
used in all computers. The main difference between RAM and SSDs is that SSDs do not lose data when
powered off. Unlike conventional hard disks, SSDs have no mechanical parts, so data retrieval and
recording is significantly faster, and SSDs have no moving parts to wear out. Eventually, SSDs will be the
standard for data storage on all computers because the pricing on SSDs has come down dramatically from
a few years ago. However, SSDs still cost significantly more than conventional drives. In the coming
years, when SSDs will cost about the same as conventional disks, computer manufacturers will install
SSDs as standard equipment on all machines. SSDs come in the same variety of interfaces as
conventional drives, including SATA, SAS, and FC. SSDs can also be used in RAID configurations just
like conventional disks. Besides much faster performance, SSDs are manufactured in the smaller 2.5-inch
form factor, the same form factor as laptop drives. SSDs generally do not come in the 3.5-inch desktop
drive size; you can purchase adapters so that a 2.5-inch SSD will fit into a 3.5-inch hard disk slot on a
desktop or server computer.

Network
Both the network card in the SQL Server machine and the network bandwidth are important factors in the
performance of your application. The server should contain a 64-bit network card, which is usually
standard in today’s computers that run Microsoft’s 64-bit operating systems, such as Windows 7/8/8.1/10
and Windows Server 2008/2012/2016. You should use Gigabit (1GB) Ethernet network adapters versus
legacy 10MB/100Mb Ethernet network adapters whenever possible. Use 10GB network adapters if your
local area network (LAN) supports it! The bottom line is that the best hardware and the best designed
database do you no good on a slow, overtaxed network.
Configuring and Tuning SQL Server
If you do not configure the server properly, all of the hardware in the world and the best designed
database mean nothing. Processor options, memory options, I/O options, and query and index options all
allow you to designate the most appropriate server configuration for you. Although most of the time you
will leave these options at their default values, it is useful to know what configuration options are
available to you.

Memory Options
You can designate the minimum and maximum memory used by SQL Server. You can also specify the
minimum memory allocated to each user for each query run. You should generally not modify any of the
memory options. This is because SQL Server does an excellent job of allocating and deallocating memory
on its own. The only time you would want to modify these options is if you are running SQL Server on the
same machine as another highly memory-intensive application, such as Microsoft Exchange Server. I
recommend running SQL Server on a dedicated machine where this is not a problem. If you must modify
the SQL Server memory options, here’s the process:
1. Right-click the server you want to affect and select Properties. The Server Properties dialog box
opens (see Figure 21.1).
FIGURE 21.1 The Server Properties dialog box contains pages that enable you to modify various
properties of your SQL Server.
2. Click to select the Memory page (see Figure 21.2).
FIGURE 21.2 The Memory page of the SQL Server Properties dialog box enables you to set memory
options.
3. Modify the options as desired.

Processor Options
You can configure the way in which SQL Server uses your server’s processors. The configuration options
available include the following:
You can configure the relative priority of the SQL Server process.
You can determine which of the server’s CPUs SQL Server will use.
You can designate the total number of operating system threads that SQL Server can use on your
computer.
You can set the maximum number of CPUs used by parallel query operations.
To modify the processor-related properties:
1. Right-click the server you want to affect and select Properties.
2. The Server Properties dialog box appears.
3. Click to select the Processors page. The dialog box appears as in Figure 21.3.
FIGURE 21.3 The Processors page of the Server Properties dialog box enables you to modify
processor-related properties of your SQL Server.
4. Modify the options as desired.

Security Options
You will usually work with Security options when establishing a SQL Server. Options available include
the type of authentication you want on the server (Windows Authentication or SQL Server and Windows
Authentication) and the type of login auditing you want to perform when user logins are unsuccessful.
Use the following steps to modify Security options for the server:
1. Right-click the server you want to affect and select Properties.
2. The Server Properties dialog box appears.
3. Click to select the Security page. The dialog box appears as in Figure 21.4.
FIGURE 21.4 The Security page of the Server Properties dialog box enables you to modify security-
related properties of your SQL Server.
4. Modify the options as desired.

Connections Options
The Connections options enable you to determine the maximum number of concurrent connections that the
server will allow, as well as whether the server will allow remote connections. Other options are
available as well.
Use the following steps to modify Connections options for the server:
1. Right-click the server you want to affect and select Properties.
2. The Server Properties dialog box appears.
3. Click to select the Connections page. The dialog box opens as in Figure 21.5.
FIGURE 21.5 The Connections page of the Server Properties dialog box enables you to modify
connection-related properties of your SQL Server.
4. Modify the options as desired.

Database Settings Options


The Database Settings page of the Server Properties dialog box enables you to alter settings that affect the
databases on that server. For example, you can set the default locations for database and log files, and you
can set the default index file factor.
To modify Database Settings options for the server:
1. Right-click the server you want to affect and select Properties.
2. The Server Properties dialog box opens.
3. Click to select the Database Settings page. The dialog box appears as shown in Figure 21.6.
FIGURE 21.6 The Database Settings page of the Server Properties dialog box enables you to modify
database-related properties of your SQL Server.
4. Modify the options as desired.

Advanced Options
The Advanced page of the Server Properties dialog box enables you to configure various server options.
These include where triggers can fire other triggers, the two-digit year cutoff, and much more.
Use the following steps to modify Advanced options for the server:
1. Right-click the server you want to affect and select Properties.
2. The Server Properties dialog box appears.
3. Click to select the Advanced page. You see the dialog box in Figure 21.7.
FIGURE 21.7 The Advanced page of the Server Properties dialog box enables you to modify various
properties of your SQL Server.
4. Modify the options as desired.

Permissions Options
The Permissions page of the Server Properties dialog box enables you to modify permissions that relate
to the server (not to a particular database). Here you can add and remove logins and roles to and from the
server. You can also Grant, With Grant, and Deny server-related rights to logins and roles. Server-related
rights include whether the user or role can alter any database, whether the user or role can alter any login,
and much more.
Use the following steps to modify Permissions options for the server:
1. Right-click the server you want to affect and select Properties.
2. The Server Properties dialog box appears.
3. Click to select the Permissions page. You see the dialog box in Figure 21.8.
FIGURE 21.8 The Permissions page of the Server Properties dialog box enables you to modify
permission-related properties of your SQL Server.
4. Modify the options as desired.

Summary
The best-designed system will fail to meet users’ needs if it performs poorly. The first line of attack when
attempting to optimize performance is to ensure that the hardware on which SQL Server runs is adequate
for the job at hand. After all the proper hardware is in place, you must determine that you have properly
configured the SQL Server software. After you configure your hardware and the SQL Server software,
you must make sure you take all of the steps to properly maintain the server. In case things go awry, you
must implement and test a backup and restore procedure.

Q&A
Q. Why is memory so important to a SQL Server?
A. SQL Server uses memory to hold all data pages, index pages, and log records. It also uses memory
to hold compiled queries and stored procedures.
Q. Explain some of the security options available.
A. Using the Security page of the Server Properties dialog box, you can change the type of
authentication you want to allow (Windows only versus Windows and SQL Server). You can also
determine what type of logging SQL Server will perform when logins are unsuccessful.

Workshop

Quiz
1. Name four things you can do to your hardware to improve performance of your SQL Server.
2. Using the Memory options page of the Server Properties dialog box, you can configure the relative
priority of the SQL Server process (true/false).
3. Using the Processor options page of the Server Properties dialog box, you can determine which of
the server’s CPUs SQL Server will use (true/false).
4. The Permissions page of the Server Properties dialog box enables you to modify database
permissions (true/false).

Quiz Answers
1. More memory, more processors, RAID array, faster network.
2. False. Using the Processor options page of the Server Properties dialog box, you can configure the
relative priority of the SQL Server process.
3. True.
4. False. The Permissions page of the Server Properties dialog box enables you to modify server-
related permissions.

Activities
View the various pages of the Server Properties dialog box. When you are finished, back up the
AdventureWorks database and then restore the database.
Lesson 22. Maintaining the Databases You Build

Just as you need to maintain your SQL Server, you also need to maintain the databases you build. If you
fail to properly maintain your databases, not only can performance be affected, you can also lose your
data. This lesson explains: How to back up your databases
How to restore your databases
How to utilize the Database Tuning Advisor
How to create and work with maintenance plans

Backing Up Your Databases


Most companies store mission-critical information on their SQL Servers. If your data is important to you,
it is imperative that you back up your databases.
Think of backing up your database like brushing your teeth. It is something that you don’t think about; you
just do it unequivocally each and every day, without exception! Two types of backups are available:
Full database backups: Back up the entire database and portions of the log.
Differential database backups: Back up data modified since the last backup.
You need to decide which backup option is appropriate for you. The right choice depends on how much
information is changed each day as well as how critical the information is to you. For example, if the data
is changed throughout the day and is mission-critical, you want to perform a full database backup daily
and then back up the transaction log hourly.
SQL Server offers three recovery models:
Full: Offers full protection. With this option, you are able to restore all committed transactions. The
database and the log are both backed up.
Bulk Logged: Offers minimal data recovery. With this option, logging is minimal. You get the best
performance and use the least amount of memory.
Simple: In the case of failure, this option loses all data modified since the last backup. With this
option, you can recover data only as of the last backup.
Use the following steps to select a recovery model:
1. Right-click the database for which you want to establish the recovery model and select Properties.
The Database Properties dialog box appears.
2. Click the Options page.
3. Open the Recovery Model drop-down list and select the appropriate recovery model (see Figure
22.1).
FIGURE 22.1 The Recovery Model drop-down list on the Options page enables you to select the
appropriate recovery model.
4. Click OK to close the Properties dialog box and save your changes.
Use the following steps to perform a backup:
1. Right-click the database that you want to back up and select Tasks|Back Up. The Back Up Database
dialog box appears (see Figure 22.2).
FIGURE 22.2 The Back Up Database dialog box enables you to designate information about the
backup.
2. Designate which database you want to back up, the name for the backup, and an optional
description for the backup.
3. Use the Backup Type drop-down to indicate whether you want to perform a full or a differential
backup.
4. Click Add or Remove to designate the filename and location for the backup.
5. Click the Backup Options page to designate additional backup options (see Figure 22.3). For
example, you can designate whether you want SQL Server to verify the backup on completion.
FIGURE 22.3 The Backup Options page of the Back Up Database dialog box enables you to designate
additional backup options.
6. Designate whether you want to append to or overwrite the existing media.
7. Click OK to complete the process.

Restoring a Database
Restoring a database is similar to backing it up. You can restore a database to itself (overwrites the
existing database), to another existing database, or to a new database. Use the following steps to restore a
database:
1. Right-click the database that you want to restore and select Tasks|Restore|Database. The Restore
Database dialog box appears (see Figure 22.4).
FIGURE 22.4 The Restore Database dialog box enables you to designate information about the restore
process.
2. Designate whether you want to restore from a database or you want to restore from a device.
3. If you click Device and then click the ellipsis (…), the Select Backup Devices dialog box, shown
in Figure 22.5, appears. Here you can designate the backup location.
FIGURE 22.5 The Select backup devices dialog allows you to designate the backup location.
4. Click Add to specify the file you want to restore from. The Locate Backup File dialog box
displays.
5. Select a file and click OK.
6. Click OK to close the Select Backup Devices dialog box. You return to the Restore Database
dialog box.
7. Click the Options page to designate the restore options (see Figure 22.6).
FIGURE 22.6 The Options page of the Restore Database dialog box enables you to designate
additional restore options.
8. Designate whether you want to overwrite the existing database. If you do not select this option and
you attempt to restore to an existing database, SQL Server returns an error.
9. Designate the logical and physical filenames for the database and the log file. If you are restoring
from one machine to another and the machines have different directory structures, you need to
change the physical filename to reflect the appropriate directory structure.
10. Indicate the recovery completion state.
11. Click OK to perform the restore process.

The Database Engine Tuning Advisor


As its naming implies, the Database Engine Tuning Advisor provides you with the information you need to
optimize the performance of your databases. You access the Database Engine Tuning Advisor within the
Performance Tools folder underneath SQL Server on the Start menu (see Figure 22.7).
FIGURE 22.7 You can find the Database Engine Tuning Advisor within the Performance Tools folder
on the Start menu.
After launching the Database Engine Tuning Advisor, the Connect to Server dialog box displays. Supply
the connection information and click Connect. The Database Engine Tuning Advisor opens as shown in
Figure 22.8.
FIGURE 22.8 The Database Engine Tuning Advisor enables you to designate options for tuning the
tables in one or more databases.
To tune a database, take the following steps:
1. Type a name for the session in the Session name text box.
2. Indicate where you want to store the Workload analysis. You can select File, Table, or Plan Cache
(see the section “Creating a Workload” later in this lesson).
3. Select the databases and tables you want to tune. Note that you can tune all tables in a database or
tune only selected tables.
4. Click Start Analysis to perform the analysis.
5. After performing an analysis, the results appear as in Figure 22.9. Notice in the figure that the
Database Engine Tuning Advisor has suggested the indexes that would help to improve the
performance of the database.
FIGURE 22.9 The Database Engine Tuning Advisor provides a list of recommendations for indexes
you should create.

Creating a Workload
A workload is a set of T-SQL statements that execute against a database you want to tune. The Database
Engine Tuning Advisor analyzes the workloads in order to recommend strategies you can use to improve
performance.
You can create a workload using one of three methods:
Use the plan cache as a workload. This prevents you from having to manually create a workload.
Use the Query Editor in Management Studio to create a workload.
Use SQL Server Profiler to create a trace file or trace table workloads.
Creating and Working with Database Maintenance Plans
You use SQL Server jobs to perform tasks, such as backing up databases, on a regular basis. You can
schedule a job to run regularly at specific days and times, or you can execute a job one time only. The
easiest way to create a job that maintains your databases is by using the Maintenance Plan Wizard. Use
the following steps to run the Maintenance Plan Wizard:
1. Expand the Management node in the Object Explorer until you can see the Maintenance Plans node
(see Figure 22.10).

FIGURE 22.10 The Maintenance Plans node enables you to create and manage maintenance plans.
2. Right-click the Maintenance Plans node and select Maintenance Plan Wizard. The Maintenance
Plan Wizard opens (see Figure 22.11).
FIGURE 22.11 The Maintenance Plan Wizard greatly facilitates the process of creating maintenance
plans.
3. Click Next. The Select Plan Properties portion of the wizard displays (see Figure 22.12). Here you
provide a name for the plan. You also indicate the user the plan will run as and whether you need a
separate schedule for each task.
FIGURE 22.12 The Plan Properties page of the wizard enables you to designate basic settings for the
maintenance plan.
4. Click Change to designate the schedule for the maintenance plan. The New Job Schedule dialog
box appears (see Figure 22.13).
FIGURE 22.13 The New Job Schedule dialog box enables you to designate when the maintenance
plan will execute.
5. Designate the frequency and other properties of the schedule. In Figure 22.13, the job is scheduled
to run daily at 2am starting 7/27/2015 and with no end date.
6. Click OK to close the New Job Schedule dialog box and return to the wizard.
7. Click Next. The Select Maintenance Tasks step of the wizard displays (see Figure 22.14). Here you
select the tasks you want the plan to perform. For example, you can have the plan update database
statistics and back up the database.
FIGURE 22.14 The Select Maintenance Tasks step of the wizard enables you to specify what
operations the maintenance plan will perform.
8. Click Next. The Select Maintenance Task Order step of the wizard displays (see Figure 22.15).
Here you can order the tasks you selected in the Select Maintenance Tasks step.

FIGURE 22.15 The Select Maintenance Task Order step of the wizard enables you designate the order
in which the task operations will execute.
9. Click Next. This step differs depending on what tasks you have opted for the plan to perform. In
this example, the Define Back Up Database step appears (see Figure 22.16), prompting you for
information about the backup that the plan will perform.

FIGURE 22.16 The Define Back Up Database step enables you to designate specifics about the
backup the maintenance plan will perform.
10. Continue to click Next until you have supplied information for all tasks the plan will perform.
11. The Select Report Options step displays. You can write the report to a text file and optionally
email it to a designated email address.
12. Click Next. The Complete the Wizard step displays, providing you with a summary of the options
you selected (see Figure 22.17).
FIGURE 22.17 The Complete the Wizard step provides you with a summary of the options you
selected.
13. Click Finish. The wizard creates the steps and jobs necessary to complete the maintenance
processing.
The process that the wizard just went through created a maintenance plan with the name specified in the
wizard (see Figure 22.18). To modify the maintenance plan, right-click the name of the maintenance plan
and select Modify. The plan appears (see Figure 22.19).
FIGURE 22.18 The wizard creates a maintenance plan that appears with the name that you specified in
the wizard.
FIGURE 22.19 You can easily modify the maintenance plan you created.
If you want to modify one of the steps, use the following steps:
1. Double-click the step you want to modify. You see the dialog box that’s appropriate for the step you
selected. As in Figure 22.20, the Reorganize Index Task dialog box displays.

FIGURE 22.20 Double-clicking a step brings up the appropriate dialog box.


2. When you are finished designating the desired values for the step, click OK to close the dialog box.
3. Continue editing steps as desired.
4. Click the Save toolbar tool and then close the plan.
The process of running the wizard also created a job that executes the maintenance plan at designated
intervals. To view the job that the wizard created, use these steps: 1. Expand the SQL Server Agent node.
2. Expand the Jobs node.
3. Right-click the job that the Maintenance Plan Wizard created.
4. Select Properties. The Job Properties dialog box displays (see Figure 22.21).

FIGURE 22.21 The Job Properties dialog box enables you to modify attributes of the job that the
Maintenance Wizard created.
5. Click the appropriate tab to modify the desired properties. For example, the Schedules page
enables you to easily modify the schedule associated with the job.
6. Click OK to close the dialog box and return to Management Studio.
Summary
The best-designed system will fail to meet users’ needs if it performs poorly. The first line of attack when
attempting to optimize performance is to ensure that the hardware on which SQL Server runs is adequate
for the job at hand. After all the proper hardware is in place, you must determine that you have properly
configured the SQL Server software (see Lesson 24, “Installing and Upgrading SQL Server”). After you
configure your hardware and the SQL Server software, you must make sure that you take all of the steps to
properly maintain the server. In case things go awry, you must implement and test a backup and restore
procedure.

Q&A
Q. Name and describe the three recovery models.
A. The Full recovery model enables you to restore all committed transactions. With this option, SQL
Server backs up both the database and the log file. With the Bulk Logged recovery model, logging is
minimal. You get the best performance with the least amount of memory, but with the minimal
recovery. The Simple recovery model loses all data since the last backup. With this model, you can
recover data only as of the last backup.
Q. What is the purpose of the Database Engine Tuning Advisor?
A. The Database Engine Tuning Advisor analyzes the tables in your database. It makes suggestions as
to what steps you can take to improve the performance of the database. For example, it suggests
indexes that you can add to each table to improve performance when retrieving data from that table.

Workshop

Quiz
1. Name two types of database backups.
2. You can overwrite an existing database when restoring a database (true/false).
3. What is a workload?
4. You do not need to specify a workload when utilizing the Database Engine Tuning Advisor
(true/false).
5. The Database Maintenance Plan Wizard only enables you to specify when backups are performed
(true/false).

Quiz Answers
1. Full database backups and differential database backups.
2. True. This is an option that you can designate when restoring a database.
3. A workload is a set of T-SQL statements that execute against a database you want to tune.
4. False. A workload is required.
5. False. The Database Maintenance Plan Wizard enables you to specify a plethora of tasks that you
can include in the maintenance plan.
Activities
Back up and then restore the AdventureWorks2014 database. Then run the Database Maintenance Plan
Wizard. Practice including different tasks within the maintenance plan. When you are finished, take a look
at the job the maintenance plan created.
Lesson 23. Performance Monitoring

It is important you build SQL statements that will execute efficiently. Fortunately SQL Server Management
Studio provides you with the tools to analyze your SQL statements and ensure you have built them as
efficiently as possible. This lesson introduces you to: How to execute queries in SQL Server
Management Studio How to display and analyze the estimated execution plan for a query How to add
indexes to allow queries to execute more efficiently How to set query options
How to use the SQL Server Profiler to diagnose performance bottlenecks

Executing Queries in SQL Server Management Studio


By executing a query within SQL Server Management Studio, you can easily troubleshoot performance
problems and tune your SQL statements. Use the following steps to execute a query:
1. Click the New Query button on the toolbar (see Figure 23.1). A new query window appears where
you can type a SQL statement (see Figure 23.2).

FIGURE 23.1 Click the New Query button on the toolbar to create a new query.
FIGURE 23.2 You use the query window to type the SQL statement you want to execute.
2. Type the desired SQL statement (see Figure 23.3).
FIGURE 23.3 Type the desired SQL statement in the Query window.
3. Click the Execute button on the toolbar to execute the query. The results appear as in Figure 23.4.
FIGURE 23.4 After executing the query, the results appear in the Results pane of the query window.
4. Click the Messages tab to view any messages associated with the execution of the query (see
Figure 23.5).
FIGURE 23.5 The Messages tab of the Results pane shows you any messages associated with the
execution of the query.

Displaying and Analyzing the Estimated Execution Plan


Generally, you will not want to simply execute queries in SQL Server Management Studio. You will also
want to analyze those queries to see if they are executing as efficiently as possible. Use the following
steps to analyze a query:
1. Click the New Query button on the toolbar. A new query window appears where you can type a
SQL statement.
2. Type the desired SQL statement.
3. Click Display Estimated Execution Plan. Your screen appears as in Figure 23.6.
FIGURE 23.6 After clicking the Display Estimated Execution Plan toolbar button, you can see the
execution plan for the query.
4. Hover your mouse pointer over the various steps in the execution plan. You will get more
information about each step (see Figures 23.7 and 23.8).
FIGURE 23.7 If you hover your mouse pointer over each step of the execution plan, you see
information about that step.
FIGURE 23.8 Notice in the example, SQL Server is using a clustered index scan when executing the
SQL statement.
5. If you want to display the execution plan each time you execute the query, click the Include Actual
Execution Plan button on the toolbar. The Execution Plan tab displays each time you execute the
query (see Figure 23.9).
FIGURE 23.9 If you click the Include Actual Execution Plan button on the toolbar, the Execution Plan
tab displays each time you execute the query.
6. To include client statistics each time you execute the query, click the Include Client Statistic button
on the toolbar. After executing the query, the Client Statistics tab appears as in Figure 23.10. Here
you can receive valuable statistical information about the execution of the query. For example, you
can determine the number of roundtrips SQL Server made to the server in executing the query.
FIGURE 23.10 If you click the Include Client Statistics button on the toolbar, the Client Statistics tab
appears each time you run a query.

Adding Indexes to Allow Queries to Execute More Efficiently


The easiest way to improve the efficiency of the queries you build is to add indexes to the underlying
tables. You can easily view the results of your efforts using the Execution Plan tab and the Client Statistics
tab after executing the query. Here’s how:
1. Make sure you have both the Include Actual Execution Plan and Include Client Statistics toolbar
buttons selected.
2. Execute a query and apply criteria to a field on which there is no index (see Figure 23.11).
FIGURE 23.11 This query is querying by ClientID for which there is no index.
3. Click the Execution Plan tab. Notice that the execution plan includes a sort (see Figure 23.12). A
sort is very inefficient when executing a query.
FIGURE 23.12 Notice that the execution plan for the query includes a sort.
4. Click the Client Statistics tab and note the Total execution time so you can compare it to your
optimized query.
5. Create an index on the field by which you are searching (see Figure 23.13).
FIGURE 23.13 Create an index based on ClientID.
6. Execute the query again.
7. Compare the Execution Plan tab. Notice that the execution plan no longer includes a sort and
instead includes a clustered index scan (see Figure 23.14).
FIGURE 23.14 After creating the index, the Execution Plan no longer includes a sort.
8. Compare the Client Statistics tab and note the Total execution time. It should be less than the one
without index.

Setting Query Options


SQL Server Management Studio provides you with a plethora of options you can use to affect how your
queries process. Use the following steps to access and modify these options:
1. Select Query Options from the Query Menu. The Query Options dialog box displays (see Figure
23.15).
FIGURE 23.15 The Query Options dialog enables you to modify options that affect how your queries
process.
2. Using the General page, you can set options, such as determining the maximum number of rows that
SQL Server returns before stopping. This valuable setting ensures that you don’t accidentally
execute a query that returns millions of rows.
3. Using the Advanced page (see Figure 23.16), you can set additional options. An example is the
SET NOCOUNT setting. When turned on, SQL Server refrains from returning the number of rows
processed. This improves the performance of your queries.

FIGURE 23.16 The Advanced page of the Query Options dialog box enables you to set additional
query options.
4. The ANSI page (see Figure 23.17) enables you to set some of the SQL-92 standard query execution
behavior. An example is how SQL Server handles nulls.

FIGURE 23.17 The ANSI page of the Query Options dialog box enables you to set some of the SQL-
92 standard query execution behavior.
5. The Grid page (see Figure 23.18) of the Query Options dialog box enables you to affect how SQL
Server displays the output from the query.

FIGURE 23.18 The Grid page of the Query Options dialog box enables you to affect how SQL Server
displays the output from the query.
6. The Text page (see Figure 23.19) of the Query Options dialog enables you to set the options that
apply when you opt to display the result set in text format or to redirect it to an output file.
FIGURE 23.19 The Text page of the Query Options dialog enables you to set options that affect you
when you display the result set as text.

SQL Server Profiler


A helpful tool when monitoring and analyzing performance is the SQL Server Profiler. Using the SQL
Server Profiler, you can monitor the SQL Server environment to determine which SQL statements are
negatively affecting performance. The SQL Server Profiler enables you to
Step through problem queries.
Find and diagnose slow-running queries.
Capture a series of SQL statements that are causing a performance bottleneck.
The steps that follow cover both how to launch the Profiler and how to create a new trace.
1. To launch the SQL Server Profiler from SQL Server Management Studio, select Tools, SQL Server
Profiler (see Figure 23.20). The Profiler opens and prompts you to connect to the server.
FIGURE 23.20 While in Management Studio, select Tools, SQL Server Profiler to launch the Profiler.
2. Enter the required connection information and click Connect. The Profiler appears as in Figure
23.21. You are now ready to designate the properties of the trace you are creating.
FIGURE 23.21 After you have launched the Profiler, you are ready to set properties of your trace.
3. Enter a name in the Trace name text box.
4. By default, the trace information displays in a window. You can opt to instead save the trace
information to a file or to a table. These options enable you to easily analyze the trace information
at a later time.
5. Click the Events Selection tab. The Trace Properties dialog box appears as in Figure 23.22. This is
where you designate the types of events you want to capture as the trace runs.
FIGURE 23.22 The Trace Properties dialog box enables you to determine the behavior of the trace.
6. The Events listed by default do not include many of the events you will probably want to capture.
To show all available events, click the Show All Events check box. The dialog box now appears as
in Figure 23.23.
FIGURE 23.23 Use Show all events to view all the events you can capture in your trace.
7. Expand and collapse the event groupings to view the various events you want to capture. Figure
23.24 shows the TSQL group expanded with five events selected.
FIGURE 23.24 You can select as many events from as many groupings as you would like.
8. Select all the events you want to capture.
9. You will probably want to filter the database whose events you want to trace. To do that, click
Show All Columns. The Trace Properties dialog box opens as in Figure 23.25.
FIGURE 23.25 You must show all columns if you want to filter the trace to activity in a specific
database.
10. Click any one of the column headings. The Edit Filter dialog box appears.
11. Click DatabaseName.
12. Enter the name of the database whose events you want to view (see Figure 23.26).
FIGURE 23.26 To filter the trace to activities occurring in a specific database, enter the name of the
database.
13. Click OK to close the dialog box.
14. When you are ready, click Run to run the trace. The running trace appears as in Figure 23.27.
FIGURE 23.27 When you run your trace, it starts capturing the designated events.
It is easy to see the effects of the actions you take within your database on the trace output. If, for example,
you execute a SQL statement in Management Studio and you have opted to monitor T-SQL events, the
results of those events appear in your trace window. Use the following steps to test this out: 1. Create a
new query in Management Studio.
2. Enter a SQL statement in the query window.
3. With your trace running, execute the SQL statement (see Figure 23.28).
FIGURE 23.28 After you have filtered your events, you must do something that triggers the events you
have selected.
4. Return to the SQL Profiler. The trace window should appear as in Figure 23.29.
FIGURE 23.29 The effects of executing your SQL statement show up in the Trace window.
5. Click Clear Trace Window at any time to remove all trace information.
6. Click Stop Selected Trace to terminate the trace process.

Summary
Learning how to create queries can be moderately difficult. Learning to create efficient queries is even
more difficult. In this lesson, you learned how you can use SQL Server Management Studio to design and
test the queries you will include in your stored procedures, triggers, functions, and other objects that use
T-SQL. You saw how you can use the tools built into Management Studio to display and analyze the
estimated execution plan for a query. You learned how to add indexes to enable queries to execute more
efficiently and how to set query options. Finally, you saw how you can use the Query Analyzer to see
exactly what is happening when you execute a T-SQL statement.

Q&A
Q. Explain why you will probably want to analyze the queries you include in your stored
procedures, functions, and so on.
A. Using the analysis tools built into SQL Server Management Studio, you can analyze your T-SQL
statements to ensure that they execute as efficiently as possible. You can modify your queries at will
and observe the effect those changes have on performance.
Q. Describe what the SQL Profiler is used for.
A. You use the SQL Profiler to trace selected events that occur when a query, view, stored procedure,
or function executes.
Workshop

Quiz
1. Name the tool on the toolbar that enables you to run the query you type into the query window.
2. Name the tool on the toolbar that enables you to view the execution plan each time you run a query.
3. Name the tool on the toolbar that enables you to view client statistics when you run your queries.
4. What is the most important thing you can do to improve query execution?

Quiz Answers
1. New Query
2. Include Actual Execution Plan
3. Include Client Statistics
4. Add indexes

Activities
Build a query based on the Sales.SalesOrderDetail table. Display the SalesOrderID, OrderQty, UnitPrice,
and LineTotal, ordering the data by LineTotal. Execute the query. Notice the number of rows affected on
the Messages page. Indicate that you want to view both the execution plan and the client statistics. Run the
query again. View the results in both the Execution Plan tab and the Client Statistics tab. Add an index
based on LineTotal. Finally, re-execute the query, noting the differences in the execution plan and client
statistics.
Lesson 24. Installing and Upgrading SQL Server

Although you can use the material in this book with most versions of SQL Server, SQL Server 2014 is the
most commonly used version of SQL Server at the time of this writing. This lesson explains: How to
launch the SQL Server installation process How to configure the various installation options How to
launch SQL Server Management Studio

Installing SQL Server 2014 Enterprise Edition


Although installing SQL Server is a fairly simple process, there are a few questions you are asked during
the installation process that might need some clarification. The text that follows walks you through the
process of installing the SQL Server 2014 database engine and provides an explanation of the various
options available to you. Here’s the process:
1. Before launching the setup program, you must first locate and mount the ISO file. Right-click the
ISO file and select Mount (see Figure 24.1). This opens the ISO file so you can view its contents
(see Figure 24.2).

FIGURE 24.1 Mount the ISO file so that you can view its contents.
FIGURE 24.2 The contents of the ISO file contain setup.exe.
2. Double-click setup.exe.
3. When prompted to allow the program to make changes to your computer, click Yes.
4. After a short delay, the SQL Server Installation Center appears. Here you can opt to perform a
variety of operations.
5. Click Installation. The dialog box displays as in Figure 24.3.
FIGURE 24.3 After clicking Installation, you can select the type of installation you want to perform.
6. Click New SQL Server Stand-alone Installation or Add Features to an Existing Installation. The
installation process goes through a series of steps that might take quite a bit of time to execute (see
Figure 24.4).
FIGURE 24.4 It is important to be patient as the installation process executes.
7. After quite some time, the installation wizard prompts you to indicate whether you want to perform
a new instance of SQL Server or add features to an existing instance of SQL Server (see Figure
24.5).
FIGURE 24.5 You can either create a new SQL Server instance, or add features to an existing
instance.
8. Click Perform a New Installation of SQL Server 2014 and click Next.
9. Indicate whether you are installing a free edition or if you have a product key that you will be
using. Click Next.
10. Accept the license terms and click Next.
11. Select SQL Server Feature Installation and click Next.
12. As its name implies, the Feature Selection step of the installation process enables you to easily
designate the features you want to include in your instance of SQL Server (see Figure 24.6). Select
the desired features and click Next.
FIGURE 24.6 You can customize SQL Server to include only the features you need.
13. If you have multiple instances of SQL Server installed on your computer, each one must be
identified by a unique instance name. Provide a name for the instance that you are creating (see
Figure 24.7) and click Next.
FIGURE 24.7 Provide a unique name for the SQL Server instance.
14. With the Server Configuration step of the installation process, you can create accounts for the
various server processes and indicate when the operating system starts each service (see Figure
24.8). Make your selections and click Next.
FIGURE 24.8 You can designate account information for each process.
15. In the Database Engine Configuration step, you designate the type of authentication you prefer,
information about administrators, and details about data directories. In Figure 24.9, Windows
authentication mode is designated, and AlisonJ has been designated as an Administrator.
FIGURE 24.9 Select the authentication mode and any system administrators.
16. On the Data Directories tab, shown in Figure 24.10, you can view and modify the directories
within which SQL Server will store the various files utilized by the server (for example,
databases).
FIGURE 24.10 You can easily customize where the various SQL files will reside.
17. After designating all desired features, click Next. The Ready to Install step displays, reflecting all
features you installed (see Figure 24.11). Review the settings carefully.
FIGURE 24.11 It is important to review the settings you have selected before you click Install.
18. Click Install to complete the process. After several minutes, you should receive a message
indicating that you need to reboot your computer. After rebooting your computer, you will be ready
to start working with SQL Server.

Installing SQL Server Management Studio


SQL Server Management Studio is a separate download and a separate installation process. Use the
following steps to install SQL Server Management Studio:
1. Download the file and run the executable file (.exe).
2. Double-click the executable and click Yes, allowing the program to run.
3. Choose a directory for the extracted files and click OK.
4. When the SQL Server Installation Center launches, click the link to select New SQL Server Stand-
alone Installation or Add Features to an Existing Installation.
5. Accept the license terms and click Next.
6. Select Add Features to an Existing Instance of SQL 2014 (see Figure 24.12).
FIGURE 24.12 To install Management Studio, you must add features to your existing instance of SQL
Server.
7. Click Next. The Feature Selection portion of the installation appears. Select all the desired
features. Note that in Figure 24.13, Management Tools is selected. This includes Management
Studio.
FIGURE 24.13 Add Management Tools to your SQL Server instance so that you can use Management
Studio.
8. Click Next.
9. Complete the installation. Management Studio is now ready to use.

Summary
Although Microsoft makes it fairly easy to install SQL Server, it prompts you for information that you
might not be familiar with. This lesson walked you through the installation process, covering the available
options.

Q&A
Q. What is the difference between the SQL Server Database Engine and Management Studio?
A. The SQL Server Database Engine is the application that provides the processing for the database.
This processing includes the execution of T-SQL, whether from the Query window, views, stored
procedures, functions, or triggers. SQL Server Management studio provides a means of graphically
managing database servers, databases, and their objects.
Workshop

Quiz
1. You are prompted for the authentication model during the installation of the SQL Server 2014
database engine (true/false).
2. Name the management tool you use to manage SQL Server 2014 databases.

Quiz Answers
1. True
2. SQL Server Management Studio

Activities
Download SQL Server. Install both the database engine and SQL Server Management Studio. Launch
Management Studio and practice expanding and contracting the nodes of the Object Explorer. Select
different nodes and view the summary information.
Index

Symbols
@@ functions, 231
@@Error, 219-220
@@Identity, 218
@@RowCount, 217
@@TranCount function, 218
explained, 216
% (percent) sign, 104
_ (underscore), 95, 104

A
accounts, dbo, 295
action queries
DELETE statement, 146
INSERT statement, 143-144
SELECT INTO statement, 145
TRUNCATE statement, 147
UPDATE statement, 141-142
Activity Monitor, 25
Actual Execution Plan button, 361
Add Features to an Existing Installation option, 379
Add Objects dialog box, 306-307
Add Table dialog box, 70-71, 76, 180, 192-193
administration
column permissions, 315-316
function permissions, 315
object permissions, 302-309
assigning permissions to particular objects, 302-305
assigning permissions to users or roles, 305-309
stored procedure permissions, 314
table permissions, 310-312
view permissions, 312-314
Windows Administrators group, 296
advanced options (SQL Server), 330-331
Advanced page (Query Options dialog), 365
AdventureWorks2014 database, installing, 27-29
Agent (SQL Server), 17
aggregate functions
AVG, 113-114
COUNT, 111-112
COUNT_BIG, 112
explained, 110
MAX, 115
MIN, 114
SUM, 112-113
aggregating data with views. See views
aliases, table aliases, 92
ALTER permissions, 309
ALTER VIEW statement, 187
analyzing
Estimated Execution Plan, 358-359
queries, 374
trace output, 372-373
ANSI page (Query Options dialog), 366
Application role, 293
assigning
column permissions, 315-316
function permissions, 315
object permissions
for particular objects, 302-305
to users or roles, 305-309
stored procedure permissions, 314
table permissions, 310-312
view permissions, 312-314
Attach command, 40
Attach Databases dialog box, 40-41
attaching to existing database, 40-41
audit logs, inserting data into
Delete triggers, 272-274
Insert triggers, 266-268
Update triggers, 269-270
authentication
explained, 277-278
logins
granting database access to logins, 284
SA Login, 285, 296
SQL Server logins, 283-284
Windows logins, 280-282
ownership, 295
roles
explained, 285-286
fixed database roles, 289-292
fixed server roles, 286-288
user-defined database roles, 293-294
types of, 278-279, 296
Autogrowth option (New Database dialog box), 37
@AverageFreight variable, 209
averaging data, 113-114
AVG function, 113-114

B
backing up databases, 335-338
Back Up Database dialog box, 336-338
backup devices, 23
BEGIN...END construct, 202
BEGIN TRANSACTION statement, 239
Bigint data type, 47
Binary data type, 47
Bit data type, 47
Books Online, 149
Browse for Objects dialog box, 288-292, 308, 312-313
bulkadmin, 286
Bulk Insert Administrators (bulkadmin), 286
bulk logged recovery, 336, 352
Business Intelligence Edition (SQL Server), 15

C
calculating summary statistics, 109-110
cascading deletes, 85
CASE statement, 207-209, 212
Change Autogrowth dialog box, 37-38
changing sort direction, 102
Char data type, 47
check constraints, 54-55, 65
Check Constraints dialog box, 54-55
Choose Name dialog box, 64, 73
choosing recovery model, 336
clauses. See also keywords; statements
FOR XML, 107-109
FROM, 92
GROUP BY, 109-110
HAVING, 117-118
ORDER BY, 101-102
changing sort direction, 102
syntax, 101
TOP, 118-119
WHERE, 119
data filtering rules, 95-96
IN keyword, 100-101
NOT keyword, 100-101
NULL keyword, 100
syntax, 93-94
Clear Trace Window command, 372
Client Statistics tab (Management Studio), 359-361
COALESCE function, 172
column-level permissions, 315-316
Column Permissions dialog box, 316-317
columns, 45
adding data in, 112-113
column-level permissions, 315-316
computed columns, 57-58
constraints. See constraints
data types available, 46
explained, 5
finding maximum values in, 115
finding minimum values in, 114
identity specifications, 56
indexes, 60-62
maximum values, 115
selecting, 90
Tables and Columns specifications, 79-81
user-defined data types, 58-60
COMMIT TRANSACTION statement, 239
computed columns, creating, 57-58
configuring SQL Server
advanced options, 330-331
connections options, 328-329
database settings, 329-330
memory options, 324-325
permissions options, 331-332
processor options, 326-327
security options, 327-328
connecting to database servers, 25-26
connections options (SQL Server), 328-329
Connect to Server dialog box, 25-26, 342
constraints, 50
check, 54-55, 65
default, 53
foreign key, 51, 65, 68
Not Null, 54
primary key, 51, 65
rules, 55
unique, 56
controlling flow of stored procedures
BEGIN...END construct, 202
CASE statement, 207-209, 212
GOTO statement, 203-206
IF...ELSE construct, 200-201
labels, 203-206
overview, 200
RETURN statement, 203-206, 212
WHILE statement, 210-211
CONTROL permissions, 310, 318
converting strings
to lowercase, 160
to uppercase, 161
COUNT_BIG function, 112
COUNT function, 111-112
counting rows, 111-112
@Country variable, 201
CREATE VIEW statement, 185-187
creating
cursors, 245
databases, 33-34
fields, 46
foreign key relationships, 79
indexes, 362-364
joins
full joins, 129
inner joins, 121-124
outer joins, 124-125
self-joins, 130-132
logins
granting database access to logins, 284
SQL Server logins, 283-284
Windows logins, 280-282
stored procedures
in Query Editor, 192-195
with T-SQL, 196
tables
adding to database diagrams, 76
SELECT INTO statement, 145
traces, 367-372
triggers, 263-266
Delete triggers, 272-274
Insert triggers, 266-268
syntax, 266
Update triggers, 269-270
unions, 133-135
users, 300-302
variables, 198-199
views, 179
with Management Studio Query Builder, 179-185
with T-SQL, 185-187
workloads, 343-344
credentials, 23
Credentials node (Management Studio), 23
Cursor data type, 47
@Cursor variable, 249
cursors
defining, 245
looping through records with, 246-249
populating, 246

D
data
deleting
DELETE statement, 146
TRUNCATE statement, 147
inserting
INSERT statement, 143-144
stored procedures, 233-235
updating, 141-142
Database Creators (dbcreator), 286
database diagrams
adding tables, 76
creating, 70-74
definition of term, 6
editing, 75-76
purpose of, 10
relationships versus, 77
removing tables, 77
Database Engine, 387
Database Engine Configuration step (SQL Server installation), 382
Database Engine Tuning Advisor, 18-19, 341-344
accessing, 341
creating workloads, 343-344
purpose of, 352
tuning databases, 342-343
database maintenance plans, 344-351
Database Role – New dialog box, 294
Database Role Properties dialog box, 290-291
databases
AdventureWorks2014, installing, 27-29
attaching to existing database, 40-41
authentication
explained, 277-278
logins, 280-285
ownership, 295
roles, 285-295
types of, 278-279, 296
backing up, 335-338
creating, 33-34
database diagrams
adding tables, 76
creating, 70-74
definition of term, 6
editing, 75-76
purpose of, 10
relationships versus, 77
removing tables, 77
Database Engine Tuning Advisor, 341-344
accessing, 341
creating workloads, 343-344
purpose of, 352
tuning databases, 342-343
database maintenance plans, 344-351
definition of term, 5
design master, 24
indexes, 362-364
logins
granting database access to logins, 284
SA Login, 285, 296
SQL Server logins, 283-284
Windows logins, 280-282
master database, 20
Model, 20-21
MSDB, 21
options, 36-39
recovery models, 336, 352
restoring, 338-341
roles
explained, 285-286
fixed database roles, 289-292
fixed server roles, 286-288
user-defined database roles, 293-294
settings (SQL Server), 329-330
tables. See tables
TempDB, 21, 243-244
transaction log, 39
users, adding, 300-302
views
advantages of, 177, 188
creating, 179-187
customizing user data with, 188
definition of term, 7
explained, 177-179
indexed views, 7
modifying, 184-187
permissions, 312-314
security, 188
database servers, connecting to, 25-26
Databases node (Management Studio), 19-21
explained, 19-20
master database, 20
Model database, 20-21
MSDB database, 21
TempDB database, 21
Database User dialog box, 305-306, 308-309
Database User – New dialog box, 300-301
Data Definition Language (DDL), 24
Data Directories tab (SQL Server installation), 382-384
data filtering, 95-96
data replication, 24-25
data types
fields, 46
user-defined, 58-60
DATEADD function, 98-99, 168
Date data type, 47
DATEDIFF function, 98-99, 169
DATENAME function, 167
DATEPART function, 98, 166, 174
DateTime2 data type, 47
DateTime data type, 47
date/time functions, 96-98, 163
DATEADD, 168
DATEDIFF, 98-99, 169
DATENAME, 167
DATEPART, 98, 166, 174
DAY, 164
GETDATE, 96-97, 163
MONTH, 163
YEAR, 165
DateTimeOffset data type, 47
DAY function, 164
db_accessadmin, 290
db_backupoperator, 290
dbcreator, 286
db_datareader, 290
db_datawriter, 290
db_ddladmin, 290
db_denydatareader, 290
db_denydatawriter, 290
dbo account, 295
db_owner, 290
db_securityadmin, 290
DDL (Data Definition Language), 24
Decimal data type, 48
DECLARE CURSOR statement, 245
DECLARE keyword, 198-199
declaring. See creating
default constraints, 53
defining. See creating
DELETE permissions, 310
DeletePerson trigger, 272
Delete rule (relationships), 84-85
DELETE statement
compared to TRUNCATE, 147
explained, 146
Delete triggers, 272-274
deleting
foreign key relationships, 79
spaces from strings
leading spaces, 162
trailing spaces, 163
table data
DELETE statement, 146
Delete triggers, 272-274
stored procedures, 237
TRUNCATE statement, 147
tables from database diagrams, 77
DENY statement, 302, 317
descriptions for foreign key relationships, 81
designing stored procedures
in Query Editor, 192-195
with T-SQL, 196
design master, 24
diagram pane (View Builder), 184
diagrams, database diagrams
adding tables, 76
creating, 70-74
definition of term, 6
editing, 75-76
purpose of, 10
relationships versus, 77
removing tables, 77
dialog boxes
Add Objects, 306-307
Add Table, 70-71, 76, 180, 192-193
Attach Databases, 40-41
Back Up Database, 336-338
Browse for Objects, 288-292, 308, 312-313
Change Autogrowth, 37-38
Check Constraints, 54-55
Choose Name, 64, 73
Column Permissions, 316-317
Connect to Server, 25-26, 342
Database Role – New, 294
Database Role Properties, 290-291
Database User, 305-306, 308-309
Database User – New, 300-301
Edit Filter, 371
Execute Procedure, 197, 222
Foreign Key Relationships, 73-76, 84-86
Index Columns, 61-62
Indexes/Keys, 61-63
Index Properties, 62-63
Job Properties, 351
Locate Backup File, 28, 339
Locate Database Files, 40-41
Locate Folder, 34
Login – New, 281-283
New Database
creating databases, 33-34
defining database options, 36-39
New Job Schedule, 346
New User-defined Data Type, 58-59
Query Options, 364-367
Advanced page, 365
ANSI page, 366
General page, 365
Grid page, 366
Text page, 367
Relationships, 75
Restore Database, 28, 338-341
Save, 74
Select Backup Device, 28, 339-340
Select Login, 301
Select Objects, 306-308
Select Object Types, 306-307
Select Server Login or Role, 288-289
Select User or Group, 282
Select Users or Roles, 303, 315-316
Server Properties
Advanced page, 330-331
Connections page, 328-329
Database Settings page, 329-330
Memory page, 324-325
Permissions page, 331-332
Processors page, 326-327
Security page, 327-328
Server Role Properties, 288
SQL Server Login Properties, 285
Table Properties, 302-304
Tables and Columns, 70-72, 80
Trace Properties, 369-371
View Properties, 312-313
differential database backups, 335
diskadmin, 286
Disk Administrators (diskadmin), 286
Display Estimated Execution Plan button, 358
displaying Estimated Execution Plan, 358-359
DISTINCT keyword, 105-107, 119
documents (XML), returning data as, 107-109
DROP statement, 147

E
Edit Filter dialog box, 371
editing. See modifying
eliminating xx row(s) affected message, 215-216
EmpGetByTitle function, 257-258
Enterprise Edition (SQL Server), 16
@@Error function, 219-220
error handling
explained, 227
returning success/failure information, 229-231
runtime errors, 227-228
error messages, referential integrity, 83
Estimated Execution Plan, 358-359
EXCEPT operator, 138-139
EXEC permissions, 312
Execute button, 355
Execute Procedure dialog box, 197, 222
Execute Stored Procedure command, 197
executing
queries in SQL Server Management Studio, 355-358
stored procedures, 197-198
Execution Plan tab (Management Studio), 359-362
explicit transactions, 237-238
Express Edition (SQL Server), 14, 30
expressions
first non-null expression, returning, 172
rounding to specified length, 150-151
in SELECT statements, 90-91
extracting
characters from string
left of string, 152
right of string, 152-153
parts of dates, 166
substrings, 159

F
failure information, returning from stored procedures, 229-231
FC (Fibre Channel), 322
fields, 45
adding data in, 112-113
column-level permissions, 315-316
computed columns, 57-58
constraints. See constraints
data types available, 46
explained, 5
finding maximum values in, 115
finding minimum values in, 114
identity specifications, 56
indexes, 60-62
maximum values, 115
selecting, 90
Tables and Columns specifications, 79-81
user-defined data types, 58-60
file groups, 39
files
AdventureWorks2014 sample files, 27-29
file groups, 39
file types, 36
ISO file, mounting, 377-378
log files, 25
explained, 42
inserting data with triggers, 266-274
transaction log, 39
filtering data, 95-96
FindReports function, 258-260
first non-null expression, returning, 172
fixed database roles, 289-292
fixed server roles, 286-288
Float data type, 48
flow of stored procedures, controlling
BEGIN...END construct, 202
CASE statement, 207-209, 212
GOTO statement, 203-206
IF...ELSE construct, 200-201
labels, 203-206
overview, 200
RETURN statement, 203-206, 212
WHILE statement, 210-211
foreign key relationships, 51, 65
adding, 79
deleting, 79
naming, 81
in one-to-many relationships, 68
Tables and Columns specifications, 79-81
viewing, 77-79
Foreign Key Relationships dialog box, 73-76
Delete rule, 84-85
Update rule, 85-86
FOR XML clause, 107-109
FROM clause, 92
full database backups, 335
full joins, 129
FullName function, 253-254
full recovery, 336, 352
function permissions, 315
functions, 149
@@ functions, 231
@@Error, 219-220
explained, 216
@@Identity, 218
@@RowCount, 217
@@TranCount function, 218
AVG, 113-114
COALESCE, 172
COUNT, 111-112
COUNT_BIG, 112
DATEADD, 168
DATEDIFF, 98-99, 169
DATENAME, 167
DATEPART, 98, 166, 174
DAY, 164
EmpGetByTitle, 257-258
FindReports, 258-260
FullName, 253-254
GetAncestor, 259
GETDATE, 96-97, 163
GetTotalInventory, 254-255
inline table-valued functions, 257-258
ISNULL, 170-171, 174
IsNumeric, 149-150
LEFT, 152
LEN, 153
LOWER, 160
LTRIM, 162
MAX, 115
MIN, 114
MONTH, 163
multi-statement table-valued functions, 258-260
NULLIF, 171
permissions, 315
REPLACE, 154
REPLICATE, 156
REVERSE, 155
RIGHT, 152-153
ROUND, 150-151
RTRIM, 163
scalar functions, 253-256
advantages/disadvantages, 255-256
FullName, 253-254
GetTotalInventory, 254-255
SPACE, 158
STUFF, 157, 173
SUBSTRING, 159
SUM, 112-113
UPPER, 161
user-defined functions, 9
YEAR, 165

G
General page (Query Options dialog), 365
Geography data type, 48
Geometry data type, 48
GetAncestor function, 259
GETDATE function, 96-97, 163
GetTotalInventory function, 254-255
global variables
@@Error, 219-220
explained, 216
@@Identity, 218
@@RowCount, 217
@@TranCount, 218
GOTO statement, 203-206
granting database access to logins, 284
GRANT statement, 302
Grid page (Query Options dialog), 366
Grid pane (View Builder), 184
GROUP BY clause, 109-110
groups
file groups, 39
Windows Administrators group, 296

H
hardware, performance tuning
memory, 321-322
networks, 324
overview, 321
processors, 322
storage, 322-324
HAVING clause, 117-118, 119
help, Books Online, 149
Hierarchyid data type, 48

I
@@Identity function, 218
identity increments, 56
identity seeds, 56
identity specifications, 56
IF...ELSE construct, 200-201
Image data type, 48
implicit transactions, 237-238
implied permissions, 300
Include Actual Execution Plan button, 359
Include Client Statistics button, 359-361
Index Columns dialog box, 61-62
indexed views, 7
indexes, creating, 60-62, 362-364
Indexes/Keys dialog box, 61-63
Index Properties dialog box, 62-63
inherited/implied permissions, 300, 317
initial size of databases, 36
IN keyword, 100-101
inline table-valued functions, 257-258
inner joins
creating, 121-124
explained, 126
input parameters, 221-225
INSERT and UPDATE Specification node (relationships), 84-86
Delete rule, 84-85
Update rule, 85-86
INSERT permissions, 310
InsertPerson trigger, 267
INSERT statement, 143-144
Insert triggers, 266-268
installation
AdventureWorks2014 database, 27-29
Management Studio, 385-386
SQL Server, 377-382
Add Features to an Existing Installation, 379
Database Engine Configuration step, 382
Data Directories tab, 382-384
mounting ISO file, 377-378
New SQL Server Stand-alone Installation, 379-380
Ready to Install step, 382-384
Server Configuration step, 381-382
SQL Server Feature Installation step, 381
SQL Server Installation Center, 379-380
Int data type, 48
INTERSECT operator, 137
ISNULL function, 170-171, 174
IsNumeric function, 149-150
ISO file, mounting, 377-378

J-K
Job Properties dialog box, 351
jobs, 17
joining data. See joins; views
joins
explained, 121, 188
full joins, 129, 139
inner joins
creating, 121-124
explained, 126
outer joins, 124-125
explained, 127
left outer joins, 124
right outer joins, 125
purpose of, 126
self-joins, 130-132
junction tables, 70
keywords. See also clauses; statements
DECLARE, 198-199
DISTINCT, 105-107, 119
IN, 100-101
NOT, 100-101
NULL, 100

L
labels, 203-206
leading spaces, removing from strings, 162
LEFT function, 152
left outer joins, 124, 127
LEN function, 153
length of strings, determining, 153
linked servers, 24
@Locale variable, 201
@LocalError variable, 239
@LocalRows variable, 239
Locate Backup File dialog box, 28, 339
Locate Database Files dialog box, 40-41
Locate Folder dialog box, 34
log files, 25
explained, 42
inserting data with triggers
Delete triggers, 272-274
Insert triggers, 266-268
Update triggers, 269-270
transaction log, 39
logical names, 36
Login – New dialog box, 281-283
logins
granting database access to logins, 284
SA Login, 285, 296
SQL Server logins, 283-284
Windows logins, 280-282
Logins node (Management Studio), 22
looping through records with cursors, 247-249
@LoopText variable, 211
@LoopValue variable, 211
lowercase, converting strings to, 160
LOWER function, 160
LTRIM function, 162

M
maintaining databases
backing up, 335-338
Database Engine Tuning Advisor, 341-344, 352
database maintenance plans, 344-351
restoring, 338-341
Maintenance Plan Wizard, 344-351
Management node (Management Studio), 25
Management Studio, 19
Databases node, 19-21
explained, 19-20
master database, 20
Model database, 20-21
MSDB database, 21
TempDB database, 21
executing queries in, 355-358
installation, 385-386
Management node, 25
Query Builder
creating views with, 179-185
modifying views, 184-185
Replication node, 24-25
Security node
Credentials, 23
explained, 21-22
Logins, 22
Server Roles, 22
Server Objects node, 23
backup devices, 23
linked servers, 24
server triggers, 24
many-to-many relationships, 70, 87
master database, 20
MAX function, 115
maximum values, finding, 115
memory
importance of, 333
performance tips, 321-322
SQL Server options, 324-325
Messages tab (Management Studio), 358
MIN function, 114
minimum values, finding, 114
Model database, 20-21
modifying
database diagrams, 75-76
triggers, 263-266
views
with Management Studio Query Builder, 184-185
with T-SQL, 185-187
Money data type, 48
monitoring performance. See performance monitoring
MONTH function, 163
Mount command, 377
mounting ISO file, 377-378
MSDB database, 21
multi-statement table-valued functions, 258-260
@MyMessage parameter, 226

N
naming foreign key relationships, 81
NChar data type, 48
networks
performance tips, 324
SANs (Storage Area Network), 323
New Database command, 33
New Database dialog box
creating databases, 33-34
defining database options, 36-39
New Job Schedule dialog box, 346
New Query button, 355-356
New Query toolbar, 223
New SQL Server Stand-alone Installation option, 379-380
New Trigger command, 263
New User-defined Data Type dialog box, 58-59
NoDeleteActive trigger, 273-274
NOT keyword, 100-101
Not Null constraints, 54
NText data type, 48
NULLIF function, 171
NULL keyword, 100
nulls, 170
COALESCE function, 172
identifying, 170-171
ISNULL function, 170-171, 174
NULLIF function, 171
replacing values with, 171
Numeric data type, 48
numeric functions
IsNumeric, 149-150
ROUND, 150-151
numeric values, identifying, 149-150
NVarChar data type, 48
NVarChar(MAX) data type, 49

O
Object Explorer, 64
object permissions
assigning for particular objects, 302-305
assigning to users or roles, 305-309
explained, 299
one-to-many relationships, 68
one-to-one relationships, 68-69, 87
operators
EXCEPT, 138-139
INTERSECT, 137
options (database), 36-39
ORDER BY clause, 101-102
changing sort direction, 102
syntax, 101
outer joins, 124-125
explained, 127
left outer joins, 124
right outer joins, 125
output parameters, 225-226
ownership, 295

P
parameters of stored procedures, 221
explained, 231
input parameters, 221-225
output parameters, 225-226
percent (%) sign, 104
performance monitoring
indexes, creating, 362-364
overview, 355
queries
Estimated Execution Plan, 358-359
executing in SQL Server Management Studio, 355-358
query options, 364-367
SQL Server Profiler, 367-373
analyzing trace output, 372-373
creating traces, 367-372
performance tuning
hardware
memory, 321-322
networks, 324
overview, 321
processors, 322
storage, 322-324
SQL Server
advanced options, 330-331
connections options, 328-329
database settings, 329-330
memory options, 324-325
overview, 324
permissions options, 331-332
processor options, 326-327
security options, 327-328
Perform a New Installation of SQL Server 2014 option, 379-380
permissions options (SQL Server), 331-332
permission statements, 302
permissions validation, 299
column-level permissions, 315-316
database users, adding, 300-302
definition of term, 278
function permissions, 315
inherited/implied permissions, 300, 317
object permissions
assigning for particular objects, 302-305
assigning to users or roles, 305-309
explained, 299
permission statements, 302
statement permissions, 299
stored procedure permissions, 314
table permissions, 309-312
assigning, 310-312
types of, 309-310
view permissions, 312-314
plans, Estimated Execution Plan, 358-359
populating cursors, 246
primary key constraints, 51, 65
procedures, stored. See stored procedures
procEmployeeGetByTitleAndBirthDateOpt stored procedure, 224-225
procEmployeeGetByTitleAndBirthDate stored procedure, 221
procEmployeeGetYoungSalesReps stored procedure, 221
procEmployeesGetByJobTitleAndHireDate stored procedure, 244
procEmployeesGetByTitleAndBirthDateOutput stored procedure, 225-226
procEmployeesGetCursor stored procedure, 246
procEmployeesGetTemp stored procedure, 243-244
processadmin, 286
Process Administrators (processadmin), 286
processors, 322, 326-327
procGetString stored procedures, 247-248
procOrderDetailAddHandleErrors2 stored procedure, 229
procOrderDetailAddHandleErrors3 stored procedures, 230-231
procOrderDetailAddOutput stored procedure, 234
procOrderDetailAdd stored procedure, 234
procOrderDetailAddTransaction stored procedure, 238
procSalesOrderDetailDelete stored procedure, 237
procSalesOrderDetailUpdate stored procedure, 235-236
procSalesOrderHeaderUpdate stored procedure, 235
Profiler, 16-17, 367-373
analyzing trace output, 372-373
creating traces, 367-372
when to use, 374
properties, Server Properties dialog box
Advanced page, 330-331
Connections page, 328-329
Database Settings page, 329-330
Memory page, 324-325
Permissions page, 331-332
Processors page, 326-327
Security page, 327-328
Public role, 292

Q
queries. See also clauses; statements
analyzing, 374
Estimated Execution Plan, 358-359
executing in SQL Server Management Studio, 355-358
joins
explained, 121
full joins, 129, 139
inner joins, 121-124
outer joins, 124-125
purpose of, 126
self-joins, 130-132
Query Options, 364-367
Advanced page, 365
ANSI page, 366
General page, 365
Grid page, 366
Text page, 367
subqueries, 136-137
Top Values queries, 118-119
union queries, 133-135
Query Builder, 179-185
Query Editor, 192-195
Query Options command (Query menu), 364
Query Options dialog box, 364-367
Advanced page, 365
ANSI page, 366
Grid page, 366
Text page, 367

R
RAID (Redundant Array of Independent Disks), 323
RAM (random access memory)
importance of, 333
performance tips, 321-322
SQL Server options, 324-325
Ready to Install step (SQL Server installation), 382-384
Real data type, 49
records
deleting
DELETE statement, 146
Delete triggers, 272-274
TRUNCATE statement, 147
deleting data in, 272-274
explained, 5-6
inserting, 266-268
looping through, 246-249
updating, 269-270
recovery models, 336, 352
Redundant Array of Independent Disks (RAID), 323
REFERENCES permissions, 310
referential integrity, 81-84
refreshing tables list, 64
relationships, 67
database diagrams versus, 77
Delete rule, 84-85
establishing referential integrity, 81-84
foreign key relationships
adding, 79
deleting, 79
naming, 81
Tables and Columns specifications, 79-81
viewing, 77-79
many-to-many, 70, 87
one-to-many, 68
one-to-one, 68-69, 87
Update rule, 85-86
Relationships dialog box, 75
removing
foreign key relationships, 79
spaces from strings
leading spaces, 162
trailing spaces, 163
table data
DELETE statement, 146
Delete triggers, 272-274
stored procedures, 237
TRUNCATE statement, 147
tables from database diagrams, 77
REPLACE function, 154
replacing
characters in strings, 157
strings
REPLACE function, 154
REPLICATE function, 156
values with nulls, 171
replicas, 24
REPLICATE function, 156
replication, 24-25
Replication node (Management Studio), 24-25
Restore Database dialog box, 28, 338-341
restoring databases, 338-341
results pane (View Builder), 184
RETURN statement, 203-206, 212
@return variable, 255
REVERSE function, 155
reversing strings, 155
RIGHT function, 152-153
right outer joins, 125, 127
roles
explained, 22, 285-286
fixed database roles, 289-292
fixed server roles, 286-288
permissions. See permissions validation
server roles, 22
user-defined database roles, 293-294
ROLLBACK TRANSACTION statement, 238-239
ROUND function, 150-151
rounding expressions to specified length, 150-151
@@RowCount variable, 217
rows
counting, 111
deleting
DELETE statement, 146
Delete triggers, 272-274
TRUNCATE statement, 147
explained, 5-6
inserting, 266-268
looping through, 246-249
updating, 269-270
RTRIM function, 163
rules, 55
check constraints versus, 65
data filtering, 95-96
runtime errors, handling, 227-228

S
SA Login, 285, 296
sample files, installing, 27-29
SANs (Storage Area Network), 323
SAS (Serial Attached Small Computer System Interface), 322
SATA (Serial AT Attachment), 322
Save dialog box, 74
saving tables, 64
scalar functions, 253-256
advantages/disadvantages, 255-256
FullName, 253-254
GetTotalInventory, 254-255
security
authentication
logins, 280-285
ownership, 295
roles, 285-295
types of, 278-279, 296
credentials, 23
logins, 22
granting database access to logins, 284
SA Login, 285, 296
SQL Server logins, 283-284
Windows logins, 280-282
permissions validation, 299
column-level permissions, 315-316
CONTROL permissions, 318
database users, adding, 300-302
function permissions, 315
inherited/implied permissions, 300, 317
object permissions, 299, 302-309
permission statements, 302
statement permissions, 299
stored procedure permissions, 314
table permissions, 309-312
view permissions, 312-314
roles
explained, 285-286
fixed database roles, 289-292
fixed server roles, 286-288
user-defined database roles, 293-294
server roles, 22
SQL Server, 327-328, 333
stored procedures, 250
views, 188
securityadmin, 286
Security Administrators (securityadmin), 286
Security node (Management Studio). See also logins; roles
Credentials node, 23
explained, 21-22
Logins, 22
Server Roles, 22
Select Backup Devices dialog box, 28, 339-340
SELECT INTO statement, 145
Select Login dialog box, 301
Select Objects dialog box, 306-308
Select Object Types dialog box, 306-307
SELECT permissions, 310
Select Server Login or Role dialog box, 288-289
SELECT statement. See also aggregate functions
@@ functions, 231
@@Error, 219-220
explained, 216
@@Identity, 218
@@RowCount, 217
@@TranCount, 218
date and time functions, 96-98
DISTINCT keyword, 105-107, 119
EXCEPT operator, 138-139
expressions, 90-91
FOR XML clause, 107-109
FROM clause, 92
GROUP BY clause, 109-110
HAVING clause, 117-119
IN keyword, 100-101
INTERSECT, 137
NOT keyword, 100-101
ORDER BY clause, 101-102
changing sort direction, 102
syntax, 101
overview, 89
selecting all fields, 90
selecting specific fields, 90
SET NOCOUNT, 231
subqueries, 136-137
syntax, 90
TOP clause, 118-119
when to use, 103
WHERE clause, 119
data filtering rules, 95-96
IN keyword, 100-101
NOT keyword, 100-101
NULL keyword, 100
syntax, 93-94
wildcard characters, 104
Select User or Group dialog box, 282
Select Users or Roles dialog box, 303, 315-316
self-joins, 130-132
Serial AT Attachment (SATA), 322
Serial Attached Small Computer System Interface (SAS), 322
serveradmin, 286
Server Administrators (serveradmin), 286
Server Configuration step (SQL Server installation), 381-382
Server Objects node (Management Studio), 23
backup devices, 23
linked servers, 24
server triggers, 24
Server Properties dialog box
Advanced page, 330-331
Connections page, 328-329
Database Settings page, 329-330
Memory page, 324-325
Permissions page, 331-332
Processors page, 326-327
Security page, 327-328
Server Role Properties dialog box, 288
Server Roles node (Management Studio), 22
Server Roles subnode. See roles
servers
connecting to, 25-26
SQL Server. See SQL Server
server triggers, 24
SET NOCOUNT statement, 215-216, 231
SET statement, 248
setupadmin, 286
Setup Administrators (setupadmin), 286
short (constraints), 51
simple (constraints), 51
simple recovery, 336, 352
size of databases, 36
SmallDateTime data type, 49
SmallInt data type, 49
SmallMoney data type, 49
Solid State Disks (SSDs), 323-324
sort direction, changing, 102
SPACE function, 158
spaces
returning, 158
removing from strings
leading spaces, 162
trailing spaces, 163
sp_changeobjectowner stored procedure, 295
sp_changeobjectowner system-stored procedure, 295
@SQLCommand variable, 248
SQL pane (View Builder), 184
SQL Profiler, 16-17, 367-373
analyzing trace output, 372-373
creating traces, 367-372
when to use, 374
SQL Server
Activity Monitor, 25
authentication
explained, 277-278
logins, 280-285
ownership, 295
roles, 285-295
types of, 278-279, 296
Database Engine Tuning Advisor, 18-19
databases. See databases
installation, 377-382
Add Features to an Existing Installation, 379
Database Engine Configuration step, 382
Data Directories tab, 382-384
mounting ISO file, 377-378
New SQL Server Stand-alone Installation, 379-380
Ready to Install step, 382-384
Server Configuration step, 381-382
SQL Server Feature Installation step, 381
SQL Server Installation Center, 379-380
log files, 25
explained, 42
inserting data with triggers, 266-274
transaction log, 39
logins
creating, 283-284
granting database access to logins, 284
SA Login, 285, 296
SQL Server logins, 283-284
Windows logins, 280-282
Management Studio, 19
Databases node, 19-21
executing queries in, 355-358
installation, 385-386
Management node, 25
Replication node, 24-25
Security node, 21-23
Server Objects node, 23-24
performance tuning
advanced options, 330-331
connections options, 328-329
database settings, 329-330
memory options, 324-325
overview, 324
permissions options, 331-332
processor options, 326-327
security options, 327-328
Profiler, 16-17, 367-373
analyzing trace output, 372-373
creating traces, 367-372
when to use, 374
roles
explained, 285-286
fixed database roles, 289-292
fixed server roles, 286-288
user-defined database roles, 293-294
Security node, 21-23
SQL Server Agent, 17
SQL Server Database Engine, 387
versions
overview, 13
SQL Server 2014 Business Intelligence Edition, 15
SQL Server 2014 Enterprise Edition, 16
SQL Server 2014 Express, 14
SQL Server Express Edition, 30
SQL Server Standard Edition, 15
SQL Server Web Edition, 14-15
views
advantages of, 188
creating with Management Studio Query Builder, 179-185
creating with T-SQL, 185-187
explained, 177-179
security, 188
SQL Server 2014 Business Intelligence Edition, 15
SQL Server 2014 Enterprise Edition
installing
Add Features to an Existing Installation, 379
Database Engine Configuration step, 382
Data Directories tab, 382-384
mounting ISO file, 377-378
New SQL Server Stand-alone Installation, 379-380
Ready to Install step, 382-384
Server Configuration step, 381-382
SQL Server Feature Installation step, 381
SQL Server Installation Center, 379-380
overview, 16
SQL Server 2014 Express, 14
SQL Server Agent, 17
SQL Server and Windows (Mixed) authentication, 278-279, 296
SQL Server Database Engine, 387
SQL Server Express Edition, 30
SQL Server Feature Installation step (SQL Server installation), 381
SQL Server Installation Center, 379
SQL Server Login Properties dialog box, 285
SQL Server Standard Edition, 15
SQL Server Web Edition, 14-15
SQL_Variant data type, 49
SSDs (Solid State Disks), 323-324
stable (constraints), 51
Standard Edition (SQL Server), 15
Standard role, 293
statement permissions, 299
statements. See also clauses; functions; keywords
ALTER VIEW, 187
BEGIN TRANSACTION, 239
COMMIT TRANSACTION, 239
CREATE VIEW, 185-187
DECLARE CURSOR, 245
DELETE
compared to TRUNCATE, 147
explained, 146
DENY, 302, 317
DROP, 147
flow control constructs
BEGIN...END, 202
CASE, 207-209, 212
GOTO, 203-206
IF...ELSE, 200
RETURN, 203-206, 212
WHILE statement, 210-211
GRANT, 302
INSERT, 143-144
permissions, 299
ROLLBACK TRANSACTION, 239
SELECT
date and time functions, 96-98
DISTINCT keyword, 105-107, 119
EXCEPT operator, 138-139
expressions, 90-91
FOR XML clause, 107-109
FROM clause, 92
@@ functions, 216-220
GROUP BY clause, 109-110
HAVING clause, 117-119
IN keyword, 100-101
INTERSECT operator, 137
NOT keyword, 100-101
ORDER BY clause, 101-102
overview, 89
selecting all fields, 90
selecting specific fields, 90
SET NOCOUNT, 231
syntax, 90
TOP clause, 118-119
when to use, 103
WHERE clause, 93-96, 119
wildcard characters, 104
SELECT INTO, 145
SET, 248
SET NOCOUNT, 215-216, 231
TRUNCATE, 147
UPDATE, 141-142
WITH GRANT, 302, 317
stopping traces, 372
Stop Selected Trace command, 372
storage, 322-324
Storage Area Network (SANs), 323
stored procedure permissions, 314
stored procedures. See also triggers
benefits of, 191-192
compared to triggers, 10
controlling flow of
BEGIN...END construct, 202
CASE statement, 207-209, 212
GOTO statement, 203-206
IF...ELSE construct, 200-201
labels, 203-206
overview, 200
RETURN statement, 203-206, 212
WHILE statement, 210-211
creating
in Query Editor, 192-195
with T-SQL, 196
cursors, 245-249
defining, 245
looping through records with, 246-249
populating, 246
definition of term, 8
deleting data with, 237
error handling
explained, 227
returning success/failure information, 229-231
runtime errors, 227-228
executing, 197-198
inserting data with, 233-235
parameters, 221
explained, 231
input parameters, 221-225
output parameters, 225-226
permissions, 314
procEmployeeGetByTitleAndBirthDate, 221
procEmployeeGetByTitleAndBirthDateOpt, 224-225
procEmployeeGetYoungSalesReps, 221
procEmployeesGetByJobTitleAndHireDate, 244
procEmployeesGetByTitleAndBirthDateOutput, 225-226
procEmployeesGetCursor, 246
procEmployeesGetTemp, 243-244
procGetString, 247-248
procOrderDetailAdd, 234
procOrderDetailAddHandleErrors2, 229
procOrderDetailAddHandle-Errors3, 230-231
procOrderDetailAddOutput, 234
procOrderDetailAdd-Transaction, 238
procSalesOrderDetailDelete, 237
procSalesOrderDetailUpdate, 235-236
procSalesOrderHeaderUpdate, 235
returning success/failure information from, 229-231
security, 250
SET NOCOUNT statement, 215-216
sp_changeobjectowner, 295
temporary tables, 243-244
transactions, 237
implementing, 238-239
implicit versus explicit, 237-238
updating data with, 235-236
variables, 198-199
string functions, 151
LEFT, 152
LEN, 153
LOWER, 160
LTRIM, 162
REPLACE, 154
REPLICATE, 156
REVERSE, 155
RIGHT, 152-153
RTRIM, 163
SPACE, 158
STUFF, 157
SUBSTRING, 159
UPPER, 161
strings
converting to lowercase, 160
converting to uppercase, 161
determining length of, 153
extracting characters from left, 152
extracting characters from right, 152-153
extracting substrings from, 159
removing spaces from
leading spaces, 162
trailing spaces, 163
replacing
REPLACE function, 154
REPLICATE function, 156
replacing characters in, 157
returning spaces in, 158
reversing, 155
string functions, 151
LEFT, 152
LEN, 153
LOWER, 160
LTRIM, 162
REPLACE, 154
REPLICATE, 156
REVERSE, 155
RIGHT, 152-153
RTRIM, 163
SPACE, 158
STUFF, 157
SUBSTRING, 159
UPPER, 161
STUFF function, 157, 173
subqueries, 136-137
SUBSTRING function, 159
substrings, extracting, 159
success information, returning from stored procedures, 229-231
SUM function, 112-113
summarizing table data. See aggregate functions
summary statistics, calculating, 109-110
synchronization, 24
sysadmin, 286, 296
System Administrators (sysadmin), 286

T
table aliases, 92
Table Designer, 46
table permissions, 309-312
assigning, 310-312
types of, 309-310
Table Properties dialog box, 302-304
tables. See also views
adding to database diagrams, 76
aggregate functions
AVG, 113-114
COUNT function, 111
explained, 110
finding minimum values in, 114
MAX function, 115
SUM, 112-113
aliases, 92
columns, 45
adding data in, 112-113
column-level permissions, 315-316
computed columns, 57-58
constraints. See constraints
data types available, 46
explained, 5
finding maximum values in, 115
finding minimum values in, 114
identity specifications, 56
indexes, 60-62
maximum values, 115
selecting, 90
Tables and Columns specifications, 79-81
user-defined data types, 58-60
constraints. See constraints
creating, 45-46, 145
definition of term, 5-6
deleting data from
DELETE statement, 146
stored procedures, 237
TRUNCATE statement, 147
identity specifications, 56
indexes, 60-62, 362-364
inserting data into
INSERT statement, 143-144
Insert triggers, 266-268
stored procedures, 233-235
joins, 188
explained, 121
full joins, 129, 139
inner joins, 121-124
outer joins, 124-127
purpose of, 126
self-joins, 130-132
junction tables, 70
nulls, 170
COALESCE function, 172
ISNULL function, 170-171, 174
NULLIF function, 171
permissions, 309-312
assigning, 310-312
types of, 309-310
refreshing list, 64
relationships, 67
database diagrams versus, 77
Delete rule, 84-85
establishing referential integrity, 81-84
foreign key relationships, 77-81
many-to-many, 70, 87
one-to-many, 68
one-to-one, 68-69, 87
Update rule, 85-86
removing from database diagrams, 77
rows
counting, 111
deleting, 146-147, 272-274
explained, 5-6
inserting, 266-268
looping through, 246-249
updating, 269-270
saving, 64
table aliases, 92
Tables and Columns specifications, 79-81
temporary tables
stored proceudres, 243-244
when to use, 250
union queries, 133-135
updating
stored procedures, 235-236
UPDATE statement, 141-142
Update triggers, 269-270
Tables and Columns dialog box, 70, 72, 80
Tables and Columns specifications, 79-81, 86
table-valued functions
inline table-valued functions, 257-258
multi-statement table-valued functions, 258-260
TAKE OWNERSHIP permissions, 310
TempDB, 243-244
TempDB database, 21
temporary tables
stored procedures, 243-244
when to use, 250
Text data type, 49
Text page (Query Options dialog), 367
Time data type, 49
time/date functions, 96-98, 163
DATEADD, 168
DATEDIFF, 98-99, 169
DATENAME, 167
DATEPART, 98, 166, 174
DAY, 164
GETDATE, 96-97, 163
MONTH, 163
YEAR, 165
TimeStamp data type, 50
TinyInt data type, 50
toolbars, New Query, 223
TOP clause, 118-119
Top Values queries, 118-119
Trace Properties dialog box, 369-371
traces
analyzing trace output, 372-373
creating, 367-372
stopping, 372
trace window, 372-373
trace window, 372-373
trailing spaces, removing from strings, 163
@@TranCount function, 218
transaction log, 39
transactions, 237
implementing, 238-239
implicit versus explicit, 237-238
transaction log, 39
when to use, 240
triggers. See also stored procedures
compared to stored procedures, 10
creating, 263-266
Delete triggers, 272-274
Insert triggers, 266-268
syntax, 266
Update triggers, 269-270
definition of term, 10, 263, 275
disadvantages of, 274-275
modifying, 263-266
server triggers, 24
when to use, 275
TRUNCATE statement, 147
tuning performance. See performance tuning

U
underscore (_), 95, 104
union queries, 133-135
unique constraints, 56
UniqueIdentifier data type, 50
UPDATE permissions, 310
UpdatePerson trigger, 269-270
Update rule (relationships), 85-86
UPDATE statement, 141-142
Update triggers, 269-270
updating tables
stored procedures, 235-236
UPDATE statement, 141-142
Update triggers, 269-270
uppercase, converting strings to, 161
UPPER function, 161
user-defined database roles, 293-294
user-defined data types, 58-60
user-defined functions
benefits of, 9
definition of term, 9
EmpGetByTitle, 257-258
FindReports, 258-260
FullName, 253-254
GetTotalInventory, 254-255
inline table-valued functions, 257-258
multi-statement table-valued functions, 258-260
overview, 253
scalar functions, 253-256
advantages/disadvantages, 255-256
FullName, 253-254
GetTotalInventory, 254-255
users
adding, 300-302
authentication
explained, 277-278
logins, 280-285, 296
ownership, 295
roles, 285-294
types of, 278-279, 296
ownership, 295
permissions validation, 299
column-level permissions, 315-316
CONTROL permissions, 318
database users, adding, 300-302
function permissions, 315
inherited/implied
permissions, 300, 317
object permissions, 299, 302-309
permission statements, 302
statement permissions, 299
stored procedure permissions, 314
table permissions, 309-312
view permissions, 312-314

V
validating permissions. See permissions validation
values, null
COALESCE function, 172
ISNULL function, 170-171
NULLIF function, 171
VarBinary data type, 50
VarBinary(MAX) data type, 50
VarChar data type, 50
VarChar(MAX) data type, 50
variables
@AverageFreight, 209
@Country, 201
creating in stored procedures, 198-199
@Cursor, 249
global variables
@@Error, 219-220
explained, 216
@@Identity, 218
@@RowCount, 217
@@TranCount, 218
@Locale, 201
@LocalError, 239
@LocalRows, 239
@LoopText, 211
@LoopValue, 211
@return, 255
@SQLCommand, 248
versions of SQL Server
overview, 13
SQL Server 2014 Business Intelligence Edition, 15
SQL Server 2014 Enterprise Edition, 16
SQL Server 2014 Express, 14
SQL Server Express Edition, 30
SQL Server Standard Edition, 15
SQL Server Web Edition, 14-15
View Builder, 184-185
VIEW DEFINITION permissions, 310
view permissions, 312-314
View Properties dialog box, 312-313
views
advantages of, 177, 188
creating, 179
with Management Studio Query Builder, 179-185
with T-SQL, 185-187
customizing user data with, 188
definition of term, 7
explained, 177-179
indexed views, 7
modifying
with Management Studio Query Builder, 184-185
with T-SQL, 185-187
permissions, 312-314
security, 188

W
Web Edition (SQL Server), 14-15
WHERE clause, 119
data filtering rules, 95-96
IN keyword, 100-101
NOT keyword, 100-101
NULL keyword, 100
syntax, 93-94
WHILE statement, 210-211
wildcard characters, 104
Windows Administrators group, 287, 296
Windows logins, 280-282
Windows Only authentication, 278-279, 296
WITH GRANT statement, 302, 317
wizards, Maintenance Plan Wizard, 344-351
workloads, creating, 343-344

X-Y-Z
XML data type, 50
XML documents, returning data as, 107-109
xx row(s) affected message, eliminating, 215-216

YEAR function, 165


Code Snippets

You might also like