Você está na página 1de 185

O F F I C I A L

M I CRO S O F T

L EA RN I N G

PRO DU C T

2778A

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL Companion Content

Information in this document, including URL and other Internet Web site references, is subject to change without notice. Unless otherwise noted, the example companies, organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious, and no association with any real company, organization, product, domain name, e-mail address, logo, person, place or event is intended or should be inferred. Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation. Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property. The names of manufacturers, products, or URLs are provided for informational purposes only and Microsoft makes no representations and warranties, either expressed, implied, or statutory, regarding these manufacturers or the use of the products with any Microsoft technologies. The inclusion of a manufacturer or product does not imply endorsement of Microsoft of the manufacturer or product. Links may be provided to third party sites. Such sites are not under the control of Microsoft and Microsoft is not responsible for the contents of any linked site or any link contained in a linked site, or any changes or updates to such sites. Microsoft is not responsible for webcasting or any other form of transmission received from any linked site. Microsoft is providing these links to you only as a convenience, and the inclusion of any link does not imply endorsement of Microsoft of the site or the products contained therein. 2008 Microsoft Corporation. All rights reserved. Microsoft and the trademarks listed at http://www.microsoft.com/about/legal/en/us/IntellectualProperty/Trademarks/EN-US.aspx are trademarks of the Microsoft group of companies. All other marks are property of their respective owners.

Product Number: 2778A Released: 11/2008

Getting Started with Databases and Transact-SQL in SQL Server 2008

1-1

Module 1
Getting Started with Databases and Transact-SQL in SQL Server 2008
Contents:
Lesson 1: Overview of SQL Server 2008 Lesson 2: Overview of SQL Server Databases Lesson 3: Overview and Syntax Elements of T-SQL Lesson 4: Working with T-SQL Scripts Lesson 5: Using T-SQL Querying Tools Module Reviews and Takeaways Lab Review Questions and Answers 2 5 7 9 11 13 15

1-2

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 1

Overview of SQL Server 2008


Contents:
Question and Answers Additional Reading 3 4

Getting Started with Databases and Transact-SQL in SQL Server 2008

1-3

Question and Answers


Overview of Client/Server Architecture
Question: What types of Client/Server architecture systems do you use at your current organization? Answer: Answers will vary, but will include multitier web applications and two-tier client line of business applications.

1-4

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Additional Reading
Overview of Client/Server Architecture
Chapter 7 - Client/Server Architecture File-Server vs. Client/Server

SQL Server Components


Editions and Components of SQL Server 2008 Installing SQL Server 2005

SQL Server Management Tools


Editions and Components of SQL Server 2008

SQL Server Database Engine Components


SQL Server Overview Components of the SQL Server Database Engine Considerations for Installing the SQL Server Database Engine

Getting Started with Databases and Transact-SQL in SQL Server 2008

1-5

Lesson 2

Overview of SQL Server Databases


Contents:
Additional Reading 6

1-6

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Additional Reading
Overview of Relational Databases
Databases Relational Database Components Database Engine Concepts Relational Databases

What is Normalization?
Normalization SQL Database Normalization Rules

The Normalization Process


Normalization SQL Database Normalization Rules

SQL Server Database Objects


Identifiers Using Extended Properties on Database Objects Database Engine Concepts Deprecated Database Engine Features in SQL Server 2008

Overview of Data Types


Data Types (Transact-SQL)

Getting Started with Databases and Transact-SQL in SQL Server 2008

1-7

Lesson 3

Overview and Syntax Elements of T-SQL


Contents:
Additional Reading 8

1-8

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Additional Reading
A History and Definition of ANSI SQL and T-SQL
Using Common Table Expressions

Categories of SQL Statements


GRANT (Transact-SQL)

Introduction to Basic T-SQL Syntax


Query Fundamentals Transact-SQL Syntax Conventions (Transact-SQL)

Types of T-SQL Operators


Transact-SQL Reference (Transact-SQL)

What are T-SQL Functions?


Functions (Transact-SQL)

What are T-SQL Variables?


Transact-SQL Variables

What are T-SQL Expressions?


Expressions (Transact-SQL)

Control-of-flow Statements
Control-of-Flow Conditional Statement Syntax GOTO (Transact-SQL)

Getting Started with Databases and Transact-SQL in SQL Server 2008

1-9

Lesson 4

Working with T-SQL Scripts


Contents:
Additional Reading 10

1-10

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Additional Reading
What are Batch Directives?
ELSE (IF...ELSE)

Structured Exception Handling


TRY...CATCH (Transact-SQL) RAISERROR (Transact-SQL)

Commenting T-SQL Code


/*...*/ (Comment) (Transact-SQL) -- (Comment) (Transact-SQL) Using Comments

Getting Started with Databases and Transact-SQL in SQL Server 2008

1-11

Lesson 5

Using T-SQL Querying Tools


Contents:
Additional Reading 12

1-12

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Additional Reading
Tools for Querying SQL Server 2008 Databases
Query Tools bcp Utility sqlcmd Utility

An Introduction to SQL Server Management Studio


Features in SQL Server Management Studio

What is a SQL Server Solution?


Developing Solutions and Projects in SQL Server Management Studio Introduction to Solutions, Projects, and Items Introducing SQL Server Management Studio

Creating SQL Server Solutions


Introduction to Solutions, Projects, and Items How to: Create New Solutions Using Solution Explorer

Executing Queries in SQL Server Management Studio


Query Tools

Generating Reports in Microsoft Office Excel


Connect to (import) SQL Server data Use Microsoft Query to retrieve external data

Getting Started with Databases and Transact-SQL in SQL Server 2008

1-13

Module Reviews and Takeaways


Review questions
Question: What examples of a third tier client server architecture have you seen at work? Answer: An example of third tier client/server architecture would be a client that connects to a web server that connects to SQL Server 2008 for access to the data. Question: Which server management tool do we use to create optimal sets of indexes and partitions? Answer: Database Engine Tuning Advisor helps create optimal sets of indexes, indexed views, and partitions. Question: How would you quickly create graphs and reports from SQL data? Answer: Connect to the SQL database from an Excel file. Question: What are the two main parts of the relational database server? Answer: The relational database server of SQL Server has two main parts: the relational engine and the storage engine.

Best Practices related to a particular technology area in this module


Supplement or modify the following best practices for your own work situations: Formatting o o Capitalize reserve words. Code should be indented properly.

Naming Objects o Objects should be placed in square brackets. o [Customers]

Retain the case of the table names as in the database. [OrderDetails]

Include schema in object names. Sales.Customers

Use ANSI SQL Comment Code

1-14

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Tools
Tool
Microsoft SQL Server Management Studio

Use for

Where to find it

Managing SQL server Start | All Programs | Microsoft SQL Server 2008 databases and tables.

SQL Server Business Managing SQL server Start | All Programs | Microsoft SQL Server 2008 Intelligence Development applications. Studio

Getting Started with Databases and Transact-SQL in SQL Server 2008

1-15

Lab Review Questions and Answers


Question: Why would we execute a T-SQL command using SQLCMD? Answer: SQLCMD can be launched from the command line, in a script or through an application, allowing a SQL script to be launched programmatically or without the Management Studio. Question: What are the four main tools for querying SQL Server 2008 databases? Answer: SQL Server Management Studio, Microsoft Office Excel, and SQLCMD. PowerShell can also query SQL Server 2008 databases, but we did not use it in the lab. Question: How is Excel useful when querying SQL Server 2008 databases? Answer: Excel can collect large amounts of data and perform visualization, reporting, and analysis on the desktop.

Querying and Filtering Data

2-1

Module 2
Querying and Filtering Data
Contents:
Lesson 1: Using the SELECT Statement Lesson 2: Filtering Data Lesson 3: Working with NULL Values Lesson 4: Formatting Result Sets Lesson 5: Performance Considerations for Writing Queries Module Reviews and Takeaways Lab Review Questions and Answers 2 6 10 14 18 20 21

2-2

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 1

Using the SELECT Statement


Contents:
Question and Answers Detailed Demo Steps Additional Reading 3 4 5

Querying and Filtering Data

2-3

Question and Answers


Demonstration: Retrieve Data by Using the SELECT Statement
Question: Considering the two ways of requesting columns from a table, which tables in the databases you work with are probably fine for using the generic * instead of listing each column? Answer: Tables with few columns. For one time query of tables with many columns to discover any schema changes.

2-4

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Retrieve Data by Using the SELECT Statement
Demonstration steps Retrieve Data by Using the SELECT Statement
1. 2. 3. 4. 5. 6. Start the NY-SQL-01 virtual machine and login as Administrator with password Pa$$w0rd. Click Start, All Programs, Microsoft SQL Server 2008, SQL Server Management Studio, Connect. On the File menu, click Open, File and open the file: E:\MOD02\democode\SimpleQueries.sql. In the query window, highlight the code for the first example, and then click Execute. Notice that all columns are returned in the result set. In the query window, highlight the code for the second example and then click Execute. Notice that only the columns listed are now returned in the result set. Keep the VM running with SQL Server Management Studio open.

Querying and Filtering Data

2-5

Additional Reading
Elements of the SELECT Statement
Parts of a SELECT Statement Query Fundamentals

Retrieving Columns in a Table


SELECT Clause (Transact-SQL) SELECT Examples (Transact-SQL)

2-6

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 2

Using Variables
Contents:
Question and Answers Detailed Demo Steps Additional Reading 7 8 9

Querying and Filtering Data

2-7

Question and Answers


Filtering Data by Using String Comparisons
Question: When searching string data within a table which comparison do you think would be used the most? Why would this be most common? Answer: LIKE is a very common comparison operator. This is generally because part of a string is often known with other parts being variable. CONTAINS and FREETEXT are also good options for this answer. = is typically not common for string comparisons since the data has a high potential of being variable, particularly in longer string values. For short string values such as codes, = is more common. Question: In the LIKE statement, where is the appropriate location to place the % sign and why? Answer: After the first character. This will allow the SQL statement to run using and index for that column, if one is available. When the % sign is at the beginning of the criteria string, all values in that column must be compared with the criteria. Indexes are not used.

Filtering Data by Using Logical Operators


Question: In a very large table why would do you think the NOT operator might be the least efficient one to use? Answer: The NOT operator must first determine if the comparison is TRUE or FALSE and then perform additional processing to change the result to the opposite one. On queries with large row sets this can extra processing can affect performance.

2-8

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Filter Data by Using Different Search Conditions
Demonstration steps Retrieve Data by Using the SELECT Statement
1. 2. 3. 4. 5. Return to the VM and open the file: E:\MOD02\democode\FilteringQueries.sql. Highlight the code under Example 1 and then click Execute. Notice that the result set now shows only 7,493 rows. Highlight the code under Example 2 and then click Execute. Notice that only 139 orders were retrieved in the result set this time. Highlight the code under Example 3 and then click Execute. Notice that the first few rows of data as well as the number of rows retrieved. (this will be compared with the next statement) Highlight the code under Example 4 and then click Execute. Notice that this statement is equivalent to the BETWEEN statement previously executed, but uses a different WHERE clause. Note: Dates are entered as strings with the format of YYYYMMDD. 6. Leave the VM running with SQL Server Management Studio open.

Querying and Filtering Data

2-9

Additional Reading
Retrieving Specific Rows in a Table
Predicate (Transact-SQL) WHERE (Transact-SQL) Search Condition (Transact-SQL)

Filtering Data by Using Comparison Operators


Comparison Operators (Transact-SQL) Comparison Operators BETWEEN (Transact-SQL)

