Corrections/Comments
 

Home
Books
T-SQL Courses
Resources
Blog
About BG


Inside Microsoft SQL Server 2005: T-SQL Querying

Last modified: 2009-09-15
Note: If you have a later printing of this book, it may already contain the below corrections.

Chapter 01 - Logical Query Processing
Chapter 02 - Physical Query Processing
Chapter 03 - Query Tuning
Chapter 04 - Subqueries, Table Expressions and Ranking Functions
Chapter 05 - Joins and Set Operations
Chapter 06 - Aggregating and Pivoting Data
Chapter 07 - TOP and APPLY
Chapter 08 - Data Modification
Chapter 09 - Graphs, Trees, Hierarchies and Recursive Queries
Appendix A - Logic Puzzles

Inside Microsoft SQL Server 2005: T-SQL Programming

Last modified: 2008-05-21
Note: If you have a later printing of this book, it may already contain the below corrections.

Chapter 01 - Datatype Related Problems, XML, and CLR UDTs
Chapter 02 - Temporary Tables and Table Variables
Chapter 03 - Cursors
Chapter 04 - Dynamic SQL
Chapter 05 - Views
T-SQL and CLR Routines:
  Chapter 06 - User Defined Functions
  Chapter 07 - Stored Procedures
  Chapter 08 - Triggers
Chapter 09 - Transactions
Chapter 10 - Exception Handling
Chapter 11 - Service Broker
Appendix A - Companion to CLR Routines

 

Inside Microsoft SQL Server 2005: T-SQL Querying

Chapter 01 - Logical Query Processing

Date / By Where Correction
2006-05-04
Benjamin Nevarez
Page 8, bottom part of sidebar Currently: "On the other hand, UNIQUE and PRIMARY KEY constraints, sorting, and grouping treat NULLs as equal:
* You cannot insert into a table two rows with a NULL in a column that has a UNIQUE or PRIMARY KEY constraint defined on it."

Error: a PRIMARY KEY constraint cannot be defined on a column that allows NULLs, so the discussion is irrelevant to primary keys.

Should be: "On the other hand, a UNIQUE constraint, sorting, and grouping treat NULLs as equal:
* You cannot insert into a table two rows with a NULL in a column that has a UNIQUE constraint defined on it."

2006-07-23
Itzik Ben-Gan
Page 20, middle of page Currently:
(A) <left_table_expression>
      {CROSS | OUTER} APPLY <table_expression>
Should be:
(A) <left_table_expression>
      {CROSS | OUTER} APPLY <right_table_expression>


Chapter 02 - Physical Query Processing

Date / By Where Correction
2006-10-21
Arik Frenkental
Page 43, Figure 2-7 There should be a "Yes" above the arrow pointing from "Does query qualify for parallel plan?" to "Phase 1 parallel plan".
2007-07-03
Lindsey Allen
Page 51, URL in More Info box Currently: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsql90/html/xmlshowplans.asp

Should be: http://msdn2.microsoft.com/en-us/library/ms345130.aspx


Chapter 03 - Query Tuning

Date / By Where Correction
2006-11-27
Bill Ziss
Page 68, Listing 3-1, CASE expression in INSERT INTO dbo.Orders statement Currently:
CASE WHEN n % 10 = 0
  THEN THEN 1 + ABS(CHECKSUM(NEWID())) % 30
  ELSE 0
END AS orderdate
Error: "THEN" is repeated

Should be:
CASE WHEN n % 10 = 0
  THEN 1 + ABS(CHECKSUM(NEWID())) % 30
  ELSE 0
END AS orderdate
2007-10-14
T. Wong, Arik Frenkental
 
Page 73, end of 3rd line from bottom Currently: signal_wait_time

Should be: signal_wait_time_ms
2006-08-06
Miri Elani
Page 81, Table 3-3, Column counter_name Currently:
counter_name
----------------------------
Buffercachehitratio
Buffer cache hit ratio base
Pagelookups/sec
Freeliststalls/sec
Freepages
Totalpages
Targetpages
Databasepages
Reservedpages
Stolenpages

Should be:
counter_name
----------------------------
Buffer cache hit ratio
Buffer cache hit ratio base
Page lookups/sec
Free list stalls/sec
Free pages
Total pages
Target pages
Database pages
Reserved pages
Stolen pages
2006-02-15
Eric Mamet
Pages 101, 102, 103, queries against #AggQueries, calculation of duration in seconds (result columns total_s and running_total_s)

The duration column reported in traces in SQL Server 2000 was expressed in millisecond units, but in SQL Server 2005 it is expressed in microseconds. Therefore, in order to calculate the duration in seconds, the value should be divided by 1000000 instead of by 1000. This is relevant to the queries in pages 101, 102 and 103. In the calculation of the result columns total_s and running_total_s the expression is currently: / 1000, and should be: / 1000000. Consequentially, the values in Table 3-13, columns total_s and running_total_s should reflect this change. Note that this does not have any impact on the percentage calculations discussed in that section.

2006-09-24
Micah Nikkel
Pages 132-155, section "Index Access Methods", all references to unordered index scans (clustered or nonclustered) Currently the text says that when SQL Server needs to fully scan the leaf level of an index in no particular order (access method shows Ordered: False in execution plan) it will rely on IAM pages (aka allocation order scans). Recent findings shed new light on ordered vs. unordered index scans. I urge you to read a three-part article that I wrote on the subject after the book was published: Part I, Part II, Part III. The article contains more recent information on the subject.
2006-07-23
Itzik Ben-Gan
Page 132, under "Index Access Methods", second paragraph, lines 2-4 Currently:
"I'll be discussing some access methods to use against the Orders table that are structured as a heap and some that are structured as a clustered table."

