1. Trang chủ
  2. » Công Nghệ Thông Tin

Microsoft SQL Server 2008 R2 Unleashed- P174 pot

10 78 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 181,55 KB

Nội dung

ptg 1674 CHAPTER 43 Transact-SQL Programming Guidelines, Tips, and Tricks Panteley Sylvia 100 White Johnson 100 Straight Dean 100 Locksley Charlene 100 Carson Cheryl 100 Blotchet-Halls Reginald 100 del Castillo Innes 100 Note that no real difference exists between left and right outer joins except for specifying which table on which side of the join condition is to be the controlling, or outer, table. For example, the previous query would provide the same result if you reversed the tables in the join clause and made it a right outer join: select au_lname, au_fname, avg(royaltyper) from dbo.titleauthor ta right outer join dbo.authors a on ta.au_id = a.au_id group by au_lname, au_fname order by 3 A full outer join returns all matching rows from both tables, along with all rows from each table, without a corresponding match in the other table: select a.au_fname, p.pub_name from dbo.authors a full outer join dbo.publishers p on a.state = p.state go au_fname pub_name James A. NULL Francine du Plessix Kumquat Technical Publishing Jean NULL E.L. Nordome Titles Justin Algodata Infosystems April Sidney’s Books and More Ron Algodata Infosystems Jack NULL Matt NULL Josef NULL Albert Ramona Publishers NULL Gooseberry Titles NULL Binnet & Hardley NULL GGG&G NULL Lucerne Publishing NULL Tomato Books NULL Significant Titles Company ptg 1675 T-SQL Tips and Tricks 43 OUTER JOIN Versus WHERE Clause Matching With the ANSI join syntax, you specify the join condition in the FROM clause. Additional search conditions can be specified in either the JOIN clause or WHERE clause. It’s important to remember that in a left or right outer join, search conditions specified in the ON clause work differently than search conditions in the WHERE clause: . Search conditions in the WHERE clause always exclude nonmatching rows. . Search conditions in the ON clause sometimes exclude rows and sometimes do not. Needless to say, it can be somewhat confusing to figure out which rows and data values will be returned. To demonstrate the use of search conditions in the WHERE clause versus the ON clause, the examples presented in this section make use of the two views shown in Listing 43.15. LISTING 43.15 CREATE VIEW Statements for Outer Join Examples CREATE VIEW dbo.STORES_V1 AS SELECT STOR_ID, CITY FROM DBO.STORES WHERE STOR_ID BETWEEN ‘A001’ AND ‘A005’ go CREATE VIEW dbo.STORES_V2 AS SELECT STOR_ID, STATE FROM DBO.STORES WHERE STOR_ID BETWEEN ‘A002’ AND ‘A007’ UNION ALL SELECT ‘A004’, ‘MA’ go select * from dbo.stores_v1 select * from dbo.stores_v2 STOR_ID CITY A001 Dublin A002 Oakland A003 Bisbee A004 White Plains A005 Thomaston (5 row(s) affected) STOR_ID STATE A002 NJ A003 AZ A004 NY ptg 1676 CHAPTER 43 Transact-SQL Programming Guidelines, Tips, and Tricks A005 GA A006 CA A007 CA A004 MA Listing 43.16 provides an example of a left outer join query that includes the search condition in the ON clause. All rows are returned from STORES_V1, and NULL values are returned for STORES_V2 where there isn’t a matching STOR_ID or where there is a matching STOR_ID but STATE is not equal to ’GA’. LISTING 43.16 Specifying the Search Condition in the ON Clause SELECT * FROM DBO.STORES_V1 V1 LEFT OUTER JOIN DBO.STORES_V2 V2 ON V1.STOR_ID = V2.STOR_ID AND V2.STATE <> ‘GA’ ORDER BY V1.STOR_ID ,V2.STATE go STOR_ID CITY STOR_ID STATE A001 Dublin NULL NULL A002 Oakland A002 NJ A003 Bisbee A003 AZ A004 White Plains A004 MA A004 White Plains A004 NY A005 Thomaston NULL NULL Now, if you put the search condition in the WHERE clause, as shown in Listing 43.17, the nonmatching rows from STORES_V2 are filtered out because the NULL value returned for STATE does not match the WHERE clause search criteria WHERE V2.STATE <> ‘GA’. (Remember that NULL values are neither equal to nor not equal to other values.) LISTING 43.17 Specifying a Search Condition in a WHERE Clause SELECT * FROM DBO.STORES_V1 V1 LEFT OUTER JOIN DBO.STORES_V2 V2 ON V1.STOR_ID = V2.STOR_ID WHERE V2.STATE <> ‘GA’ ORDER BY V1.STOR_ID ,V2.STATE go STOR_ID CITY STOR_ID STATE A002 Oakland A002 NJ ptg 1677 T-SQL Tips and Tricks 43 A003 Bisbee A003 AZ A004 White Plains A004 MA A004 White Plains A004 NY To include the nonmatching rows from STORES_V2, you need to add a check for NULL to the WHERE clause, as shown in Listing 43.18. LISTING 43.18 Including Nonmatching Inner Table Rows That Do Not Match a WHERE Clause Search Condition SELECT * FROM DBO.STORES_V1 V1 LEFT OUTER JOIN DBO.STORES_V2 V2 ON V1.STOR_ID = V2.STOR_ID WHERE (V2.STATE <> ‘GA’ or V2.STATE is NULL) ORDER BY V1.STOR_ID ,V2.STATE go STOR_ID CITY STOR_ID STATE A001 Dublin NULL NULL A002 Oakland A002 NJ A003 Bisbee A003 AZ A004 White Plains A004 MA A004 White Plains A004 NY Notice that the row where STOR_ID = ‘A005’ is still not included in the result set. The query shown in Listing 43.18 also demonstrates another difference between specifying a search condition in the WHERE clause and the ON clause. In this case, the outer join is performed first, so that all rows and selected column values are returned from STORES_V2, including the row where STOR_ID = ‘A005’, without considering the WHERE clause condition: SELECT * FROM DBO.STORES_V1 V1 LEFT OUTER JOIN DBO.STORES_V2 V2 ON V1.STOR_ID = V2.STOR_ID go STOR_ID CITY STOR_ID STATE A001 Dublin NULL NULL A002 Oakland A002 NJ A003 Bisbee A003 AZ A004 White Plains A004 NY A004 White Plains A004 MA A005 Thomaston A005 GA ptg 1678 CHAPTER 43 Transact-SQL Programming Guidelines, Tips, and Tricks After the join result is returned, because the STATE value is equal to ’GA’, the search condi- tion in the WHERE clause (V2.STATE <> ‘GA’) filters out that row. In a left or right outer join, a search condition in the ON clause also works differently, depending on whether it refers to a field in the inner or outer table. If the ON clause search condition refers to a field in the outer table, it determines whether the related row finds a match. (The outer row is returned regardless.) For example, Listing 43.19 demonstrates a search condition in the ON clause that restricts which rows in STORES_V1 (the outer table) join to STORES_V2. The join is performed only for those rows in STORES_V1 where CITY is greater than N. However, all rows from STORES_V1 are still returned. LISTING 43.19 Specifying an ON Clause Search Condition on the Outer Table SELECT * FROM DBO.STORES_V1 V1 LEFT OUTER JOIN DBO.STORES_V2 V2 ON V1.STOR_ID = V2.STOR_ID AND V1.CITY > ‘N’ ORDER BY V1.STOR_ID ,V2.STATE go STOR_ID CITY STOR_ID STATE A001 Dublin NULL NULL A002 Oakland A002 NJ A003 Bisbee NULL NULL A004 White Plains A004 MA A004 White Plains A004 NY A005 Thomaston A005 GA If the ON clause search condition refers to a field in the inner table, it determines whether the related row matches the join. Listing 43.20 shows an example of specifying the ON clause search condition on the inner table. Again, notice that all rows from STORES_V1 are returned, but only the matching rows are returned from STORES_V2, where STOR_ID is less than A004. LISTING 43.20 Specifying an ON Clause Search Condition on the Inner Table SELECT * FROM DBO.STORES_V1 V1 LEFT OUTER JOIN DBO.STORES_V2 V2 ON V1.STOR_ID = V2.STOR_ID AND V2.STOR_ID < ‘A004’ ORDER BY V1.STOR_ID ,V2.STATE go STOR_ID CITY STOR_ID STATE ptg 1679 T-SQL Tips and Tricks 43 A001 Dublin NULL NULL A002 Oakland A002 NJ A003 Bisbee A003 AZ A004 White Plains NULL NULL A005 Thomaston NULL NULL When you perform a left or right outer join, a search condition against the outer table in the ON clause works differently from the same search condition specified in the WHERE clause. As shown in Listing 43.19, when the search condition in the ON clause filters on a field in the outer table, the outer row is returned, regardless, with no matching rows returned from the inner table. However, if the search condition on the OUTER table is spec- ified in the WHERE clause, the outer row is eliminated from the result set, as shown in Listing 43.21. LISTING 43.21 Specifying an Outer Table Search Condition in the WHERE Clause SELECT * FROM DBO.STORES_V1 V1 LEFT OUTER JOIN DBO.STORES_V2 V2 ON V1.STOR_ID = V2.STOR_ID WHERE V1.CITY > ‘N’ ORDER BY V1.STOR_ID ,V2.STATE go STOR_ID CITY STOR_ID STATE A002 Oakland A002 NJ A004 White Plains A004 MA A004 White Plains A004 NY A005 Thomaston A005 GA Nested Outer Joins When using the ANSI JOIN syntax, you must be careful about mixing outer joins with inner joins because the query may not generate the desired result if the outer join is not continued down to the lowest level. For example, consider the query shown in Listing 43.22. The intent of this query is to list all authors whose state equals NE and, for those authors, display the titles of their associated books, if any. LISTING 43.22 An Outer Join Nested in an Inner Join select left(au_lname, 20) as au_lname, au_fname, left(title, 20) as title from dbo.authors a left join dbo.titleauthor ta on a.au_id = ta.au_id join dbo.titles t on ta.title_id = t.title_id where a.state = ‘NE’ ptg 1680 CHAPTER 43 Transact-SQL Programming Guidelines, Tips, and Tricks go au_lname au_fname title Patterson Richard North The Lasko Tangent Patterson Richard North The Outside Man Patterson Richard North Private Screening Patterson Richard North Eyes of a Child Patterson Richard North Degree of Guilt Patterson Richard North Escape the Night However, because the outer join is not carried to the titles table, the author with no matching row in the titleauthor table ends up getting filtered from the result set. The reason is that when the outer join is performed between authors and titleauthor, because no matching row is found, NULL is returned for title_id. Because a normal inner join is performed on the titles table, the NULL value for title_id does not match any rows in the titles table, so the author with no matching rows in titleauthor ends up getting filtered out. To see those authors, you need to modify the query in Listing 43.22 to carry the outer join down to the join between titleauthor and authors: select left(au_lname, 20) as au_lname, au_fname, left(title, 20) as title from dbo.authors a left join dbo.titleauthor ta on a.au_id = ta.au_id left join dbo.titles t on ta.title_id = t.title_id where a.state = ‘NE’ go au_lname au_fname title Patterson Richard North The Lasko Tangent Patterson Richard North The Outside Man Patterson Richard North Private Screening Patterson Richard North Eyes of a Child Patterson Richard North Degree of Guilt Patterson Richard North Escape the Night McBadden Heather NULL Working with Full Outer Joins A full outer join selects rows from both tables and joins those rows that match on the join fields. In addition to the matching rows, one copy of each nonmatching row from each table is returned. Listing 43.23 shows an example of a full outer join. ptg 1681 T-SQL Tips and Tricks 43 LISTING 43.23 Full Outer Join Example SELECT * FROM DBO.STORES_V1 V1 FULL OUTER JOIN DBO.STORES_V2 V2 ON V1.STOR_ID = V2.STOR_ID ORDER BY V1.STOR_ID ,V2.STOR_ID ,V2.STATE go STOR_ID CITY STOR_ID STATE NULL NULL A006 CA NULL NULL A007 CA A001 Dublin NULL NULL A002 Oakland A002 NJ A003 Bisbee A003 AZ A004 White Plains A004 MA A004 White Plains A004 NY A005 Thomaston A005 GA As you can see from the results in Listing 43.23, all rows are returned from both STORES_V1 and STORES_V2. In a full outer join, a search condition in the ON clause is handled differently from a search condition in the WHERE clause in that it never results in a row being excluded from the result set. All it does is categorize the input row as being either matching or nonmatching. In Listing 43.24, a search condition ( V1.STOR_ID > ‘A003’) is specified in the ON clause. As you can see, any rows that do not meet that search condition are returned as nonmatching rows. LISTING 43.24 Specifying a Search Condition in a Full Outer Join ON Clause SELECT * FROM DBO.STORES_V1 V1 FULL OUTER JOIN DBO.STORES_V2 V2 ON V1.STOR_ID = V2.STOR_ID AND V1.STOR_ID > ‘A003’ ORDER BY V1.STOR_ID ,V2.STOR_ID ,V2.STATE go STOR_ID CITY STOR_ID STATE NULL NULL A002 NJ NULL NULL A003 AZ NULL NULL A006 CA NULL NULL A007 CA A001 Dublin NULL NULL A002 Oakland NULL NULL A003 Bisbee NULL NULL A004 White Plains A004 MA A004 White Plains A004 NY A005 Thomaston A005 GA ptg 1682 CHAPTER 43 Transact-SQL Programming Guidelines, Tips, and Tricks As you can see, when you work with full outer joins, search arguments in the ON clause serve only to define which rows are used as matching rows for a join. Search arguments specified in the WHERE clause define which rows are returned. It’s important to note that the WHERE clause conditions behave as if the join is an inner join and are applied after the join is done. Listing 43.25 shows an example. LISTING 43.25 Specifying a Search Condition in a Full Outer Join WHERE Clause SELECT * FROM dbo.STORES_V1 V1 FULL OUTER JOIN dbo.STORES_V2 V2 ON V1.STOR_ID = V2.STOR_ID WHERE V1.STOR_ID > ‘A003’ ORDER BY V1.STOR_ID ,V2.STOR_ID ,V2.STATE go STOR_ID CITY STOR_ID STATE A004 White Plains A004 MA A004 White Plains A004 NY A005 Thomaston A005 GA Generating T-SQL Statements with T-SQL The system catalogs in SQL Server 2008 contain a wealth of information you can use to save a lot of time and effort when generating SQL statements that need to be run repeat- edly on a large number of database objects or when trying to build a column list for a query. You can use T-SQL code to select information from the system catalogs, system tables, and system views to generate SELECT statements and the like. For example, say you want to grant EXECUTE permission to the user fred on each stored procedure in the bigpubs2008 database. This can be a tedious task to perform using SSMS because in the Securables dialog for the user fred, you have to select each procedure, one at a time, and click the Grant Execute check box. If there were a large number of procedures, this could be pretty time-consuming, and your mouse-clicking finger would probably get pretty tired. The quicker and easier way would be to build the SQL statements necessary to grant EXECUTE permission to fred on all the stored procedures. The following SELECT statement can be used to generate a SQL script with those commands: select ‘grant execute on ‘ + name + ‘ to fred’ from sys.procedures order by name go grant execute on byroyalty to fred ptg 1683 T-SQL Tips and Tricks 43 grant execute on cursor_proc to fred grant execute on error_handler to fred grant execute on find_books_by_type2 to fred grant execute on gen_sequence to fred grant execute on get_authors to fred grant execute on get_next_item_from_queue to fred grant execute on get_titles to fred grant execute on p_explicit_cols to fred grant execute on p_fetch_explicit_cols to fred grant execute on p_insert_explicit_cols to fred grant execute on reptq1 to fred grant execute on reptq2 to fred grant execute on reptq3 to fred grant execute on SHOW_PARTS_LIST to fred grant execute on title_authors to fred grant execute on trantest to fred grant execute on ytd_sales to fred grant execute on ytd_sales2 to fred You can copy and paste the output from this statement into a query window in SSMS and execute it to grant the desired permissions. When you get to know your system catalog views, you can begin to automate the generation of a number of SQL operations in this manner, freeing up your time to spend on more interesting projects. Working with @@ERROR and @@ROWCOUNT When you are writing T-SQL code that needs to check for both errors and the number of rows affected after your SQL statements, one of the common pitfalls is trying to get both the error status and the number of rows after a SQL statement runs. You have to remem- ber that all SQL statements except the DECLARE statement reset the value of @@ROWCOUNT and @@ERROR to the status of the last command executed. If after a SQL statement you check the value of @@ERROR, the statement used to check @@ERROR resets @@ROWCOUNT. If you check @@ROWCOUNT first, it resets the value of @@ERROR. To check both values, you need to use an assignment SELECT immediately after the SQL state- ment you are checking and capture both values into local variables. Note that you cannot accomplish this with the SET statement because the SET statement allows setting a value to only a single variable at a time. The example in Listing 43.26 provides a way to capture and check both @@ROWCOUNT and @@ERROR after an UPDATE statement in a T-SQL batch. LISTING 43.26 Capturing Both @@ROWCOUNT and @@ERROR After an UPDATE Statement declare @rowcnt int, @error int UPDATE dbo.titles set price = price * 1.10 where type = ‘fiction’ . GA Generating T -SQL Statements with T -SQL The system catalogs in SQL Server 2008 contain a wealth of information you can use to save a lot of time and effort when generating SQL statements that. affected after your SQL statements, one of the common pitfalls is trying to get both the error status and the number of rows after a SQL statement runs. You have to remem- ber that all SQL statements. generation of a number of SQL operations in this manner, freeing up your time to spend on more interesting projects. Working with @@ERROR and @@ROWCOUNT When you are writing T -SQL code that needs to

Ngày đăng: 05/07/2014, 02:20

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

  • Đang cập nhật ...

TÀI LIỆU LIÊN QUAN