Filtering Data by Using String Comparisons


FREETEXT (Transact-SQL) CONTAINS (Transact-SQL) LIKE (Transact-SQL)

Filtering Data by Using Logical Operators


Logical Operators (Transact-SQL) Logical Operator Precedence

Operator Precedence
Logical Operators (Transact-SQL)

Retrieving a Range of Values


BETWEEN (Transact-SQL)

Retrieving a List of Values


IN (Transact-SQL)

2-10

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 3

Working with NULL Values


Contents:
Question and Answers Detailed Demo Steps Additional Reading 11 12 13

Querying and Filtering Data

2-11

Question and Answers


Functions to Work with NULL Values
Question: When working with data, which data types would you expect to contain NULL values? How can you determine exactly which columns in your organization's tables are allowed to have NULL values? Answer: Columns that commonly contain NULL values are those of data types: char, nchar, varchar, nvarchar, text, ntext. Numeric columns may contain NULL data, but it is not advisable. The easiest way to check column data types is to check in SQL Server Management Studio. If you do not have access to this tool then requesting the information from IT is a good idea.

Demonstration: Using Functions to Work with NULL Values


Question: Handling NULL values is a very important part of retrieving accurate data for your organization. Considering these three functions, what types of queries do you anticipate using each one for? Answer: ISNULL() queries with data that you want to check for NULL values. NULLIF() queries that you want to offer a more meaningful value in place of the NULL keyword being displayed in the result. COALESCE() Queries where NULL values may exist and you wish to substitute one of several possibilities into a column of the result set.

2-12

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Using Functions to Work with NULL Values
Demonstration steps Three useful functions for dealing with NULL values in column data.
1. 2. 3. Return to the VM, click NEW Query, and open file E:\MOD02\democode\NULLDemo.sql. Highlight the code for the first demo and click Execute. Explain that the first uses the ISNULL() function to examine the MaxQty column and returns the value 0.00 if the MaxQty column value is NULL. Point out that the first result set does not use ISNULL() and displays NULL as the column value. The second result set displays 0.00 in the rows that previously showed a NULL value. You may need to scroll down to view the second result set. Highlight the code for the second demo and click Execute. In this result set point out that the NULLIF() function assigned a NULL value in the Null if Equal column for those rows that have the same value in the MakeFlag and FinishedGoodsFlag columns. It also shows the value of the MakeFlag column if the two columns do not have the same value. Highlight the code for the third example and click Execute. Note that the COALESCE() function will look at the value of each argument listed and return the value of the first argument that does not have a NULL value. Note that the Total Salary column is populated with data based on the following criteria in the COALESCE() function: If the hourly_wage column has a value Total Salary has a calculated value based on the hourly_wage * 40 hours * 52 weeks. If the salary column is not NULL the value of the salary column is displayed in Total Salary. If the commission column is not NULL the value displayed in Total Salary is equal to commission * num_sales. 8. Keep the VM running and SQL Management Studio open.

4. 5.

6.

7.

Querying and Filtering Data

2-13

Additional Reading
Considerations for Working with NULL Values
Null Values Using Sparse Columns

Functions to Work with NULL Values


Null Values ISNULL (Transact-SQL) NULLIF (Transact-SQL) COALESCE (Transact-SQL)

2-14

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 4

Formatting Result Sets


Contents:
Question and Answers Detailed Demo Steps Additional Reading 15 16 17

Querying and Filtering Data

2-15

Question and Answers


Eliminating Duplicate Rows
Question: Knowing that DISTINCT processes only those columns returned in the result set, are there situations where these results may not reflect an accurate representation of unique data? Answer: Because DISTINCT only looks at the result set it will only evaluate the rows and columns that are present. If any of the data would be considered duplicate based on columns that are not in the select list, these columns will not be taken into consideration.

Using Expressions
Question: The above examples show how expressions can be used. What other ways do think you will use expressions to create queries? Answer: They can be used as possible values in comparisons, static values in derived columns, static values in concatenated columns.

Demonstration: Format Result Sets


Question: Formatting the result sets helps the reader interpret the data. What other reasons are there for creating result sets with a specific formatting? Answer: Hide or display data based on user information for security reasons. Hide or display data based on parameter values.

2-16

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Demonstration: Format Result Sets
Demonstration steps
1. 2. Return to the VM and click New Query, open E:\MOD02\democode\ResultSetFormatting.sql. Highlight the code for the first example and click Execute. Notice that on the first result set the original column name is used for the heading label, but on the second result set the more meaningful string Employee Identification Number that was specified in the second query has become the column header. Highlight the code for the second example and click Execute. Notice that the first querys select list has the LastName, FirstName, and MiddleName fields listed separately. This results in all three columns appearing in the first result set. By using the concatenation functionality of Transact-SQL you can join the three columns together into one derived column and insert commas and spaces to put the name into a more readable format. 4. Highlight the code for the third example and click Execute. Notice that the first query creates a derived column called NewPrice which is equal to the ListPrice + 10%, and the WHERE clause requires that the result set only show those items with at lease a 20% margin. If you click in the top result set you can see that this result set has 304 rows (may be different in each database). In the second result set you have the same columns, but only shows the 98 rows (may vary) with a SellEndDate that is earlier than todays date. Close SQL Server Management Studio and discard changes. Close the VM and discard changes.

3.

5. 6. 7. 8.

Querying and Filtering Data

2-17

Additional Reading
Sorting Data
ORDER BY Clause (Transact-SQL) Sorting Rows with ORDER BY

Eliminating Duplicate Rows


Eliminating Duplicates with DISTINCT

Labeling Columns in Result Sets


Using Table Aliases Assigning Result Set Column Names

Using String Literals


SUBSTRING (Transact-SQL) + (String Concatenation) (Transact-SQL)

Using Expressions
+ (String Concatenation) (Transact-SQL) Functions (Transact-SQL) Derived Column Transformation

2-18

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 5

Performance Considerations for Writing Queries


Contents:
Additional Reading 19

Querying and Filtering Data

2-19

Additional Reading
How SQL Server Processes Transact-SQL Queries
SQL Statement Processing Query Performance Query Tuning Recommendations

Tips on Creating More Efficient Queries


Query Processing -- introduction to the blog! Troubleshooting Queries Troubleshooting Poor Query Performance: Cardinality Estimation Pattern Matching in Search Conditions Analyzing a Query

Solutions for Query Optimization


Troubleshooting Poor Query Performance: Cardinality Estimation Checklist for Analyzing Slow-Running Queries

2-20

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Module Reviews and Takeaways


Review questions
Question: When creating a WHERE clause by entering search conditions that include column data, what do you need to consider to help the query optimizer create the lowest cost execution plan? Why or how do these make a difference? Answer: Placement of wildcards after the first character will allow the use of indexes. Avoid using the asterisk in the SELECT list. Avoid using NOT in conditions when possible. Use constants instead of expressions or calculations for comparisons. Question: NULL values are present in many databases, usually by design. What can you do to discover where NULL values may be stored? Why is it important to know where NULL values can be encountered? Answer: The easiest method is to examine the table schema in SQL Server Management Studio and note the columns that allow NULL values. Alternatively, you can obtain the schema from IT.

Real-world Issues and Scenarios


Question: The DB Administrator has added a new column to the Person.Person table and you are asked to include this column in all queries and reports. But when you use the column in an expression in a search condition, few if any rows are returned. What is a likely cause? What can you do to help solve the issue? Answer: The cause is most likely that the columns allow NULL values and have not been populated. To solve the issue the COALESCE() and ISNULL() functions can be used to replace NULL values in the query output. Question: You are asked to quickly create a report on a table with a large number of data rows in it. When writing the query, what are some things you can do to help the system retrieve the required rows as quickly as possible? Answer: Use indexed columns in the WHERE clause. Only list the required columns in the SELECT list. Do not use calculations against column values in the WHERE clause. Do not use NOT in comparisons.

Querying and Filtering Data

2-21

Lab Review Questions and Answers


Question: Using the * to designate all columns in a table for display is useful when you dont know the table schema. What issues can arise when using the *, and what else can you use instead? Answer: Using an asterisk returns all columns in the row. Some of the columns may contain large amounts of data, or even unreadable data, thus cluttering the output. Performance of the query can also be adversely affected if some of the columns contain large binary data. Instead of using the * you should list specific column names in the SELECT list. Question: When a column in your query can contain NULL values you may get unexpected results in the data set. What are some of the techniques that can be used to ensure that all of the expected data is listed? Answer: NULL values are considered undefined values. This means that any attempt to directly use columns with NULL values will not return expected results. o o o Calculations will return undefined values. Rows of data may not be in the data set. Concatenated columns will be returned as blank in the data set.

The following functions can be used to accommodate NULL values: o o ISNULL() will replace a NULL value with a given value in the data set. COALESCE() allows you to designate a number of values that can be substituted for NULL values. Each column or value listed is tested for a NULL value and the first one to not have a NULL value is used in the data set. IS NULL is used to test for NULL values in a column in the WHERE clause.

Question: When performing string comparisons on a column you can use LIKE, CONTAINS, and FREETEXT. What are the differences and when would each be best used? Answer: LIKE uses wildcards to search for partial matches in text columns. LIKE is best used when the strings are relatively short and spelling is the main consideration for the search. CONTAINS uses a word or list of words to search strings in a column. CONTAINS is best used for larger columns and when derivatives of the word are also desired such as drive, drove, driving, and driven. FREETEXT uses a word or list of words on large text data that has been indexed using Full Text indexing. FREETEXT also allows you to search for derivatives of the word or words in the list.

Grouping and Summarizing Data

3-1

Module 3
Grouping and Summarizing Data
Contents:
Lesson 1: Summarizing Data by Using Aggregate Functions Lesson 2: Summarizing Grouped Data Lesson 3: Ranking Grouped Data Lesson 4: Creating Crosstab Queries Module Reviews and Takeaways Lab Review Questions and Answers 2 6 10 13 15 16

3-2

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 1

Summarizing Data by Using Aggregate Functions


Contents:
Question and Answers Detailed Demo Steps Additional Reading 3 4 5

Grouping and Summarizing Data

3-3

Question and Answers


Using Aggregate Functions With NULL Values
Question: Why is it important to be aware of and handle NULL values in aggregate functions? Answer: Since most of the aggregate functions ignore NULL values when performing their calculations, it can introduce errors into your output if the NULL values are handled incorrectly. When using SUM, the NULL values will be treated as zero and thus should be ok. But if you are using the AVG or COUNT functions your results will not be correct. Use the featured ISNULL example to correctly handle these cases.

Implementing Custom Aggregate Functions


Question: Why use a custom aggregation function if you're comfortable with handling the logic in TSQL? Answer: The custom aggregate will execute faster as it is compiled code (T-SQL is interpreted) and may also simplify queries by making them easier to read and understand, thus easing query maintenance.

Demonstration: Using Common Aggregate Functions


Question: What would be the best aggregate function to use when counting records in a table? Answer: The COUNT function. Question: How can you restrict one of the sample queries in this demo to only account for a certain range of employees? Answer: Add a WHERE clause to the query.

3-4

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Using Common Aggregate Functions
Demonstration steps
Create a new query in SQL Server Management Studio. Make sure the current database is set to AdventureWorks2008 Enter and then run the following query to produce a count of the employees in the system: o SELECT COUNT(*) FROM HumanResources.Employee;

Enter and then run the following query to calculate the average number of vacation hours each employee has: o SELECT AVG(VacationHours) FROM HumanResources.Employee;