Should be:
"I'll be discussing some access methods to use against the Orders table, both when it's structured as a heap and when it's structured as a clustered table."
2006-07-23
Itzik Ben-Gan
Page 137, lines 3-4 from the top Currently:
"With no fragmentation at all, the performance of an ordered scan of an index should be very close to the performance of an ordered scan, because both will end up reading the data physically in a sequential manner."

Should be:
"With no fragmentation at all, the performance of an ordered scan of an index should be very close to the performance of an unordered scan, because both will end up reading the data physically in a sequential manner."

2007-10-14
T. Wong

Page 139, first sentence Currently: "An ordered index scan is not used only when you explicitly request the data sorted; rather, it is also used when..."

Should be: "An ordered index scan is used not only when you explicitly request the data sorted; rather, it is also used when..."

2006-05-27
Itzik Ben-Gan

Page 140, middle of paragraph following the query Currently: "Our access method first performs a seek within the index to find the first key in the sought range (orderid = 101). The second part of the access method is an ordered partial scan in the leaf level from the first key in the range until the last (orderid = 101)."
Should be: "Our access method first performs a seek within the index to find the first key in the sought range (orderid = 101). The second part of the access method is an ordered partial scan in the leaf level from the first key in the range until the last (orderid = 120)."

2006-11-27
Bill Kan

Page 141, bottom paragraph Currently: "Note that in the execution plan you won’t explicitly see the partial scan part of the access method; rather, it’s hidden in the Index Scan operator."
Should be: "
Note that in the execution plan you won’t explicitly see the partial scan part of the access method; rather, it’s hidden in the Index Seek operator."

2006-05-27
Lilach Ben-Gan

Page 143, captions of figures 3-34 and 3-35 Last word in figure captions should be table not tale

2007-04-29
Benjamin Nevarez

Page 143, Figure 3-35
Page 147, Figure 3-39
Page 158, Figure 3-49
Page 159, Figure 3-50
Page 160, Figure 3-52
Page 160, Figure 3-52

 
Change in representation of a bookmark lookup on a table with a clustered index in graphical execution plan in SQL Server 2005 Service Pack 2:
Prior to Service Pack 2, the graphical execution plan showed a Clustered Index Seek operator to represent a bookmark lookup on a table with a clustered index. This was a correct representation of reality, but confused people. In Service Pack 2 a bookmark lookup on a table with a clustered index is now represented as a Key Lookup operator.
Therefore, if you examine the execution plans for the queries in the book involving bookmark lookup on a table with a clustered index (not just in Chapter 3, rather throughout the book), you will get slightly different plans than the ones in the book's figures. The meaning of the plans is still the same of course.
For details, please refer to: http://msdn2.microsoft.com/en-us/library/bb326635.aspx.

2006-05-27
Itzik Ben-Gan

Page 158, second sentence after Figure 3-49 Currently: "As the selectivity of the query grows larger, the more substantial the cost is of the lookups here."
Should be: "As the selectivity of the query gets lower (low selectivity = high percentage of rows), the more substantial the cost is of the lookups here."

2006-06-01
Stephen Hunt

Page 162, instruction to restore the original clustered index just before the section "Covering Nonclustered Index Seek + Ordered Partial Scan" Currently: "Before proceeding to the next step, restore the original clustered index:
DROP INDEX dbo.Orders.idx_cl_oid;
CREATE UNIQUE CLUSTERED INDEX idx_cl_od ON dbo.Orders(orderid);"
Should be: "Before proceeding to the next step, restore the original clustered index:
DROP INDEX dbo.Orders.idx_cl_oid;
CREATE CLUSTERED INDEX idx_cl_od ON dbo.Orders(orderdate);"

2006-06-27
Itzik Ben-Gan

Page 163 Table 3-16, Page 164 Figure 3-55, Page 164 Table 3-17, Page 165 Figure 3-56, Page 166 Figure 3-57 Access method currently called: "Unordered Covering Nonclustered Index Scan + Lookups"

Error: the word "covering" was added in these tables/figures to the access method's name by mistake.

Should be: "Unordered Nonclustered Index Scan + Lookups"

2007-07-17
zhao lidong

Page 168, second paragraph, third sentence Currently: "While logical scan fragmentation is never a good thing, average scan fragmentation has two facets."
Should be: "While logical scan fragmentation is never a good thing, average page density has two facets."

2006-05-27
Itzik Ben-Gan

Page 173, second paragraph, second sentence Currently: "Ideally, you should be thinking about the number of customers, the number of different order dates, and so on."
Should be: "Ideally, you should be thinking about realistic distribution of session start times, session duration, and so on."

2006-05-27
Lilach Ben-Gan

Page 173, caption of Listing 3-7 Currently: "Populate sessions with inadequate sample data"
Should be: "Populate BigSessions with inadequate sample data"

2008-10-24
Rudolf

Page 179, quote of Steve Kass Currently: Quoted text says that there are 4 pages, 3 with 179 rows and 1 with 37 however most of the following calculations infer 5 pages with 4 of them with 179 rows and 1 with 37.
Should be: The correct numbers are 5 pages, 4 with 179 rows and 1 with 37.

2006-05-27
Lilach Ben-Gan

Page 180, sentence before last Currently: "There are still many performance improvements to gain merely from the changing way you write your code."
Should be: "There are still many performance improvements to gain merely from changing the way you write your code."

2007-07-17
zhao lidong

Page 187, third sentence after Figure 3-66 Currently: "If the answer is yes, ..."
Should be: "If the answer is no, ..."


Chapter 04 - Subqueries, Table Expressions and Ranking Functions

Date / By Where Correction
2006-09-11
Michael O Fourie
Page 192, Fourth paragraph

Currently: " ..., and a third time with LIKE N'D%: "
Error: missing closing quote
Should be: " ..., and a third time with LIKE N'D%': "

2006-07-23
Stephen M. Schissler
Page 203, Third line

Currently: "The predicate b NOT IN (a, b, NULL) therefore returns NOT UNKNOWN..."
Should be: "The predicate c NOT IN (a, b, NULL) therefore returns NOT UNKNOWN..."

2007-10-14
zhao lidong
Page 203, 1st paragraph, last sentence

Currently: "To make the NOT IN query logically equivalent to the EXISTS query..."
Should be: "To make the NOT IN query logically equivalent to the NOT EXISTS query..."

2007-10-14
T. Wong

Page 206, 2nd paragraph, 2nd to last sentence

Currently:
"… the filter generates an empty set and the expression MIN(keycol) + 1 yields a NULL."

Should be:
"… the filter generates an empty set and the expression MIN(keycol + 1) yields a NULL."


Chapter 05 - Joins and Set Operations

Date / By Where Correction
2006-06-27
Itzik Ben-Gan
Page 272, Bottom Note box, first sentence

Currently: "Changing the compatibility mode of a database to an earlier version will prevent you from using the new language elements (for example, ranking functions, recursive queries, and so on)."
Should be: "Changing the compatibility mode of a database to an earlier version will prevent you from using some of the new language elements (for example, PIVOT, UNPIVOT, and so on)."

2006-07-23
Itzik Ben-Gan
Page 275, first sentence after table 5-2

Currently: "Note that the outer rows represent the points before the gaps because the next highest key value is missing."
Should be: "Note that the outer rows represent the points before the gaps because the next key value is missing."


Chapter 06 - Aggregating and Pivoting Data

Date / By Where Correction
2007-07-17
zhao lidong
Page 328, first sentence after Note box Currently: "The main difference between the solution for cumulative aggregates and the solution for running aggregates is in the join condition..."
Should be: "The main difference between the solution for cumulative aggregates and the solution for sliding aggregates is in the join condition..."
2006-03-29
Lilach Ben-Gan
Page 335, Tip box, second paragraph, second sentence Currently: "If you need to pivot more that one column’s attributes..."
Should be: "If you need to pivot more than one column’s attributes..."
2006-03-29
Lilach Ben-Gan
Page 340, caption of Table 6-16 Currently: "Count of Yearly Quantities per" Customer"
Should be: "Count of Yearly Orders per Customer"
2007-07-17
zhao lidong
Page 356, step 15, line 5 Currently: reference to StructLayout.LayoutKindSequential attribute
Should be: StructLayout.LayoutKind.Sequential
2009-09-15 /
Tóth Rudolf, Adam Machanic
Chapter 6, Page 360, First (and only) query in page
Currently:

SELECT groupid,
  CAST(ROUND(EXP(SUM(LOG(ABS(NULLIF(val,0)))))*
    (1-SUM(1-SIGN(val))%4)*(1-SUM(1-SQUARE(SIGN(val)))),0) AS INT)
  AS product
FROM dbo.Groups
GROUP BY groupid;


Should be:

SELECT groupid,
  COALESCE(CAST(ROUND(EXP(SUM(LOG(ABS(NULLIF(val,0)))))*
    (1-SUM(1-SIGN(val))%4)*MIN(ABS(SIGN(val))),0) AS INT), MAX(val))
  AS product
FROM dbo.Groups
GROUP BY groupid;
2006-03-29
Lilach Ben-Gan
Page 364, captions of columns in Table 6-24 Currently: groupid, agg_or, agg_or_binval
Should be: groupid, agg_and, agg_and_binval
2006-03-29
Lilach Ben-Gan
Page 364, captions of columns in Table 6-25 Currently: groupid, agg_or, agg_or_binval
Should be: groupid, agg_xor, agg_xor_binval


Chapter 07 - TOP and APPLY

Date / By Where Correction
2007-10-14
zhao lidong
Page 412, second paragraph from bottom, first sentence Currently: "CHECKSUM returns an integer between 2147483648 and 2147483647."

Should be: "CHECKSUM returns an integer between -2147483648 and 2147483647."


Chapter 08 - Data Modification

Date / By Where Correction
2006-06-27
Lilach Ben-Gan
Page 431, Lines 1 and 4 from bottom; Page 432, Lines 1 and 6 from top References in text to temporary table currently called: #CustStage

Error: typo in text references to table name.

Should be: #CustsStage

2006-06-27
Lilach Ben-Gan
Page 434, Second sentence right after the Note box References in text to stored procedure currently called: usp_AsyncSec

Error: typo in text references to stored procedure name.

Should be: #usp_AsyncSeq

2006-07-06
Lilach Ben-Gan
Page 441, Last sentence Currently:
"...which creates the LargeOrders tables..."
Should be:
"...which creates the LargeOrders table..."
2007-10-14
T. Wong
Page 445, last paragraph, 2nd sentence Currently: "When you modify the table on the "many" side of a one-to-many join..."

Should be: "When you modify the table on the "one" side of a one-to-many join..."
2006-07-06
Itzik Ben-Gan
Page 445, UPDATE UPDATE statement at top of page Currently:
UPDATE dbo.Orders
  SET (ShipCountry, ShipRegion, ShipCity) =
    (SELECT Country, Region, City
     FROM dbo.Customers AS C
     WHERE C.CustomerID = dbo.Orders.CustomerID);
WHERE C.Country = 'USA';

Should be:
UPDATE dbo.Orders
  SET (ShipCountry, ShipRegion, ShipCity) =
    (SELECT Country, Region, City
     FROM dbo.Customers AS C
     WHERE C.CustomerID = dbo.Orders.CustomerID)