Enter and then run the following query to calculate the maximum number of vacation hours held by an employee: o SELECT MAX(VacationHours) FROM HumanResources.Employee;

Enter and then run the following query to calculate the total number of vacation hours held by employees: o SELECT SUM(VacationHours) FROM HumanResources.Employee;

Grouping and Summarizing Data

3-5

Additional Reading
Using Aggregate Functions Native to SQL Server
Summarizing Data Deterministic and Nondeterministic Functions Aggregate Functions

Using Aggregate Functions With NULL Values


Aggregate Functions (Transact-SQL) COUNT (Transact-SQL)

CLR Integration, Assemblies


Common Language Runtime (CLR) Integration Programming Concepts

Implementing Custom Aggregate Functions


CREATE AGGREGATE (Transact-SQL) CLR User-Defined Aggregates Invoking CLR User-Defined Aggregate Functions

3-6

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 2

Summarizing Grouped Data


Contents:
Question and Answers Detailed Demo Steps Additional Reading 7 8 9

Grouping and Summarizing Data

3-7

Question and Answers


Using the GROUP BY Clause
Question: Why might you want to group results is this absolutely necessary? Answer: Grouping data, and by extension the GROUP BY clause, is one of the most fundamental concepts in Transact SQL. It is through this clause that the query processor knows how to process your aggregation functions on groups of data and not an entire table. Without GROUP BY it would be impossible to generate summary information on any level other than that of a table level.

Filtering Grouped Data by Using the HAVING Clause


Question: Are HAVING and WHERE essentially the same? Answer: The HAVING and WHERE clauses are similar but not the same. HAVING behaves like a WHERE but applies to groups as a whole whereas the WHERE clause applies to individual rows. It is only when a GROUP BY is not used that HAVING is behaves like a WHERE clause. In this case, since performance will be identical, you should probably use the language construct that makes it the most clear what you are doing.

Demonstration: How to Use the ROLLUP and CUBE Operators


Question: What could be some determining factors on whether you chose to use a ROLLUP vs. a CUBE query? Answer: A quick factor may be the handling of NULL values as each operator handles them a bit differently.

Building a Query for Summarizing Grouped Data - COMPUTE


Question: What advantages does using the COMPUTE statement provide? Answer: There can be several advantages. One clear advantage is summary information at different levels can be returned in a single call instead of multiple calls.

3-8

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: How to Use the ROLLUP and CUBE Operators
Demonstration steps
Create a new query in SQL Server Management Studio. Make sure the current database is set to AdventureWorks2008 Enter and then run the following ROLLUP query:
o USE AdventureWorksDW2008; GO SELECT ProductKey, OrderDateKey, DueDateKey, ShipDateKey, SUM (SalesAmount) AS [Sales] FROM dbo.FactInternetSales GROUP BY ROLLUP(ProductKey, OrderDateKey, DueDateKey, ShipDateKey);

Enter and then run the following CUBE query:


o USE AdventureWorksDW2008;

GO SELECT ProductKey, OrderDateKey, DueDateKey, ShipDateKey,SUM (SalesAmount) AS [Sales] FROM dbo.FactInternetSales GROUP BY CUBE(ProductKey, OrderDateKey, DueDateKey, ShipDateKey);

Grouping and Summarizing Data

3-9

Additional Reading
Using the GROUP BY Clause
GROUP BY (Transact-SQL)

Filtering Grouped Data by Using the HAVING Clause


HAVING (Transact-SQL)

Building a Query for Summarizing Grouped Data - GROUP BY


GROUP BY (Transact-SQL)

Examining how the ROLLUP and CUBE Operators Work


GROUP BY (Transact-SQL)

Using the ROLLUP and CUBE Operators


GROUP BY (Transact-SQL)

Examining the COMPUTE and COMPUTE BY Clauses


COMPUTE (Transact-SQL)

Building a Query for Summarizing Grouped Data - COMPUTE


COMPUTE (Transact-SQL)

Using GROUPING SETS


GROUP BY (Transact-SQL) GROUPING SETS Equivalents

3-10

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 3

Ranking Grouped Data


Contents:
Question and Answers Additional Reading 11 12

Grouping and Summarizing Data

3-11

Question and Answers


Categorizing the Ranking Functions Based on Their Functionality
Question: What ranking function would be most useful in ranking the teams in a sports league where you dont want gaps in the rankings? Answer: DENSE_RANK.

3-12

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Additional Reading
What is Ranking?
Ranking Functions (Transact-SQL) Over Clause (Transact-SQL)

Ranking Data by Using RANK


RANK (Transact-SQL)

Ranking Data by Using DENSE_RANK


DENSE_RANK (Transact-SQL)

Ranking Data by Using ROW_NUMBER


ROW_NUMBER (Transact-SQL)

Ranking Data by Using NTILE


NTILE (Transact-SQL)

Categorizing the Ranking Functions Based on Their Functionality


Ranking Functions (Transact-SQL)

Grouping and Summarizing Data

3-13

Lesson 4

Creating Crosstab Queries


Contents:
Additional Reading 14

3-14

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Additional Reading
How the PIVOT and UNPIVOT Operators Work
Using PIVOT and UNPIVOT

Using the PIVOT Operator


Using PIVOT and UNPIVOT

Using the UNPIVOT Operator


Using PIVOT and UNPIVOT

Grouping and Summarization Features New to SQL Server 2008


SQL Server Overview

Grouping and Summarizing Data

3-15

Module Reviews and Takeaways


Review questions
Question: Which of the built in aggregate functions does not ignore NULL values? Answer: The COUNT(*) statement Question: The HAVING clause is very similar to the WHERE clause with one notable difference. What is the difference? Answer: HAVING filters after the SELECT but before the results are returned. WHERE filters in the SELECT. Question: Which ranking function would be appropriate for a sports league rankings query? Answer: RANK, because ties are present, with gaps between tied ranks. Question: Creating cross tab queries is probably one of the most common uses for what operator? Answer: The PIVOT operator.

3-16

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lab Review Questions and Answers


Question: When you execute queries with aggregate functions you may see a warning message Null value is eliminated by an aggregate or other SET operation. Why do you get this? Answer: The server returns this warning as a convenience, letting you know that null values were not respected by your operation. This could potentially save you some debugging time later if you were not expecting the null value elimination. Other exercises in the lab show you how to explicitly eliminate null values from your queries. Question: When executing your query you receive the error Column xyz is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. What did you forget to do? Answer: This error occurs most frequently when you forget to include columns in the select list that arent used with aggregates into the GROUP BY clause. Question: When ranking the salespersons into four categories based on their year to date sales, were the amount of results in each category even? Why or why not? Answer: If the number of rows in a category is not divisible by number of categories, the size of the groups will differ by one member. Additionally, the larger group will come before the others.

Joining Data from Multiple Tables

4-1

Module 4
Joining Data from Multiple Tables
Contents:
Lesson 1: Querying Multiple Tables by Using Joins Lesson 2: Applying Joins for Typical Reporting Needs Lesson 3: Combining and Limiting Result Sets Module Reviews and Takeaways Lab Review Questions and Answers 2 6 10 14 16

4-2

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 1

Querying Multiple Tables by Using Joins


Contents:
Question and Answers Detailed Demo Steps Additional Reading 3 4 5

Joining Data from Multiple Tables

4-3

Question and Answers


Demonstration: Querying a Table Using Joins
Question: When would it make sense to use an outer join instead of an inner join? Answer: When you need to return all rows from at least one of the tables or views mentioned in the FROM clause instead of eliminating rows as an inner join would do. Question: Can you think of any scenarios in which you would use a cross join? Answer: If you want to run a query that will return data for every month, for example, even on customers that had no orders that particular month, you could use a Cartesian product to get that data.

4-4

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Querying a Table Using Joins
Demonstration steps
Start SQL Server Management Studio and, using the AdventureWorks2008 database, perform each of the queries found in E:\MOD04\Democode\QueryingWithJoins.sql.

Joining Data from Multiple Tables

4-5

Additional Reading
Fundamentals of Joins
PRIMARY KEY Constraints FOREIGN KEY Constraints

Categorizing Statements by Types of Joins


Using Joins

4-6

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 2

Applying Joins for Typical Reporting Needs


Contents:
Question and Answers Detailed Demo Steps Additional Reading 7 8 9

Joining Data from Multiple Tables

4-7

Question and Answers


Demonstration: Joining Tables
Question: What is a translation (or intermediate) table and what is it used for? Answer: A translation (or intermediate) table is the middle table in a join when you are joining three or more tables. Question: When does it make sense to use a non-equi join? Answer: As a general rule, not-equal joins make sense only when used with a self-join.

4-8

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Joining Tables
Demonstration steps
Using the AdventureWorks2008 database, perform each of the queries found in E:\MOD04\Democode\JoiningTables.sql.

Joining Data from Multiple Tables

4-9

Additional Reading
Joining Tables in a User-Defined Function
Views

4-10

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 3

Combining and Limiting Result Sets


Contents:
Question and Answers Detailed Demo Steps Additional Reading 11 12 13

Joining Data from Multiple Tables

4-11

Question and Answers


Limiting Result Sets by Using the TOP and TABLESAMPLE Operators
Question: When would you use TOP to limit a result set? Answer: Sometimes you want to determine how many rows are returned by a query, for example in a table that contains dates you may only want to return some number or percentage of the most recent rows added or modified. You can use the TOP clause to do this. Question: When would you use TABLESAMPLE to limit a result set? Answer: Whenever you need a truly random sample of data from your database, such as in some data mining applications where you need a sampling mechanism, you can use TABLESAMPLE. With TABLESAMPLE you are able to get a sample set of data without having to sift through the database manually.

Demonstration: Combining and Limiting Result Sets


Question: What are the basic rules for combining the result sets of two queries by using UNION? Answer: The following are basic rules for combining the result sets of two queries by using UNION: The number and the order of the columns must be the same in all queries. The data types must be compatible.

Question: How do you think rows are returned from a SELECT TOP statement that also has an ORDER BY clause? Answer: If a SELECT statement that includes TOP also has an ORDER BY clause, the rows to be returned are selected from the ordered result set. The whole result set is built in the specified order and the top n rows in the ordered result set are returned. Question: What conditions must be met in order to use TABLESAMPLE to return a sample from a large table? Answer: You can use TABLESAMPLE to quickly return a sample from a large table when either of the following conditions is true: The sample does not have to be a truly random sample at the level of individual rows. Rows on individual pages of the table are not correlated with other rows on the same page.

4-12

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Combining and Limiting Result Sets Demonstration steps
Demo Steps
1. 2. Prepare the AdventureWorks2008 database using the query found at E:\MOD04\Democode\PrepareResultSets.sql. Using the AdventureWorks2008 database, perform each of the queries found in E:\MOD04\Democode\ResultSets.sql.

Joining Data from Multiple Tables

4-13

Additional Reading
Limiting Result Sets by Using the EXCEPT and INTERSECT Operators
Collation Precedence (Transact-SQL)

4-14

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Module Reviews and Takeaways


Review questions
Question: How does a join condition define the way two tables are related in a query? Answer: By specifying the column from each table to be used for the join or by specifying a logical operator (for example, = or <>,) to be used in comparing values from the columns. Question: How can multiple join operators be combined in the same statement? Answer: The join expressions can be connected using the AND or OR operators. Question: What options are available to the TABLESAMPLE clause and what are they used for? Answer: SYSTEM and REPEATABLE. SYSTEM returns an approximate percentage of rows and generates a random value for each physical 8-KB page in the table. REPEATABLE causes a selected sample to be returned again.