WHERE CustomerID IN
  (SELECT CustomerID FROM dbo.Customers WHERE Country = 'USA');

2006-07-06
Itzik Ben-Gan
Page 448, Item 2 in the numbered list at the bottom of the page Currently:
"2. Lock one available new message using an UPDATE TOP(@n) statement with the READPAST hint to skip locked rows, and change its status to 'open'. @n represents a configurable input that determines the maximum number of messages to process in each iteration."

Should be:
"2. Lock @n available new messages using an UPDATE TOP(@n) statement with the READPAST hint to skip locked rows, and change their status to 'open'. @n represents a configurable input that determines the maximum number of messages to process in each iteration."


Chapter 09 - Graphs, Trees, Hierarchies and Recursive Queries

Date / By Where Correction
2006-07-06
Lilach Ben-Gan
Page 480, Last sentence before Listing 9-8 Currently: "Run the code in Listing 9-8 to create the fn_subordinates2 function, which is a revision of fn_subordinates2 that also supports a level limit."

Should be: "Run the code in Listing 9-8 to create the fn_subordinates2 function, which is a revision of fn_subordinates1 that also supports a level limit."
2007-07-17
zhao lidong
Page 493, comment before creation of temp table #SubsSort in Listing 9-16 Currently: "-- #SubsPath is a temp table that will hold the final"

Should be: "-- #SubsSort is a temp table that will hold the final"
2007-07-17
Itzik Ben-Gan
Page 494, comment before last INSERT statement in Listing 9-16 Currently: "-- Load the rows from #SubsPath to @SubsSort..."

Should be: "-- Load the rows from #SubsPath to #SubsSort..."
2007-07-17
zhao lidong
Page 485, comment in Listing 9-11 Currently: "-- and previous level < @maxlevels"

Should be: "-- and previous level <= @maxlevels"
2007-07-17
zhao lidong
Page 506, sixth line from bottom of page Currently: "...and its path is: parent path + 'employee id..."

Should be: "...and its path is: parent path + employee id..."
2006-07-06
Lilach Ben-Gan
Page 513, Text at top of page before the first query in the page Currently: "Let’s review typical requests from a tree. For each request, I’ll provide a sample query followed by its output (shown in Table 9-35).
Return the subtree with a given root:"

Should be: "Let’s review typical requests from a tree. For each request, I’ll provide a sample query followed by its output.
Return the subtree with a given root, generating the output shown in Table 9-35:"
2007-07-17
zhao lidong
Page 533, first sentence after Table 9-50 Currently: "...in the BOMCTE..."

Should be: "...in the BOMTC..."


Appendix A - Logic Puzzles

Date / By Where Correction
2006-07-23
Richard Siddaway
Page 562, answer to puzzle 10, first sentence in puzzle answer Currently: "All the lamps are off except for lamps number 1, 4, 9, 16, 25, 49, 64, 81, and 100, which are on."

Error: 36 should also be in the list.

Should be: "All the lamps are off except for lamps number 1, 4, 9, 16, 25, 36, 49, 64, 81, and 100, which are on."
2006-05-09
Itzik Ben-Gan
Page 567, answer to puzzle 19, last sentence in puzzle answer Currently: "Here’s the first part of the sequence with a few additional numbers: 4, 3, 3, 5, 4, 4, 3, 5, 5, 4, 3, 6, 6, 8, 8, 7, 7, 9, 8, 8, 6, 9, 9, 11, 10, 10, 9, 11, 11, 10, …"

Error: the first number in the sequence (4) was added by mistake.

Should be: "Here’s the first part of the sequence with a few additional numbers: 3, 3, 5, 4, 4, 3, 5, 5, 4, 3, 6, 6, 8, 8, 7, 7, 9, 8, 8, 6, 9, 9, 11, 10, 10, 9, 11, 11, 10, …"

 

Inside Microsoft SQL Server 2005: T-SQL Programming

Chapter 01 - Datatype Related Problems, XML, and CLR UDTs

Date / By Where Correction

2007-10-14
Matthew Bryde

Page 11, Last sentence in first paragraph Currently: sentence starts with "I'll cover discuss three techniques..."

Should be: "I'll cover three techniques..."

2008-05-21
Dan Vilnoiu

Pages 17 Query at bottom of page Currently:

SELECT app,
  (SELECT COUNT(*) FROM dbo.Sessions AS C
   WHERE ts >= starttime
     AND ts < endtime) AS cnt
FROM (SELECT DISTINCT app, starttime AS ts
      FROM dbo.Sessions) AS T;

Should be:

SELECT app,
  (SELECT COUNT(*) FROM dbo.Sessions AS C
   WHERE C.app = T.app
     AND ts >= starttime
     AND ts < endtime) AS cnt
FROM (SELECT DISTINCT app, starttime AS ts
      FROM dbo.Sessions) AS T;

2008-05-21
Dan Vilnoiu

Pages 18 Currently:

SELECT app, MAX(cnt) AS mx
FROM (SELECT app,
        (SELECT COUNT(*) FROM dbo.Sessions AS C
         WHERE ts >= starttime
           AND ts < endtime) AS cnt
      FROM (SELECT DISTINCT app, starttime AS ts
            FROM dbo.Sessions) AS T) AS D
GROUP BY app;

Should be:

SELECT app, MAX(cnt) AS mx
FROM (SELECT app,
        (SELECT COUNT(*) FROM dbo.Sessions AS C
         WHERE C.app = T.app
           AND ts >= starttime
           AND ts < endtime) AS cnt
      FROM (SELECT DISTINCT app, starttime AS ts
            FROM dbo.Sessions) AS T) AS D