Best Practices related to using Joins


Supplement or modify the following best practices for your own work situations: Specifying the join conditions in the FROM clause helps separate them from any other search conditions that may be specified in a WHERE clause, and is the recommended method for specifying joins. Columns used in a join condition are not required to have the same name or be the same data type. However, if the data types are not identical, they must be compatible, or be types that SQL Server can implicitly convert. To retain the non-matching information by including non-matching rows in the results of a join, use a full outer join. SQL Server provides the full outer join operator, FULL OUTER JOIN, which includes all rows from both tables, regardless of whether or not the other table has a matching value.

Best Practices related to using the UNION operator


Supplement or modify the following best practices for your own work situations: All select lists in the statements that are being combined with UNION must have the same number of expressions (column names, arithmetic expressions, aggregate functions, and so on). Corresponding columns in the result sets that are being combined with UNION, or any subset of columns used in individual queries, must be of the same data type, have an implicit data conversion possible between the two data types, or have an explicit conversion supplied. For example, a UNION between a column of datetime data type and one of binary data type will not work unless an explicit conversion is supplied. However, a UNION will work between a column of money data type and one of int data type, because they can be implicitly converted. Corresponding result set columns in the individual statements that are being combined with UNION must occur in the same order, because UNION compares the columns one-to-one in the order given in the individual queries.

Joining Data from Multiple Tables

4-15

Best Practices related to using the EXCEPT and INTERSECT operators


Supplement or modify the following best practices for your own work situations: The definitions of the columns that are part of an EXCEPT or INTERSECT operation do not have to be the same, but they must be comparable through implicit conversion. The query specification or expression cannot return xml, text, ntext, image, or nonbinary CLR user-defined type columns because these data types are not comparable.

4-16

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lab Review Questions and Answers


Question: What results did the Inner Join in Exercise 1 return? Answer: All the columns in both tables, and returns only the rows for which there is an equal value in the join column. Question: What results did the Left Outer Join and Right Outer Join in Exercise 1 return? Answer: The Left Outer Join included all rows in the Product table in the results, whether or not there was a match on the ProductID column in the ProductReview table. The Right Outer Join returned all sales persons in the results, regardless of whether they are assigned a territory. Question: Why was the ProductVendor table given two different table aliases in the FROM clause of Exercise 2? Answer: Because the ProductVendor table appears in two roles and those aliases were used to qualify the column names in the rest of the query. Question: What would happen if we added an ORDER BY clause to the TOP select statement in Exercise 3? Answer: The rows to be returned would be selected from the ordered result set instead of from the standard, unordered result set.

Working with Subqueries

5-1

Module 5
Working with Subqueries
Contents:
Lesson 1: Writing Basic Subqueries Lesson 2: Writing Correlated Subqueries Lesson 3: Comparing Subqueries with Joins and Temporary Tables Lesson 4: Using Common Table Expressions Module Reviews and Takeaways Lab Review Questions and Answers 2 6 9 11 15 16

5-2

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 1

Writing Basic Subqueries


Contents:
Question and Answers Detailed Demo Steps Additional Reading 3 4 5

Working with Subqueries

5-3

Question and Answers


Demonstration: Writing Basic Subqueries
Question: How would you rewrite the basic subquery demonstrated to you here as a join? Answer:
SELECT Prd1.Name FROM Production.Product AS Prd1 JOIN Production.Product AS Prd2 ON WHERE Prd2. Name = 'Freewheel' (Prd1.ListPrice = Prd2.ListPrice)

Question: What results were returned by the SELECT statement that contained an ANY expression and why? Answer: The products whose list prices are greater than or equal to the maximum list price of any product subcategory.

5-4

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Writing Basic Subqueries
Demonstration steps
Start SQL Server Management Studio and, using the AdventureWorks2008 database, perform each of the queries found in E:\MOD05\Democode\WritingBasicSubqueries.sql.

Working with Subqueries

5-5

Additional Reading
What are Subqueries?
ALL (Transact-SQL) SOME | ANY (Transact-SQL)

Scalar versus Tabular Subqueries


Craig Freedman's SQL Server Blog: Scalar Subqueries

5-6

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 2

Writing Correlated Subqueries


Contents:
Question and Answers Detailed Demo Steps 7 8

Working with Subqueries

5-7

Question and Answers


Demonstration: Writing Correlated Subqueries
Question: What is the process behind building a correlated subquery? Answer: 1. 2. 3. 4. 5. Outer query passes column values to the inner query. Inner query uses that value to satisfy the inner query. Inner query returns a value back to the outer query. The process is repeated for the next row of the outer query. Go back to step 1 and repeat.

Question: What results did the correlated subqueries return? Answer: Sales where the quantity is less than the average quantity for sales of that product.

5-8

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Writing Correlated Subqueries
Demonstration steps
Start SQL Server Management Studio and, using the AdventureWorks2008 database, perform each of the queries found in E:\MOD05\Democode\WritingCorrelatedSubqueries.sql.

Working with Subqueries

5-9

Lesson 3

Comparing Subqueries with Joins and Temporary Tables


Contents:
Additional Reading 10

5-10

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Additional Reading
Temporary Tables
table (Transact-SQL)

Working with Subqueries

5-11

Lesson 4

Using Common Table Expressions


Contents:
Question and Answers Detailed Demo Steps Additional Reading 12 13 14

5-12

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Question and Answers


Demonstration: Using Common Table Expressions
Question: In the first demonstration, how many times was the CTE referenced when the statement was executed and why? Answer: When the statement was executed, the CTE was referenced two times: one time to return the selected columns for the salesperson, and again to retrieve similar details for the salesperson's manager. The data for both the salesperson and the manager were returned in a single row. Question: What would happen if you created a recursive CTE that returned the same values for both the parent and child columns? Answer: You would create an infinite loop. Note that, when testing the results of a recursive query, you can limit the number of recursion levels allowed for a specific statement by using the MAXRECURSION hint and a value between 0 and 32,767 in the OPTION clause of the INSERT, UPDATE, DELETE, or SELECT statement.

Working with Subqueries

5-13

Detailed Demo Steps


Demonstration: Using Common Table Expressions
Demonstration steps
Start SQL Server Management Studio and, using the AdventureWorks2008 database, perform each of the queries found in E:\MOD05\Democode\Sales_CTE.sql and then E:\MOD05\Democode\ProductBOM.sql.

5-14

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Additional Reading
Writing Recursive Queries by Using Common Table Expressions
Recursive Queries Using Common Table Expressions

Working with Subqueries

5-15

Module Reviews and Takeaways


Review questions
Question: A subquery nested in the outer SELECT statement has what components? Answer: A regular SELECT query including the regular select list components, a regular FROM clause including one or more table or view names, an optional WHERE clause, an optional GROUP BY clause, and an optional HAVING clause. Question: What clauses can the SELECT query of a subquery include? What clauses can it not include? Answer: The SELECT query of a subquery cannot include a COMPUTE or FOR BROWSE clause, and may only include an ORDER BY clause when a TOP clause is also specified. Question: What are the three basic types of subqueries? Answer: Those that operate on lists introduced with IN, or those that a comparison operator modified by ANY or ALL; those that are introduced with an unmodified comparison operator and must return a single value; those that are existence tests introduced with EXISTS..

Best Practices related to Subqueries with EXISTS


Supplement or modify the following best practices for your own work situations: Subqueries that are introduced with EXISTS are a bit different from other subqueries in the following ways: o o The keyword EXISTS is not preceded by a column name, constant, or other expression. The select list of a subquery introduced by EXISTS almost always consists of an asterisk (*). There is no reason to list column names because you are just testing whether rows that meet the conditions specified in the subquery exist.

The EXISTS keyword is important because frequently there is no alternative, nonsubquery formulation. Although some queries that are created with EXISTS cannot be expressed any other way, many queries can use IN or a comparison operator modified by ANY or ALL to achieve similar results.

5-16

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lab Review Questions and Answers


Question: How are basic subqueries evaluated? Answer: By executing the subquery once and substituting the resulting value or values into the WHERE clause of the outer query. Question: How are correlated subqueries evaluated? Answer: These subqueries depends on the query for their values. This means that the subquery is executed repeatedly, once for each row that might be selected in the outer query. Question: What could a Common Table Expression be used for? Answer: Creating a recursive query, substituting for a view when the general use of a view is not required, enabled grouping by a column that is derived from a scalar subselect, or referencing the resulting table multiple times in the same statement.

Modifying Data in Tables

6-1

Module 6
Modifying Data in Tables
Contents:
Lesson 1: Inserting Data into Tables Lesson 2: Deleting Data from Tables Lesson 3: Update Data in Tables Lesson 4: Overview of Transactions Module Reviews and Takeaways Lab Review Questions and Answers 2 6 10 14 18 20

6-2

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 1

Inserting Data into Tables


Contents:
Question and Answers Detailed Demo Steps Additional Reading 3 4 5

Modifying Data in Tables

6-3

Question and Answers


Demonstration: Inserting Data into Tables
Question: Why is the VALUES clause used when appending data into a table? Answer: Because you have to insert an explicit value in the IDENTITY column for SQL Server to increment. Question: Under what circumstances must the column_list portion of the INSERT statement be defined? Answer: column_list and VALUES list must be used when explicit values are inserted into an identity column, and the SET IDENTITY_INSERT option must be ON for the table.

6-4

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Inserting Data into Tables
Demonstration steps
Start SQL Server Management Studio and, using the AdventureWorks2008 database, perform each of the queries found in E:\MOD06\Democode\InsertingDataIntoTables.sql.

Modifying Data in Tables

6-5

Additional Reading
INSERT Fundamentals
INSERT (Transact SQL)

INSERT Statement Definitions


Adding Rows by Using INSERT and SELECT

INSERT Statement Examples


INSERT (Transact SQL)

Inserting Values into Identity Columns


INSERT (Transact SQL) OUTPUT Clause (Transact-SQL)

Using the OUTPUT Clause with the INSERT Statement


INSERT (Transact SQL) OUTPUT Clause (Transact-SQL)

6-6

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 2

Deleting Data from Tables


Contents:
Question and Answers Detailed Demo Steps Additional Reading 7 8 9

Modifying Data in Tables

6-7

Question and Answers


Demonstration: Deleting Data from Tables
Question: Why should you use the TRUNCATE statement? Answer: The TRUNCATE TABLE statement is a fast, efficient method of deleting all rows in a table. Question: How can you completely remove a table from a database? Answer: Both the DELETE and TRUNCATE statements delete only rows from the table; the table must be removed from the database by using the DROP TABLE statement.

6-8

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Deleting Data from Tables
Demonstration steps
Start SQL Server Management Studio and, using the AdventureWorks2008 database, perform each of the queries found in E:\MOD06\Democode\DeletingDataFromTables.sql.

Modifying Data in Tables

6-9

Additional Reading
Delete Fundamentals
DELETE (Transact-SQL)

DELETE Statement Definitions


DELETE (Transact-SQL)

Defining and Using the TRUNCATE Statement


TRUNCATE TABLE (Transact-SQL)

TRUNCATE versus DELETE


TRUNCATE TABLE (Transact-SQL)

DELETE and the OUTPUT Clause


DELETE (Transact-SQL) OUTPUT Clause (Transact-SQL)

6-10

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 3

Update Data in Tables


Contents:
Question and Answers Detailed Demo Steps Additional Reading 11 12 13

Modifying Data in Tables

6-11

Question and Answers