GROUP BY app;

2006-10-02
Feelanet

Page 32, Definition of table CustomerData Currently:
CREATE TABLE dbo.CustomerData
(
  custid      INT            NOT NULL PRIMARY KEY,
  txt_data    VARCHAR(MAX)   NULL,
  ntxt_data   NVARCHAR(MAX)  NULL,
  binary_data VARBINARY(MAX) NULL
);
Error: Missing definition of column xml_data.

Should be:
CREATE TABLE dbo.CustomerData
(
  custid      INT            NOT NULL PRIMARY KEY,
  txt_data    VARCHAR(MAX)   NULL,
  ntxt_data   NVARCHAR(MAX)  NULL,
  binary_data VARBINARY(MAX) NULL,
  xml_data    XML            NULL
);

2007-03-04
Zhao Lidong

Page 39, second paragraph, second sentence

Currently: "In SQL Server 7.0, the BIT value was converted to an INT because that's how filters worked."
Should be: "In SQL Server 7.0, the INT value was converted to a BIT because that's how filters worked."

2006-11-27
Herbert Albert

Page 47, first sentence in last paragraph before the section "Language for Creating UDTs"

Currently: “Note that as mentioned earlier in the chapter, the XML datatype can be adequate to store the state of the objects using XML serialization in a database as well.”

Error: this is mentioned later in the chapter; not earlier.

Should be: “Note that the XML datatype can be adequate to store the state of the objects using XML serialization in a database as well.”

2006-07-09
Tom Moreau

Page 55, Definition of DivCN method Currently:
// Division
public ComplexNumberCS DivCN(ComplexNumberCS c)
{
    // null checking
    if (this._isnull || c._isnull)
        return new ComplexNumberCS(true);
    // division
    return new ComplexNumberCS(
        (this.Real * c.Real + this.Imaginary * c.Imaginary)
          / (c.Real * c.Real + c.Imaginary * c.Imaginary),
        (this.Imaginary * c.Real - this.Real * c.Imaginary)
          / (c.Real * c.Real + c.Imaginary * c.Imaginary)
        );
}

Error: Missing check for divide by zero error.

Should be:
// Division
public ComplexNumberCS DivCN(ComplexNumberCS c)
{
    // null checking
    if (this._isnull || c._isnull)
        return new ComplexNumberCS(true);
    // zero checking
    if (c.Real == 0 && c.Imaginary == 0)
        throw new ArgumentException();
    // division
    return new ComplexNumberCS(
        (this.Real * c.Real + this.Imaginary * c.Imaginary)
          / (c.Real * c.Real + c.Imaginary * c.Imaginary),
        (this.Imaginary * c.Real - this.Real * c.Imaginary)
          / (c.Real * c.Real + c.Imaginary * c.Imaginary)
        );
}

2006-07-06
Tom Moreau

Page 56, CREATE ASSEMBLY statement right after first paragraph Currently:
CREATE ASSEMBLY ComplexNumberCS
FROM '\ComplexNumberCS\ComplexNumberCS\bin\Debug\ComplexNumberCS.dll'
WITH PERMISSION_SET = SAFE;


Error: drive letter is missing from the path to the DLL.

Should be:
CREATE ASSEMBLY ComplexNumberCS
FROM 'C:\ComplexNumberCS\ComplexNumberCS\bin\Debug\ComplexNumberCS.dll'
WITH PERMISSION_SET = SAFE;

2006-07-13
Stephen Hunt

Page 58, First paragraph, First sentence

Currently: "You can see that the second complex number (2, 3i) is sorted before the first one (2, 3i)"
Should be: "You can see that the second complex number (1, 7i) is sorted before the first one (2, 3i)"

2007-03-04
Zhao Lidong

Page 60, caption of Listing 1-4

Currently: "C# .NET-based ComplexNumberCS UDA"
Should be: "C# .NET-based ComplexNumberCS_SUM UDA"

2006-09-17
Tom Moreau, Feelanet

Pages 63, 64, Listing 1-5 Definition of #Region "arithmetic operations" Currently:
#Region "arithmetic operations"

    ' Addition
    Public Function AddCN(ByVal c As ComplexNumberVB) As ComplexNumberVB
        'Null(checking)
        If Me.isNullValue Or c.isNullValue Then
            Return New ComplexNumberVB(True)
        End If
        ' addition
        Return New ComplexNumberVB(Me.Real + c.Real, _
            Me.Imaginary + c.Imaginary)
    End Function

    ' Subtraction
    Public Function SubCN(ByVal c As ComplexNumberVB) As ComplexNumberVB
        'Null(checking)
        If Me.isNullValue Or c.isNullValue Then
            Return New ComplexNumberVB(True)
        End If
        ' addition
        Return New ComplexNumberVB(Me.Real - c.Real, _
            Me.Imaginary - c.Imaginary)
    End Function

    ' Multiplication
    Public Function MulCN(ByVal c As ComplexNumberVB) As ComplexNumberVB
        'Null(checking)
        If Me.isNullValue Or c.isNullValue Then
            Return New ComplexNumberVB(True)
        End If
        ' addition
        Return New ComplexNumberVB(Me.Real * c.Real - _
          Me.Imaginary * c.Imaginary, _
            Me.Imaginary * c.Real + Me.Real * c.Imaginary)
    End Function

    ' Division
    Public Function DivCN(ByVal c As ComplexNumberVB) As ComplexNumberVB
        'Null(checking)

          If Me.isNullValue Or c.isNullValue Then
              Return New ComplexNumberVB(True)
          End If
          ' addition
          Return New ComplexNumberVB(_
              (Me.Real * c.Real + Me.Imaginary * c.Imaginary) _
                / (c.Real * c.Real + c.Imaginary * c.Imaginary), _
              (Me.Imaginary * c.Real - Me.Real * c.Imaginary) _
                / (c.Real * c.Real + c.Imaginary * c.Imaginary) _
          )
    End Function