Demonstration: Updating Data in Tables
Question: What are the major clauses of the UPDATE statement and what do they do? Answer: SET, FROM, and WHERE. Definitions of these clauses are available on slide 19 of this slide deck. Question: How would you write an UPDATE statement to increase the price of all products on a table by 10 percent? Answer: You would use the TOP clause with a (10) PERCENT argument, such as in the following:
UPDATE TOP (10) PERCENT Production.Product SET ListPrice = ListPrice * 1.1

6-12

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Updating Data in Tables
Demonstration steps
Start SQL Server Management Studio and, using the AdventureWorks2008 database, perform each of the queries found in E:\MOD06\Democode\UpdatingDataInTables.sql.

Modifying Data in Tables

6-13

Additional Reading
UPDATE Fundamentals
UPDATE (Transact-SQL) Changing Data by Using UPDATE

UPDATE Statement Definitions


Changing Data by Using the SET Clause Changing Data by Using the FROM Clause Changing Data by Using the WHERE Clause

Updating with Information from another Table


UPDATE (Transact-SQL)

UPDATE and the OUTPUT Clause


UPDATE (Transact-SQL) OUTPUT Clause (Transact-SQL)

6-14

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 4

Overview of Transactions
Contents:
Question and Answers Detailed Demo Steps Additional Reading 15 16 17

Modifying Data in Tables

6-15

Question and Answers


Demonstration: Creating a Transaction
Question: How can a transaction be rolled back and when would you want to roll a transaction back? Answer: If errors are encountered, all data modifications made after the BEGIN TRANSACTION can be rolled back using the ROLLBACK TRANSACTION statement to return the data to this known state of consistency. Each transaction lasts until either it completes without errors and COMMIT TRANSACTION is issued to make the modifications a permanent part of the database, or errors are encountered and all modifications are erased with a ROLLBACK TRANSACTION statement.

Demonstration: Setting Transaction Isolation Levels


Question: How long does SQL Server hold a shared lock created by the SET TRANSACTION ISOLATION LEVEL statement? Answer: For each Transact-SQL statement that follows, SQL Server holds all of the shared locks until the end of the transaction.

Demonstration: Using Nested Transactions


Question: What did the SELECT statement indicate to you? Answer: This indicates that the commit of the inner transaction from the transaction OutOfProc was overridden by the subsequent rollback.

6-16

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Creating a Transaction
Demonstration steps
Start SQL Server Management Studio and, using the AdventureWorks2008 database, perform each of the queries found in E:\MOD06\Democode\CreatingATransaction.sql.

Demonstration: Setting Transaction Isolation Levels


Demonstration steps
Start SQL Server Management Studio and, using the AdventureWorks2008 database, perform each of the queries found in E:\MOD06\Democode\SettingTIL.sql.

Demonstration: Demonstration: Using Nested Transactions


Demonstration steps
1. 2. Start SQL Server Management Studio and, using the AdventureWorks2008 database, perform each of the queries found in E:\MOD06\Democode\UsingNestedTransactions.sql. Refresh AdventureWorks2008 | Programmability | Stored Procedures to view the new dbo.TransProc procedure created by using Nested Transactions.

Modifying Data in Tables

6-17

Additional Reading
Transaction Fundamentals
Transactions (Database Engine) Distributed Transactions (Database Engine)

Transactions and the Database Engine


Write-Ahead Transaction Log Checkpoints and the Active Portion of the Log

Basic Transaction Statement Definitions


BEGIN TRANSACTION (Transact-SQL) COMMIT TRANSACTION (Transact-SQL) SET XACT_ABORT (Transact-SQL) TRY...CATCH (Transact-SQL) Using TRY...CATCH in Transact-SQL

What are Transaction Isolation Levels?


Isolation Levels in the Database Engine

Using Nested Transactions


Nesting Transactions

6-18

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Module Reviews and Takeaways


Review questions
Question: What are the four properties of a logical unit of work? Answer: ACID - atomicity, consistency, isolation, and durability. Question: How can the INSERT and SELECT statements be used to add rows to a table? Answer: Use the INSERT statement to specify values directly or from a subquery, use the SELECT statement with the INTO clause. Question: What happens when a WHERE clause is not specified in a DELETE statement? Answer: If a WHERE clause is not specified, all the rows in table_or_view are deleted. Question: What are the major clauses of the UPDATE statement? Answer: SET, FROM, and WHERE.

Best Practices related to Specifying and Enforcing Transactions


Supplement or modify the following best practices for your own work situations: SQL programmers are responsible for starting and ending transactions at points that enforce the logical consistency of the data. The programmer must define the sequence of data modifications that leave the data in a consistent state relative to the organization's business rules. The programmer must include these modification statements in a single transaction so that the SQL Server Database Engine can enforce the physical integrity of the transaction.

Best Practices related to Inserting Rows into a Table


Supplement or modify the following best practices for your own work situations: If a value is being loaded into columns with a char, varchar, or varbinary data type, the padding or truncation of trailing blanks (spaces for char and varchar, zeros for varbinary) is determined by the SET ANSI_PADDING setting defined for the column when the table was created. If an empty string (' ') is loaded into a column with a varchar or text data type, the default operation is to load a zero-length string. If an INSERT statement violates a constraint or rule, or if it has a value incompatible with the data type of the column, the statement fails and the Database Engine displays an error message.

Best Practices related to Deleting Rows from a Table


Supplement or modify the following best practices for your own work situations: DELETE can be used in the body of a user-defined function if the object modified is a table variable. The DELETE statement may fail if it tries to remove a row referenced by data in another table with a FOREIGN KEY constraint. If the DELETE removes multiple rows, and any one of the removed

Modifying Data in Tables

6-19

rows violates a constraint, the statement is canceled, an error is returned, and no rows are removed. If you want to delete all the rows in a table, use the DELETE statement without specifying a WHERE clause, or use TRUNCATE TABLE. TRUNCATE TABLE is faster than DELETE and uses fewer system and transaction log resources. Note: if you do use the TRUNCATE statement on a table, you will reset the identity seed of any IDENTITY column in that table.

Best Practices related to Updating Rows in a Table


Supplement or modify the following best practices for your own work situations: UPDATE statements are allowed in the body of user-defined functions only if the table being modified is a table variable. If an update to a row violates a constraint or rule, violates the NULL setting for the column, or the new value is an incompatible data type, the statement is canceled, an error is returned, and no records are updated. The results of an UPDATE statement are undefined if the statement includes a FROM clause that is not specified in such a way that only one value is available for each column occurrence that is updated, that is if the UPDATE statement is not deterministic.

6-20

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lab Review Questions and Answers


Question: Why are values for column names listed in the same order as columns on the table when using the INSERT statement? Answer: Because if all values for column names are listed in the same order as columns on the table, we do not need to specify a column name list. Question: How can we verify that a table has been deleted after using the DELETE statement? Answer: Use a SELECT COUNT(*) statement on the deleted table. Question: How can we write an UPDATE statement to ensure that all rows of a table are affected? Answer: By omitting a WHERE clause that would specify the row or rows to update.

Querying Metadata, XML, and Full-Text Indexes

7-1

Module 7
Querying Metadata, XML, and Full-Text Indexes
Contents:
Lesson 1: Querying Metadata Lesson 2: Overview of XML Lesson 3: Querying XML Data Lesson 4: Overview of Full-Text Indexes Lesson 5: Querying Full-Text Indexes Module Reviews and Takeaways Lab Review Questions and Answers 2 6 8 13 15 19 20

7-2

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 1

Querying Metadata
Contents:
Question and Answers Detailed Demo Steps Additional Reading 3 4 5

Querying Metadata, XML, and Full-Text Indexes

7-3

Question and Answers


Demonstration: Querying Metadata
Question: Why would you choose to use the INFORMATION_SCHEMA rather than System Catalog views to obtain metadata? Answer: The INFORMATION_SCHEMA is based on the ISO standard for metadata so metadata queries using it will be portable between ISO standard databases. Question: Why would you choose to use the System Stored Procedures and Functions to query metadata? Answer: System Stored Procedures and Functions provide a layer of abstraction that reduces the need to understand the underlying system catalog

7-4

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Querying Metadata
Demonstration steps
Querying metadata using System Catalog Views Open a new query window and enter the following query:
SELECT *

FROM sys.tables;

On the toolbar, click Execute

Querying metadata using the Information Schema Open a new query window and enter the following query:
SELECT COLUMN_NAME

FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = N'Product';

On the toolbar, click Execute

Querying metadata using Dynamic Management Views Open a new query window and enter the following query:
SELECT count(*), Command GROUP BY Command

FROM sys.dm_exec_requests

On the toolbar, click Execute

Querying metadata using System Stored Procedures and Functions Open a new query window and enter the following query:
EXEC sp_columns @table_name = N'Department', @table_owner = N'HumanResources';

On the toolbar, click Execute

Querying Metadata, XML, and Full-Text Indexes

7-5

Additional Reading
What Is Metadata?
Managing Metadata in SQL Server

Compatibility Views
Compatibility Views (Transact-SQL)

System Catalog Views


Querying the SQL Server System Catalog

System Catalog View Examples


Querying the SQL Server System Catalog

Information Schema Views


Information Schema Views (Transact-SQL)

Information Schema View Examples


Information Schema Views (Transact-SQL)

Dynamic Management Views And Functions


Dynamic Management Views and Functions

Dynamic Management Views And Functions Examples


Dynamic Management Views and Functions

System Stored Procedures and Functions


Viewing Database Metadata

7-6

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 2

Overview of XML
Contents:
Additional Reading 7

Querying Metadata, XML, and Full-Text Indexes

7-7

Additional Reading
What Is XML?
Understanding XML in SQL Server

Technical Scenarios Where XML Is Used


Understanding XML in SQL Server

Business Scenarios Where XML Is Used


Understanding XML in SQL Server

How SQL Server? 2008 Implements XML


Understanding XML in SQL Server

The XML Data Type


Using XML Data Types

7-8

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 3

Querying XML Data


Contents:
Question and Answers Detailed Demo Steps Additional Reading 9 10 12

Querying Metadata, XML, and Full-Text Indexes

7-9

Question and Answers


Demonstration: Using XML
Question: Why would XQuery be used in a query? Answer: XQuery can be used in a query when data must be returned from a query that is contained in an XML column and not the XML itself. Question: Why would OpenXML be used? Answer: If XML is provided and the data contained in the XML is needed in relational format then OpenXML can be used to shred the XML.

7-10

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Using XML Demonstration steps
Using For XML to generate XML results Open a new query window and enter the following query:
SELECT Cust.CustomerID, OrderHeader.CustomerID, OrderHeader.Status, Cust.AccountNumber OrderHeader.SalesOrderID,

FROM Sales.Customer Cust, Sales.SalesOrderHeader OrderHeader WHERE Cust.CustomerID = OrderHeader.CustomerID ORDER BY Cust.CustomerID FOR XML AUTO

On the toolbar, click Execute

Using OpenXML to query XML Open a new query window and enter the following query:
DECLARE @xml_text VARCHAR(4000), @i INT SELECT @xml_text = ' <root> <person LastName="White" FirstName="Johnson" Title="Mr."/>

<person LastName="Green" FirstName="Marjorie" Title="Mrs."/> EXEC sp_xml_preparedocument @i OUTPUT, @xml_text SELECT * FROM OPENXML(@i, '/root/person') WITH (LastName nvarchar(50), FirstName nvarchar(50), Title nvarchar(8)) EXEC sp_xml_removedocument @i

<person LastName="Carson" FirstName="Cheryl" Title="Miss"/></root>'