#End Region
Error: Missing check for divide by zero error, and comment specifying arithmetic operation is currently addition in all operations by mistake.

Should be:

#Region "arithmetic operations"

    ' Addition
    Public Function AddCN(ByVal c As ComplexNumberVB) As ComplexNumberVB
        'Null(checking)
        If Me.isNullValue Or c.isNullValue Then
            Return New ComplexNumberVB(True)
        End If
        ' addition
        Return New ComplexNumberVB(Me.Real + c.Real, _
            Me.Imaginary + c.Imaginary)
    End Function

    ' Subtraction
    Public Function SubCN(ByVal c As ComplexNumberVB) As ComplexNumberVB
        'Null(checking)
        If Me.isNullValue Or c.isNullValue Then
            Return New ComplexNumberVB(True)
        End If
        ' subtraction
        Return New ComplexNumberVB(Me.Real - c.Real, _
            Me.Imaginary - c.Imaginary)
    End Function

    ' Multiplication
    Public Function MulCN(ByVal c As ComplexNumberVB) As ComplexNumberVB
        'Null(checking)
        If Me.isNullValue Or c.isNullValue Then
            Return New ComplexNumberVB(True)
        End If
        ' multiplication
        Return New ComplexNumberVB(Me.Real * c.Real - _
          Me.Imaginary * c.Imaginary, _
            Me.Imaginary * c.Real + Me.Real * c.Imaginary)
    End Function

    ' Division
    Public Function DivCN(ByVal c As ComplexNumberVB) As ComplexNumberVB
        'Null(checking)
        If Me.isNullValue Or c.isNullValue Then
            Return New ComplexNumberVB(True)
        End If
        'Zero checking
        If c.Real = 0 And c.Imaginary = 0 Then
            Throw New ArgumentException()
        End If
        ' division
        Return New ComplexNumberVB( _
            (Me.Real * c.Real + Me.Imaginary * c.Imaginary) _
              / (c.Real * c.Real + c.Imaginary * c.Imaginary), _
            (Me.Imaginary * c.Real - Me.Real * c.Imaginary) _
              / (c.Real * c.Real + c.Imaginary * c.Imaginary) _
          )
    End Function

#End Region

2006-07-06
Tom Moreau

Page 69, Instructions at bottom of page to copy Visio files

Currently: "...and copy the .vsd files..."
Should be: "...and copy the .vdx files..."

2007-03-06
Zhao Lidong

Page 71, Second sentence after Table 1-21

Currently: "The method returns a scalar .value"
Should be: "The method returns a scalar value"

2006-07-13
Stephen Hunt

Page 74, First paragraph, Second sentence

Currently: "After creating the Primary XML index, you can create up to three secondary XML Indexes:"
Should be: "After creating the Primary XML index, you can create three other types of secondary XML Indexes:"

2006-07-06
Tom Moreau

Page 77, INSERT statement at bottom of page; Page 78, Error message; Page 82, UPDATE statement at bottom of page

Currently: references in code and text to element/word "Hobbie"
Should be: "Hobby"

2006-10-25
Lorenzo Benaglia

Page 78, second paragraph

Currently: "To explain other aspects of the XML data type, I'll need to insert a contact who speaks two foreign languages. Therefore, you will change the OtherAttributes XML column from schema-validated back to well-formed." 

Error: To obtain the same result, it's not required to remove the schema binding with the XML column, so you can validate the XML fragments against the XSD Schema.

Should be: "To explain other aspects of the XML data type, I'll need to insert a contact who speaks two foreign languages. Therefore, you will change the schema associated to the OtherAttributes XML column using the minOccurs and maxOccurs XML Representation Attributes."