On the toolbar, click Execute Using XQuery to query XML Open a new query window and enter the following query:
SELECT JobCandidateID,

Resume.value('declare namespace ns=

"http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/Resume"; concat((/ns:Resume/ns:Name/ns:Name.First)[1], " ", (/ns:Resume/ns:Name/ns:Name.Last)[1])', 'nvarchar(60)') AS FullName, Resume.query('declare namespace ns= for $ed in /ns:Resume/ns:Education

"http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/Resume"; where $ed/ns:Edu.Level="Bachelor" and $ed/ns:Edu.Major="Business"

Querying Metadata, XML, and Full-Text Indexes

7-11

return $ed') AS Education

FROM HumanResources.JobCandidate

On the toolbar, click Execute

7-12

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Additional Reading
Using For XML to Generate XML
FOR XML Support for String Data Types

Shredding XML
Using OPENXML

Querying XML using XQuery


How to use XQuery to query XML data

Generating XML Based Reports


Reporting Services Using XML and Web Service Data Sources

Querying Metadata, XML, and Full-Text Indexes

7-13

Lesson 4

Overview of Full-Text Indexes


Contents:
Additional Reading 14

7-14

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Additional Reading
What Are Full-Text Indexes?
SQL Server 2008 Full-Text Search Internals and Enhancements

How are Full-Text Indexes populated?


SQL Server 2008 Full-Text Search Internals and Enhancements

Full-Text Indexing and Querying Process


SQL Server 2008 Full-Text Search Internals and Enhancements

How to implement full-text indexes in SQL Server? 2008


SQL Server 2008 Full-Text Search Internals and Enhancements

Querying Metadata, XML, and Full-Text Indexes

7-15

Lesson 5

Querying Full-Text Indexes


Contents:
Question and Answers Detailed Demo Steps Additional Reading 16 17 18

7-16

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Question and Answers


Demonstration: Full Text Index
Question: Why would you choose to use a full text search function rather than a predicate? Answer: The full text search functions provide a ranking value for each query result which can be useful in many situations. Question: Why would you choose to use a full text search predicate rather than a function? Answer: Full text search predicates are easy to use in existing queries and new queries without adding the complexity of joining to the results of the function.

Querying Metadata, XML, and Full-Text Indexes

7-17

Detailed Demo Steps


Demonstration: Full Text Index Demonstration steps
Creating a Full Text Index Open a new query window and enter the following query:
exec sp_fulltext_database 'enable'

EXEC sp_fulltext_catalog 'Cat_Name', 'create' 'PK_Product_ProductID';

EXEC sp_fulltext_table 'Production.Product', 'create', 'Cat_Name', EXEC sp_fulltext_column 'Production.Product','Name','add'; EXEC sp_fulltext_table 'Production.Product','activate'; EXEC sp_fulltext_table 'Production.Product ', 'Start_change_tracking';

EXEC sp_fulltext_table 'Production.Product ', 'Start_background_updateindex';

On the toolbar, click Execute

Querying a Full Text Index using predicates Open a new query window and enter the following query:
SELECT Name

FROM Production.Product

WHERE CONTAINS(Name, ' "Chain*" ');

On the toolbar, click Execute

Querying a Full Text Index using functions Open a new query window and enter the following query:
SELECT Product.ProductID, Product.Name, Keys.Rank FROM Production.Product INNER JOIN FREETEXTTABLE(Production.Product, Name, 'Chain',LANGUAGE 'English',2) AS Keys ON Product.ProductID = Keys.[KEY];

On the toolbar, click Execute

7-18

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Additional Reading
Overview of Full-Text Search
SQL Server 2008 Full-Text Search Internals and Enhancements

The CONTAINS Predicate


CONTAINS (Transact-SQL)

The FREETEXT Predicate


FREETEXT (Transact-SQL)

Full-Text Functions
Full-Text Search Query Fundamentals

Combining Full-Text Search and T-SQL Predicates


Integrating Full-Text Search and Transact-SQL Predicates

Querying Metadata, XML, and Full-Text Indexes

7-19

Module Reviews and Takeaways


Review questions
Question: What method should be used to obtain metadata from SQL Server 2008 pertaining to database activity? Answer:Dynamic Management Views provide activity information about SQL Server. Question: What XQuery statements make up the FLWOR structure? Answer:FLWOR is the acronym for for, let, where, order by, and return which are the statements that make up the FLWOR structure. Question: What query language is specifically designed for querying data stored in XML? Answer:XQuery is a query language designed and developed for querying data stored in XML. Question: What is the difference between a full-text query predicate and function? Answer:The difference is that the predicates return boolean (true/false) values so they are only useful within WHERE clauses of queries. On the other hand, the functions return matches in table form.

7-20

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lab Review Questions and Answers


Question: What application business requirements can be accomplished by using metadata queries? Answer: Metadata can be used for many requirements such as retrieving column names for tables, determining the data type and other properties of columns, or monitoring database activity. Question: What is the purpose of compatibility views? Answer: Compatibility views are provided to support applications that were developed on previous versions of SQL Server and used deprecated metadata structures. Question: What statement can be used to convert relational data to XML? Answer: The FOR XML statement can be used to convert relational data to XML. Question: What is the difference between the FREETEXT and CONTAINS predicates? Answer: The FREETEXT predicate is a simplistic method for searching for words or forms of a word. CONTAINS provides more advanced searching options such as finding words or phrases that are near other words or phrases.

Using Programming Objects for Data Retrieval

8-1

Module 8
Using Programming Objects for Data Retrieval
Contents:
Lesson 1: Encapsulating Queries by Using Views Lesson 2: Encapsulating Expressions by Using User-Defined Functions Lesson 3: Overview of Stored Procedures and Triggers Lesson 4: Overview of Triggers Lesson 5: Writing Distributed Queries Module Reviews and Takeaways Lab Review Questions and Answers 2 6 10 14 18 20 21

8-2

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 1

Encapsulating Queries by Using Views


Contents:
Question and Answers Detailed Demo Steps Additional Reading 3 4 5

Using Programming Objects for Data Retrieval

8-3

Question and Answers


Demonstration: Building A View
Question: Why would an indexed view be used? Answer: Indexing a view improves the performance of views that have large result sets or are called frequently. Question: Why would a partitioned view be used? Answer: Partitioning large tables into smaller tables improves performance and allows the load to be distributed among database resources. Partitioned views allow these partitioned tables to be combined into a single view to be queried.

8-4

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Building A View
Demonstration steps Create a view
Open a new query window and enter the following query:
CREATE VIEW vwEmployeeLogins AS SELECT NationalIDNumber, LoginID GO

FROM HumanResources.Employee

On the toolbar, click Execute

Query a view
Open a new query window and enter the following query:
SELECT * FROM vwEmployeeLogins

On the toolbar, click Execute

Generate a script for a view


In Object Explorer, in the AdventureWorks2008 database, right-click the Views folder, and then click Refresh. Right-click the dbo.vwEmployeeLogins view, point to Script View as, point to CREATE To, and then click New Query Editor Window.

Using Programming Objects for Data Retrieval

8-5

Additional Reading
What Are Views?
SQL Views

Creating and Managing a View


CREATE VIEW (Transact-SQL)

Considerations When Creating Views


CREATE VIEW (Transact-SQL)

Restrictions for Modifying Data by Using Views


CREATE VIEW (Transact-SQL)

Indexed Views
Creating Indexed Views

Creating An Indexed View


Creating Indexed Views

Partitioned Views
Using Partitioned Views

Creating A Partitioned View


Using Partitioned Views

8-6

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 2

Encapsulating Expressions by Using User-Defined Functions


Contents:
Question and Answers Detailed Demo Steps Additional Reading 7 8 9

Using Programming Objects for Data Retrieval

8-7

Question and Answers


Demonstration: Building A User Defined Function
Question: Why would a scalar type user-defined function be used? Answer: Scalar type user-defined functions return a single value and can be embedded into a query to alter the value of a column. Question: Why would a table type user-defined function be used? Answer: Table type user-defined functions return multiple values in a row/column table structure and can be queried like a table.

8-8

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Building A User Defined Function
Demonstration steps Create a user defined function
Open a new query window and enter the following query:
CREATE FUNCTION fnSquared ( ) @number int RETURNS int AS BEGIN

DECLARE @result int RETURN @result END GO

SET @result = @number * @number

On the toolbar, click Execute

Query a user defined function


Open a new query window and enter the following query:
SELECT dbo.fnSquared(2) SELECT dbo.fnSquared(8)

On the toolbar, click Execute

Using Programming Objects for Data Retrieval

8-9

Additional Reading
What Are User-Defined Functions
User-defined Function Basics

Creating and Managing User-Defined Functions


CREATE FUNCTION (Transact-SQL)

Restrictions When Creating User-Defined Functions


CREATE FUNCTION (Transact-SQL)

How to Implement Different Types of User-Defined Functions


CREATE FUNCTION (Transact-SQL)

Performance Considerations for using User-Defined Functions


CREATE FUNCTION (Transact-SQL)

8-10

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 3

Overview of Stored Procedures


Contents:
Question and Answers Detailed Demo Steps Additional Reading 11 12 13

Using Programming Objects for Data Retrieval

8-11

Question and Answers


Demonstration: Creating Stored Procedures
Question: How do Stored Procedures promote modular programming? Answer: Stored Procedures encapsulate common functionality so that it can be accessed from whereever it is required.

8-12

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Create an Answer File
Demonstration steps Create a stored procedure
Open a new query window and enter the following query:
CREATE Procedure pGetEmployeeLogin @NationalIDNumber nvarchar(15) AS SELECT NationalIDNumber, LoginID FROM HumanResources.Employee GO

WHERE NationalIDNumber = @NationalIDNumber

On the toolbar, click Execute

Execute a stored procedure


Open a new query window and enter the following query:
Exec pGetEmployeeLogin @NationalIDNumber='295847284'

On the toolbar, click Execute

Using Programming Objects for Data Retrieval

8-13

Additional Reading
What Are Stored Procedures?
CREATE PROCEDURE (Transact-SQL)

How Are Stored Procedures Created?


CREATE PROCEDURE (Transact-SQL)

Stored Procedure Initial Execution


CREATE PROCEDURE (Transact-SQL)

Stored Procedure Tips and Best Practices


CREATE PROCEDURE (Transact-SQL)

Demonstration: Creating Stored Procedures


CREATE PROCEDURE (Transact-SQL)

8-14

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 4

Overview of Triggers
Contents:
Question and Answers Detailed Demo Steps Additional Reading 15 16 17

Using Programming Objects for Data Retrieval

8-15

Question and Answers


Demonstration: Creating Triggers
Question: Why would you use an INSTEAD OF trigger rather than an AFTER trigger? Answer: An INSTEAD OF trigger executes before the insert, update, or delete occurs so it can be used to validate the action before it happens and cancel it if necessary. Question: Why would you use an AFTER trigger rather than an INSTEAD OF trigger? Answer: An AFTER trigger executes after the insert, update, or delete occurs so it can be used to perform subsequent action after the data has been changed.

8-16

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Using Functions to Work with NULL Values
Demonstration steps Create a trigger
Open a new query window and enter the following query:
CREATE TRIGGER trigCurrency ON Sales.Currency AFTER INSERT AS BEGIN

DECLARE @name nvarchar(50) SELECT @name = Name FROM inserted BEGIN END END GO IF len(@name) < 5 ROLLBACK TRANSACTION

On the toolbar, click Execute

See the results of a trigger


Open a new query window and enter the following query:
This statement will fail: VALUES('BAD', 'BAD')

INSERT INTO Sales.Currency(CurrencyCode, Name) This statement will succeed:

INSERT INTO Sales.Currency(CurrencyCode, Name) VALUES('YES', 'THIS IS GOOD')

On the toolbar, click Execute

Using Programming Objects for Data Retrieval

8-17

Additional Reading
What Are Triggers?
CREATE TRIGGER (Transact-SQL)

How are Triggers Created?


CREATE TRIGGER (Transact-SQL)

How Triggers Work


CREATE TRIGGER (Transact-SQL)

Trigger Types and Limitations


CREATE TRIGGER (Transact-SQL)

8-18

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 5

Writing Distributed Queries


Contents:
Additional Reading 19

Using Programming Objects for Data Retrieval

8-19

Additional Reading
How SQL Server? Works With Heterogeneous Data
Distributed Queries

Adding Linked Servers


Linking Servers

Using Ad Hoc Distributed Queries


Distributed Queries

How To Write Linked Server Based Distributed Queries


OPENROWSET (Transact-SQL) sp_addlinkedserver (Transact-SQL)

8-20

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Module Reviews and Takeaways


Review Questions
Question: What option must be specified in a CREATE VIEW in order for the view to be indexable? Answer: The SCHEMABINDING option must be specified for a view to be indexable. Question: How can the source of a stored procedure be hidden? Answer: Using the WITH ENCRYPTION option of CREATE PROCEDURE obfuscates the procedure source. Question: What special kind of stored procedure can be used to roll back an attempted data modification in a SQL Server table? Answer: A trigger is a stored procedure that is executed when a data modification is attempted. Question: What types of data sources can be linked to SQL Server 2008 for distributed queries? Answer: Any data source with a provider can be linked.

Using Programming Objects for Data Retrieval

8-21

Lab Review Questions and Answers


Question: What is the difference between scalar and table type user-defined functions? Answer: A scalar type user-defined function returns a single scalar value. A table type user-defined function returns multiple values organized in a table structure. Question: Why would a linked server be used instead of an ad hoc distributed query? Answer: A linked server maintains a connection with the remote data source at the server level so that all queries to that data source can share it. This allows changes in the connectivity as well as security measures for it to be managed in a single location. Question: How is a table type user-defined function queried? Answer: Since table type user-defined functions return multiple values in a table structure, they are usually called within the FROM clause of a T-SQL query. Question: Where are stored procedure execution plans stored after initial execution? Answer: Compiled execution plans are stored in the stored procedure cache for future use.

Using Advanced Querying Techniques

9-1

Module 9
Using Advanced Querying Techniques
Contents:
Lesson 1: Considerations for Querying Data Lesson 2: Working with Data Types Lesson 3: Cursors and Set-Based Queries Lesson 4: Dynamic SQL Lesson 5: Maintaining Query Files Module Reviews and Takeaways Lab Review Questions and Answers 2 6 10 14 18 20 22

9-2

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 1

Considerations for Querying Data


Contents:
Question and Answers Detailed Demo Steps Additional Reading 3 4 5

Using Advanced Querying Techniques

9-3

Question and Answers


Execution Plans
Question: Why would you want to view the Estimated Execution Plan? Answer: Viewing the Estimated Execution Plan may reveal resource intensive operations before the query is run.

Data Type Conversions


Question: What are some examples of operations that can result in data conversion? Answer: Answers will vary, but some examples are: adding numbers to character strings, changing to the money data type, or changing strings into date/time data.

Implicit Conversion
Question: When would you want to avoid implicit conversions? Answer: Any time that you need to insure that an operation returns a specific data type, you should avoid implicit conversions.

Demonstration: Using Execution Plans


Question: What do you need to do in order to be able to view the Actual Execution Plan? Answer: In SQL Server Management Studio, you can right-click Include Actual Execution Plan before the query is run. You can also use a SET SHOWPLAN command in a query, or use SQL Server Profiler to capture Showplan Events.

Demonstration: Understanding Data Type Conversion


Question: How can implicit data type conversions cause unexpected results on queries that run successfully? Answer: Because of data type precedence rules, some queries will succeed even though the data type precedence rules will result in one data type being converted to another data type in a way that you did not intend.

9-4

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Using Execution Plans
Demonstration steps Viewing estimated and actual execution plans with the UI
Open the script E:\MOD09\Democode\ExecutionPlanQuery.sql The simple subquery and join produce an interesting execution plan. View the Estimated Execution Plan in SQL Server Management Studio. In SQL Server Management Studio, right-click the query, and then click Include Actual Execution plan before executing the query.

Viewing estimated and actual execution plans with SET


Uncomment the SET SHOWPLAN_XML blocks in the query and views the XML showplans when you execute the query. Uncomment the SET SHOWPLAN_TEXT bblocks in the query and views the text showplans when you execute the query.

Viewing estimated and actual execution plans with SQL Server Profiler
Start SQL Server Profiler and create a new trace. In the Events tab, under Performance, select some of the different Showplan events and start the trace. In SQL Server Management Studio, execute the query again and review the execution plan in SQL Server Profiler.

Demonstration: Understanding Data Type Conversion


Demonstration steps Understanding Implicit Conversions
Open E:\MOD09\Democode\ImplicitConversionQueries.sql. There are several queries in the file you can run independently of one other. Point out to students where implicit conversion succeeds and where it fails or produces unintended results and why.

Understanding Explicit Conversions


Open E:\MOD09\Democode\CastConvertQueries.sql. There are several queries in the file you can run independently of one another. Point out to students the slight difference between the CAST and CONVERT usage.

Using Advanced Querying Techniques

9-5

Additional Reading
Execution Plans
Execution Plans

Data Type Conversions


Data Type Conversions Implicit Conversions Using CAST and CONVERT

Implicit Conversion
Data Type Conversions Implicit Conversions

Explicit Conversions with CAST and CONVERT


Using CAST and CONVERT

Data Type Precedence


Data Type Precedence

9-6

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 2

Working with Data Types


Contents:
Question and Answers Detailed Demo Steps Additional Reading 7 8 9

Using Advanced Querying Techniques

9-7

Question and Answers


Demonstration: Working with Date/Time Data
Question: What happens when you insert data containing only a date or only a time into a column that holds date and time data? Answer: The insert will succeed, but SQL Server will supply default values for the missing portion.

Demonstration: Using the hierarchyid Data Type


Question: What is the difference between the GetDescendant and GetAncestor methods? Answer: GetDescendant queries the next level down in the hierarchy, while GetAncestor queries the next level up in the hierarchy.

9-8

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Working with Date/Time Data
Demonstration steps Working with the different date/time data types
Open E:\MOD09\Democode\DateTimeComparisons.sql. The query produces a table that compares how the same date/time appear in the different datetime data types. Insert only date and only time data into a column that holds date and time data. Insert a date and time into a column that holds only date or only time data to show the error.

Demonstration: Using the hierarchyid Data Type


Creating a hierarchy
Open the SalesTerritory solution in E:\Democode\SalesTerritory. Run the queries in the following order: o CreateTerritoryTable

o
o o o

CreateTableIndex
InsertRootTerritory InsertChildTerritory CreateTerritorySP this creates a stored procedure that helps automate the entry of additional child nodes PopulateTerritoryTable this will not work without first running CreateTerritorySP

Querying and modifying a hierarchy


Run the following queries: o o o GetTerritoryOrg can be used to query the current hierarchy GetNATerritories will show territories in North America MoveTerritory moves Australia from reporting to the Worldwide department to reporting to the Asia Sales department

Using Advanced Querying Techniques

9-9

Additional Reading
Recommendations for Querying Date/Time Data
Using Time and Date Data Date and Time Data Types and Functions

Recommendations for Inserting Date/Time Data


Using Time and Date Data Date and Time Data Types and Functions

Implementing the hierarchyid Data Type


hierarchyid Using the hierarchyid Data Type

Working with Hierarchies


hierarchyid Using the hierarchyid Data Type

9-10

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 3

Cursors and Set-Based Queries


Contents:
Question and Answers Detailed Demo Steps Additional Reading 11 12 13

Using Advanced Querying Techniques

9-11

Question and Answers


Understanding Cursors
Question: Can you think of a scenario where a cursor might prove useful? Answer: Frequently, cursors are used to keep a running tally of a changing numeric value.

Demonstration: Working with Cursors


Question: How do you specify that a cursor should be read only? Answer: Use READ_ONLY in the DECLARE CURSOR statement.

Demonstration: Using Set-Based Queries


Question: Why is it recommended to rewrite cursors as set-based queries? Answer: In most cases, set-based queries run more quickly and are less resource-intensive than cursors.

9-12

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Working with Cursors
Demonstration steps Use a cursor
Open E:\MOD09\Democode\CursorSample.sql. Review and execute the query. The code produces a list of products from the AdventureWorks2008 database.

Demonstration: Using Set-Based Queries


Demonstration steps Rewriting a cursor using a set-based approach
Open E:\MOD09\Democode\PriceUpdateCursor.sql. This creates a cursor that iterates through the Production.Product table and updates list prices. Rewrite the cursor using:
o UPDATE Production.Product SET ListPrice = 49.99

The query for the set-based approach can also be found in E:\MOD09\Democode\PriceUpdateSetBased.sql.

Using Advanced Querying Techniques

9-13

Additional Reading
Understanding Cursors
Cursors (Database Engine)

Cursor Implementations
Cursor Implementations

Using Cursors
Cursors (Database Engine) DECLARE CURSOR: Using DEALLOCATE

Understanding Set-Based Logic


JOIN Fundamentals Manipulating Result Sets Query Fundamentals

9-14

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 4

Dynamic SQL
Contents:
Question and Answers Detailed Demo Steps Additional Reading 15 16 17

Using Advanced Querying Techniques

9-15

Question and Answers


Using Dynamic SQL
Question: Why choose one method of dynamic SQL execution over the other? Answer: sp_executesql is more likely to produce a reusable execution plan, so EXECUTE is normally used for simple situations where plan reusability is not a consideration.

Considerations for Using Dynamic SQL


Question: Why is SQL injection so dangerous? Answer: SQL injection, if successful, can allow an unauthorized user to access, modify, or destroy data very easily. All input must be validated when building dynamic SQL strings to help avoid SQL injection.

Demonstration: Using Dynamic SQL


Question: What role do variables play in dynamic SQL? Answer: Variables are used to store the individual strings of information that are then joined together to form the query.

9-16

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Detailed Demo Steps


Demonstration: Using Dynamic SQL
Demonstration steps Building a dynamic SQL query
Open E:\MOD09\Democode\DynamicSQL.sql.

Review and execute the query to see how a dynamic SQL string is built then passes to sp_executesql.

Using Advanced Querying Techniques

9-17

Additional Reading
Introducing Dynamic SQL
Dynamic SQL

Using Dynamic SQL


sp_executesql Using sp_executesql EXECUTE

Considerations for Using Dynamic SQL


SQL Injection SQL Injection Protection

9-18

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lesson 5

Maintaining Query Files


Contents:
Additional Reading 19

Using Advanced Querying Techniques

9-19

Additional Reading
What are Versioning and Source Control?
Source Control Basics

Features of Team Foundation Server 2008


Team Foundation Server Version control with Team Foundation Server TFS support for SQL Server 2008 Visual SourceSafe 2005

9-20

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Module Reviews and Takeaways


Review Questions
Question: How do cursors handle result sets? Answer: Cursors handle the result sets on a row-by-row basis. Each row is fetched into the cursor, where any read or update operations are performed, and then then next row is fetched into the cursor. Question: What functions are used to perform explicit data type conversions? Answer: CAST and CONVERT are used to perform explicit data type conversions. CAST is the more portable of the two functions, while CONVERT provides additional style options for date and time conversions. Question: What methods can be used to execute dynamic SQL queries? Answer: Dynamic SQL queries can be executed with sp_executesql or EXECUTE. Sp_executesql is more likely to produce reusable execution plans and is usually the recommended method for executing dynamic SQL statements.

Common Issues related to data type conversion


Identify the causes for the following common issues related to data type conversion and fill in the troubleshooting tips. For answers, refer to relevant lessons in the module.

Issue
Cannot implicitly or explicitly convert string or number data to xml data type Implicit conversions to binary data type produces unexpected results

Troubleshooting tip
Conversion to the xml data type will fail if the XML is not well-formed. If the binary data type is too small for the conversion, the leading digits are silently truncated. Conversion will succeed, but the results will be wrong. If the integer is too big for the character conversion, an asterisk is used in implicit conversions.

Converting integers to character data types implicitly results in an asterisk (*) instead of the correct value.

Best Practices related to using dynamic SQL


Supplement or modify the following best practices for your own work situations: Because dynamic SQL is a significant vector of SQL injection attacks, there are a number of steps you should take. Make no assumptions about the size, type, or content of the data that is received by your application. For example, you should make the following evaluation: o How will your application behave if an errant or malicious user enters a 10megabyte MPEG file where your application expects a postal code? How will your application behave if a DROP TABLE statement is embedded in a text field?

Using Advanced Querying Techniques

9-21

Test the size and data type of input and enforce appropriate limits. This can help prevent deliberate buffer overruns. Never build Transact-SQL statements directly from user input. Use stored procedures to validate user input. Never concatenate user input that is not validated. String concatenation is the primary point of entry for script injection. Do not accept the following strings in fields from which file names can be constructed: AUX, CLOCK$, COM1 through COM8, CON, CONFIG$, LPT1 through LPT8, NUL, and PRN.

9-22

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Lab Review Questions and Answers


Question: What is required for a conversion to the XML data type to succeed? Answer: The data to be converted must result in well-formed XML, or the conversion will fail. Question: How do you create the root node of a hierarchy? Answer: Use the GetRoot() function to determine the root level and use the result as the basis for an INSERT statement to create the root node. Question: When using a cursor, how do you retrieve the next row in the result set? Answer: Use the FETCH NEXT command.

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

R-1

Resources
Contents:
Microsoft Learning TechNet and MSDN Content Knowledgebase Communities Books 2 3 9 10 11

R-2

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Microsoft Learning
This section describes various Microsoft Learning programs and offerings. Microsoft Skills Assessments Describes the skills assessment options available through Microsoft. Microsoft Learning Describes the training options available through Microsoft face-to-face or self-paced. Microsoft Certification Program Details how to become a Microsoft Certified Professional, Microsoft Certified Database Administrators, and more. Microsoft Learning Support o To provide comments or feedback about the course, send e-mail to support@mscourseware.com. To ask about the Microsoft Certification Program (MCP), send e-mail to mcphelp@microsoft.com

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

R-3

TechNet and MSDN Content


This section includes content from TechNet for this course.

Module 1
Chapter 7 - Client/Server Architecture File-Server vs. Client/Server Editions and Components of SQL Server 2008 Installing SQL Server 2005 SQL Server Overview Components of the SQL Server Database Engine Considerations for Installing the SQL Server Database Engine Databases Relational Database Components Database Engine Concepts Relational Databases Normalization SQL Database Normalization Rules Identifiers Using Extended Properties on Database Objects Deprecated Database Engine Features in SQL Server 2008 Data Types (Transact-SQL) Using Common Table Expressions GRANT (Transact-SQL) Query Fundamentals Transact-SQL Syntax Conventions (Transact-SQL) Transact-SQL Reference (Transact-SQL) Functions (Transact-SQL) Transact-SQL Variables Expressions (Transact-SQL) Control-of-Flow Conditional Statement Syntax GOTO (Transact-SQL) ELSE (IF...ELSE) TRY...CATCH (Transact-SQL) RAISERROR (Transact-SQL)

R-4

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

/*...*/ (Comment) (Transact-SQL) -- (Comment) (Transact-SQL) Using Comments bcp Utility sqlcmd Utility Query Tools Features in SQL Server Management Studio Developing Solutions and Projects in SQL Server Management Studio Introduction to Solutions, Projects, and Items Introducing SQL Server Management Studio How to: Create New Solutions Using Solution Explorer Connect to (import) SQL Server data Use Microsoft Query to retrieve external data

Module 2
+ (String Concatenation) (Transact-SQL) Analyzing a Query Assigning Result Set Column Names BETWEEN (Transact-SQL) Checklist for Analyzing Slow-Running Queries COALESCE (Transact-SQL) Comparison Operators Comparison Operators (Transact-SQL) CONTAINS (Transact-SQL) Derived Column Transformation Eliminating Duplicates with DISTINCT Expressions (Transact-SQL) FREETEXT (Transact-SQL) Functions (Transact-SQL) IN (Transact-SQL) ISNULL (Transact-SQL) LIKE (Transact-SQL) Logical Operator Precedence Logical Operators (Transact-SQL)

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

R-5

Null Values NULLIF (Transact-SQL) Operator Precedence (Transact-SQL) ORDER BY Clause (Transact-SQL) Parts of a SELECT Statement Pattern Matching in Search Conditions Predicate (Transact-SQL) Query Fundamentals Query Performance Query Tuning Recommendations Search Condition (Transact-SQL) SELECT Clause (Transact-SQL) SELECT Examples (Transact-SQL) Sorting Rows with ORDER BY SQL Statement Processing SUBSTRING (Transact-SQL) Troubleshooting Poor Query Performance: Cardinality Estimation Troubleshooting Queries Using Sparse Columns Using Table Aliases WHERE (Transact-SQL)

Module 3
Summarizing Data Deterministic and Nondeterministic Functions Aggregate Functions COUNT (Transact-SQL) CREATE AGGREGATE (Transact-SQL) CLR User-Defined Aggregates Invoking CLR User-Defined Aggregate Functions GROUP BY (Transact-SQL) HAVING (Transact-SQL) COMPUTE (Transact-SQL) GROUPING SETS Equivalents Ranking Functions (Transact-SQL)

R-6

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Over Clause (Transact-SQL) RANK (Transact-SQL) DENSE_RANK (Transact-SQL) ROW_NUMBER (Transact-SQL) NTILE (Transact-SQL) Using PIVOT and UNPIVOT SQL Server Overview

Module 4
PRIMARY KEY Constraints FOREIGN KEY Constraints Views Collation Precedence (Transact-SQL)

Module 5
ALL (Transact-SQL) OME | ANY (Transact-SQL) Craig Freedman's SQL Server Blog: Scalar Subqueries table (Transact-SQL)

Module 6
INSERT (Transact SQL) Adding Rows by Using INSERT and SELECT INSERT (Transact SQL) INSERT (Transact SQL) OUTPUT Clause (Transact-SQL) DELETE (Transact-SQL) TRUNCATE TABLE (Transact-SQL) UPDATE (Transact-SQL) Changing Data by Using UPDATE Changing Data by Using the SET Clause Changing Data by Using the FROM Clause Changing Data by Using the WHERE Clause Transactions (Database Engine) Write-Ahead Transaction Log Checkpoints and the Active Portion of the Log BEGIN TRANSACTION (Transact-SQL)

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

R-7

COMMIT TRANSACTION (Transact-SQL) SET XACT_ABORT (Transact-SQL) TRY...CATCH (Transact-SQL) Using TRY...CATCH in Transact-SQL Isolation Levels in the Database Engine Nesting Transactions

Module 7
Managing Metadata in SQL Server Compatibility Views (Transact-SQL) Querying the SQL Server System Catalog Information Schema Views (Transact-SQL) Dynamic Management Views and Functions Viewing Database Metadata Understanding XML in SQL Server Using XML Data Types FOR XML Support for String Data Types Using OPENXML How to use XQuery to query XML data Reporting Services Using XML and Web Service Data Sources SQL Server 2008 Full-Text Search Internals and Enhancements CONTAINS (Transact-SQL) FREETEXT (Transact-SQL) Full-Text Search Query Fundamentals Integrating Full-Text Search and Transact-SQL Predicates

Module 8
SQL Views CREATE VIEW (Transact-SQL) Creating Indexed Views Using Partitioned Views User-defined Function Basics CREATE FUNCTION (Transact-SQL) CREATE PROCEDURE (Transact-SQL) CREATE TRIGGER (Transact-SQL) Distributed Queries

R-8

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Linking Servers OPENROWSET (Transact-SQL) sp_addlinkedserver (Transact-SQL)

Module 9
Execution Plans Data Type Conversions Implicit Conversions Using CAST and CONVERT Data Type Precedence Using Time and Date Data Date and Time Data Types and Functions hierarchyid Using the hierarchyid Data Type Cursors (Database Engine) Cursor Implementations DECLARE CURSOR: Using DEALLOCATE JOIN Fundamentals Manipulating Result Sets Query Fundamentals Dynamic SQL sp_executesql Using sp_executesql EXECUTE SQL Injection SQL Injection Protection Source Control Basics Team Foundation Server Version control with Team Foundation Server TFS support for SQL Server 2008 Visual SourceSafe 2005

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

R-9

Knowledge Base
This section includes content from Microsoft TechNet and MSDN that provides in-depth discussion on technical topics related to SQL Server 2008 Knowledge Base Query Tools

Microsoft
Schema Diagrams for the database can be found here: http://www.codeplex.com/MSFTDBProdSamples/Wiki/View.aspx?title=AWSchemaDiag&referring Title=Home Description of the database normalization basics

R-10

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Communities
The Professional Association for SQL Server (PASS) is an independent, not-for-profit association, dedicated to supporting, educating, and promoting the Microsoft SQL Server community. Offering a multitude of networking channels from local user groups and special interest groups (SIGs) to webcasts and the annual PASS Summit the largest gathering of SQL Server professionals in the world PASS enables knowledge sharing, in-depth learning, access to the Microsoft SQL Server team, and the ability to influence the direction of SQL Server technologies. For more information and your free membership, visit www.sqlpass.org.

Blogs
Query Processing -- introduction to the blog!

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

R-11

Books
This section describes the various books that may be of use to SQL Server 2008 DBAs. Introducing Microsoft SQL Server 2008, Microsoft Corporation, Peter DeBetta

R-12

Writing Queries Using Microsoft SQL Server 2008 Transact-SQL

Send Us Your Feedback


You can search the Microsoft Knowledge Base for known issues at Microsoft Help and Support before submitting feedback. Search using either the course number and revision, or the course title. Note Not all training products will have a Knowledge Base article if that is the case, please ask your instructor whether or not there are existing error log entries.

Courseware Feedback
Send all courseware feedback to support@mscourseware.com. We truly appreciate your time and effort. We review every e-mail received and forward the information on to the appropriate team. Unfortunately, because of volume, we are unable to provide a response but we may use your feedback to improve your future experience with Microsoft Learning products.

Reporting Errors
When providing feedback, include the training product name and number in the subject line of your email. When you provide comments or report bugs, please include the following: Document Page number or location Complete description of the error or suggested change

Please provide any details that are necessary to help us verify the issue.

Important All errors and suggestions are evaluated, but only those that are validated are added to the product Knowledge Base article.

Você também pode gostar