You can find more details on the subject in SQL Server MVP Lorenzo Benaglia’s blog entry (http://blogs.dotnethell.it/lorenzo/Post_7895.aspx).


Chapter 02 - Temporary Tables and Table Variables

Date / By Where Correction

2007-03-06
Zhao Lidong

Page 89, Last Paragraph, Line 2

Currently: "...2) use a temporary table..."
Should be: "...2) using a temporary table..."

2006-07-13
Tom Moreau

Page 92, First paragraph, Line 1

Currently: "though proc2's code creates a table called #T2"
Should be: "though proc2's code creates a table called #T1"

2006-07-13
Tom Moreau

Pages 93, 94, all references in code to table #T42 (6 references in total)

Currently: #T42
Should be: #T

2006-08-16
Feelanet

Pages 98, 100, code samples populating @T and #T, expression calculating col2

Currently: (n - 1) % 100000 + 1
Should be: (n - 1) % 10000 + 1

Note: this change will impact the cost estimates of the operators in Figure 2-3 and the statistics I/O measures that you will get when running the code against #T1. But the rest remains the same, and the points made in the discussion are just as valid.


Chapter 03 - Cursors

Date / By Where Correction

2006-09-10
Itzik Ben-Gan

Page 119, Caption of Listing 3-3

Currently: "Cursor code for custom aggregate"
Should be: "Cursor code for running aggregations"

2006-09-10
Itzik Ben-Gan

Page 121, Inline caption in Figure 3-1

Currently: "Max Concurrent Sessions Benchmark"
Should be: "Running Aggregations Benchmark"


Chapter 04 - Dynamic SQL

Date / By Where Correction

2007-10-14
Itzik Ben-Gan

Pages 160 - 166, section about Dynamic Filters

This is not a correction rather a suggestion for additional reading (strongly recommended). SQL Server MVP Erland Sommarskog wrote a great paper about the subject here.

2006-08-04
Feelanet

Page 148, Sixth line (third bullet point)

Currently: "Use the sp_droplinkedsrvlogin stored procedure to map local logins to a security account on the remote server."
Should be: "Use the sp_addlinkedsrvlogin stored procedure to map local logins to a security account on the remote server."

2007-02-15
Zhao Lidong

Pages 157, 158, Listing 4-3

Currently: comments saying "-- If only one row was inserted, don't use a cursor" and "-- If only multiple rows were inserted, use a cursor"
Should be: "-- If only one row was affected, don't use a cursor" and "-- If only multiple rows were affected, use a cursor"

2006-08-16
Feelanet

Page 160, Caption of Table 4-6

Currently: "Table 4-6 Contents of Computations Table After Inserts"
Should be: "Table 4-6 Contents of Computations Table After Updates"

2006-11-13
Morten Munch-Andersen

Page 168, 169, Listings 4-7, 4-8

Currently:
"...
OR UPPER(@cols) LIKE UPPER(N'%xp_%')
OR UPPER(@cols) LIKE UPPER(N'%sp_%')
..."

Error: in the lines of code referring to the patterns N'%sp_%' and N'%xp_%', _ (underscored) is treated as a wildcard instead of as a character. The fix is to use N'%sp[_]%' and N'%xp[_]%'.

Should be:
"...
OR UPPER(@cols) LIKE UPPER(N'%xp[_]%')
OR UPPER(@cols) LIKE UPPER(N'%sp[_]%')
..."

2006-07-23
Tom Moreau

Page 178, Second line

Currently: "I will discussed..."
Should be: "I will discuss..."


Chapter 05 - Views

Date / By Where Correction

2006-06-26
Benjamin Nevarez

Page 202, bottom paragraph, third line Currently text refers to a view called: sys.sql.modules
Should be: sys.sql_modules

2006-08-16
Feelanet

Page 195, code defining VSgn view Currently:
CREATE VIEW dbo.VSgn
AS

SELECT Cur.mnth, Cur.qty, SIGN(Cur.qty - Prv.qty) AS sgn
FROM dbo.VSalesRN AS Cur
  JOIN dbo.VSalesRN AS Prv
    ON Cur.rn = Prv.rn + 1;
GO


Should be:
CREATE VIEW dbo.VSgn
AS

SELECT Cur.mnth, Cur.qty, SIGN(Cur.qty - Prv.qty) AS sgn
FROM dbo.VSalesRN AS Cur
  LEFT OUTER JOIN dbo.VSalesRN AS Prv
    ON Cur.rn = Prv.rn + 1;
GO

2007-07-17
Matthew Wise, zhao lidong

Page 197, Listing 5-2, code defining CSgn CTE Currently:
...
CSgn AS
(
  SELECT Cur.mnth, Cur.qty, SIGN(Cur.qty - Prv.qty) AS sgn
  FROM CSalesRN AS Cur
    JOIN CSalesRN AS Prv
      ON Cur.rn = Prv.rn + 1
)
...

Should be:
...
CSgn AS
(
  SELECT Cur.mnth, Cur.qty, SIGN(Cur.qty - Prv.qty) AS sgn
  FROM CSalesRN AS Cur
    LEFT OUTER JOIN CSalesRN AS Prv
      ON Cur.rn = Prv.rn + 1
)
...


Chapter 06 - User Defined Functions


Chapter 07 - Stored Procedures

Date / By Where Correction

2007-10-14
Erland Sommarskog

Page 288, First bullet point after the first paragraph in the section EXECUTE AS

Currently: "The stored procedure and the underlying objects belong to the same schema."

Should be: "The stored procedure and the underlying objects belong to the same owner."

2006-11-13
Morten Munch-Andersen

Page 303, Listing 7-9

Currently:
"...
OR UPPER(@cols) LIKE UPPER(N'%xp_%')
OR UPPER(@cols) LIKE UPPER(N'%sp_%')
..."

Error: in the lines of code referring to the patterns N'%sp_%' and N'%xp_%', _ (underscored) is treated as a wildcard instead of as a character. The fix is to use N'%sp[_]%' and N'%xp[_]%'.

Should be:
"...
OR UPPER(@cols) LIKE UPPER(N'%xp[_]%')
OR UPPER(@cols) LIKE UPPER(N'%sp[_]%')
..."


Chapter 08 - Triggers

Date / By Where Correction

2007-01-21
Chris Bohling

Page 332, Last query in Listing 8-4 Currently:
SELECT COLUMN_NAME AS updated_column
FROM INFORMATION_SCHEMA.COLUMNS AS C JOIN @UpdCols AS U
  ON C.ORDINAL_POSITION = U.ordinal_position
WHERE TABLE_SCHEMA = 'dbo'
  AND TABLE_NAME = 'T1'
ORDER BY C.ORDINAL_POSITION;

Error: according to Books Online (http://msdn2.microsoft.com/en-us/library/ms186329.aspx): "In SQL Server 2005, the ORDINAL_POSITION column of the INFORMATION_SCHEMA.COLUMNS view is not compatible with the bit pattern of columns returned by COLUMNS_UPDATED. To obtain a bit pattern compatible with COLUMNS_UPDATED, reference the ColumnID property of the COLUMNPROPERTY system function when you query the INFORMATION_SCHEMA.COLUMNS view."

Should be:

SELECT COLUMN_NAME AS updated_column
FROM INFORMATION_SCHEMA.COLUMNS AS C JOIN @UpdCols AS U
  ON COLUMNPROPERTY(OBJECT_ID(QUOTENAME(TABLE_SCHEMA)
                              + '.' + QUOTENAME(TABLE_NAME)),
                    COLUMN_NAME, 'ColumnID') = U.ordinal_position
WHERE TABLE_SCHEMA = 'dbo'
  AND TABLE_NAME = 'T1'
ORDER BY U.ORDINAL_POSITION;

2007-03-02
Zhao Lidong

Page 335, first sentence Currently:
"Query the tables T1Audit and T1A..."
Should be:
"Query the tables T1Audit and T1..."

2006-07-26
Philipp Ohnemus

Page 335, Captions of Tables 8-3 and 8-4 Currently:
"Table 8-3 Contents of T1Audit"
"Table 8-4 Contents of T1"
Should be:
"Table 8-3 Contents of T1"
"Table 8-4 Contents of T1Audit"

2006-08-06
Tom Moreau

Page 346-351, Use of .query method

Currently the .query method is used to extract an element from the XML value containing the DDL event info. Specifically with DDL triggers this works since currently there are no cases with multiple elements with the same name at the same level. But in general, XML allows multiple elements with the same name at the same level (in which case the .query method would return all of them). In general, when you're after a single value, it is more appropriate to use the .value method where you can specify an index (ordinal).
So in all of the code samples that are supposed to extract a scalar value instead of using the .query method, use the following form of the .value method:
xml_value.value('(<path_to_element>)[1]', <sql_type>)
For example, here's the expression you need to use in the code samples in the chapter to extract the object name from the variable @eventdata:
@eventdata.value('(/EVENT_INSTANCE/ObjectName)[1]', 'sysname')
You can find the revised source code for DDL Triggers in Chapter 8 here.

2007-03-02
Zhao Lidong

Page 353, line comment in first code snippet in page Currently:
"Create login and grant it with unsafe permission level"
Should be:
"Create login and grant it with external permission level"

2007-03-02
Zhao Lidong

Page 354, Listing 8-13, first line comment in page Currently:
"Check whether the action is Insert"
Should be:
"Check type of action"

2007-03-02
Zhao Lidong

Page 357, Listing 8-14, first line comment in second block of code

Currently:
"Check whether the action is Insert"
Should be:
"Check type of action"


Chapter 09 - Transactions

Date / By Where Correction

2006-06-13
Benjamin Nevarez

Page 373, beginning of second sentence from page bottom Currently: "You get the output 'Version 2', ..."
Should be: "You get the output 'Version 1', ..."

2006-06-13
Benjamin Nevarez

Page 374, beginning of second sentence from page top Currently: "You still get 'Version 2' back, ..."
Should be: "You still get 'Version 1' back, ..."

2006-09-22
Feelanet

Page 388, Line 10 from bottom of page Currently: "...that T1.col2 is set to 102..."
Should be: "...that T1.col1 is set to 102..."


Chapter 10 - Exception Handling

Date / By Where Correction

2007-02-15
Zhao Lidong

Page 405, second paragraph, first sentence Currently: "The TRY block then sets @retry to 0 ..."
Should be: "The code before the TRY block sets @retry to 0 ..."


Chapter 11 - Service Broker

Date / By Where Correction

2007-03-02
Peter Bourlet

Page 432, last paragraph, fourth sentence Currently: "Even if there are message on the queue..."
Should be: "Even if there are messages on the queue..."

2007-03-02
Zhao Lidong

Page 435, Listing 11-1, third block comment from bottom of page Currently: "...This is created with activation off."
Should be: "...This is created with activation on."

2007-03-02
Zhao Lidong

Page 439, Listing 11-3, second block comment Currently: "...Activation is configured but turned off"
Should be: "...This is created with activation on."

2007-03-02
Zhao Lidong

Page 440, Listing 11-3, third line comment from bottom of listing Currently: "...Begin a dialog to the Hello World Service"
Should be: "...Begin a dialog to the Inventory Service"

2007-03-02
Zhao Lidong

Page 446, third paragraph, first sentence

Currently: "The private key certificate corresponding to the REMOTE SERVICE BINDING user of the initiator must have CONTROL permission on the target service..."
Should be: "The private key certificate corresponding to the REMOTE SERVICE BINDING user's certificate must have CONTROL permission on the target service..."

2007-03-02
Zhao Lidong

Page 452, last code line comment in page

Currently: "Grant Local System connect privilege"
Should be: "Grant Local System Account connect privilege"

2007-02-15
Zhao Lidong

Page 456, first sentence Currently: "The routes configured in a database can be examined in the sys.routes view The name of ..."
Should be: "The routes configured in a database can be examined in the sys.routes view. The name of ..."

2007-02-15
Zhao Lidong

Page 460, last sentence in section "Scenarios" Currently: "This isn't meant to be en exhaustive list ..."
Should be: "This isn't meant to be an exhaustive list ..."


Appendix A - Companion to CLR Routines

Date / By Where Correction

2007-03-02
Zhao Lidong

Page 465, first sentence below TOC

Currently:
"The book has common language routine (CLR)..."
Should be:
"The book has common language runtime (CLR)..."

2007-03-02
Zhao Lidong

Page 473, 13th line from bottom of page

Currently:
"Check whether the action is Insert"
Should be:
"Check type of action"

2007-03-02
Zhao Lidong

Page 480, 17th line from top of page

Currently:
"Check whether the action is Insert"
Should be:
"Check type of action"

 

Back to Inside T-SQL 2005 Main Page


 

Home ] Books ] T-SQL Courses ] Resources ] Blog ] About BG ]

[SolidQ Home] [SolidQ Blog] [SolidQ Courses] [The SolidQ journal]