Microsoft KB Archive/923020

= Inside Microsoft® SQL Server™ 2005: T-SQL Programming Comments and Corrections =

Article ID: 923020

Article Last Modified on 10/24/2007

-

APPLIES TO


 * Inside Microsoft SQL Server: T-SQL Programming, ISBN 0-7356-2197-7

-



SUMMARY
This article contains comments, corrections, and information about known errors relating to the Microsoft Press book Inside Microsoft® SQL Server™ 2005: T-SQL Programming, 0-7356-2197-7.

The following topics are covered:


 * Sample Code: Updated version of Chapter 8 sample code available
 * Page 11: &quot;cover discuss&quot; should be &quot;cover&quot;
 * Page 32: Missing definition of column xml_data in code sample
 * Page 47: Incorrect reference to information printed earlier in the chapter
 * Page 55: The DivCn method is missing a division by zero check
 * Page 56: Drive letter missing in path to ComplexNumberCS.dl
 * Page 58: Incorrect complex number referenced
 * Pages 63-64: Missing check for divide by zero error, and error in code comments
 * Page 69: .vsd file referenced in place of .vdx
 * Page 71: &quot;.value&quot; used in place of &quot;value&quot;
 * Page 74: The phrase &quot;up to three&quot; used in place of &quot;three other types of&quot;
 * Page 77: Term Hobbie used in place of Hobby
 * Page 78: Term Hobbie used in place of Hobby
 * Page 82: Term Hobbie used in place of Hobby
 * Page 92: Table #T2 referenced in place of table #T1
 * Pages 93 and 94: Table #T42 referenced in place of table #T
 * Page 98: 100000 used instead of 10000 in code sample
 * Page 100: 100000 used instead of 10000 in code sample
 * Page 119: Correction in caption for listing 3-3
 * Page 121: Correction in inline caption for Figure 3-1
 * Page 148: sp_droplinkedsrvlogin used in place of sp_addlinkedsrvlogin
 * Page 160: The term Inserts used in place of Updates
 * Page 168: Underscore character treated as a wildcard character
 * Page 169: Underscore character treated as a wildcard character
 * Page 195: Missing terms from the code sample
 * Page 197: JOIN used in place of LEFT OUTER JOIN
 * Page 202: sys.sql.modules referenced in place of sys.sql_modules
 * Page 288: &quot;schema&quot; should be &quot;owner&quot;
 * Page 303: Underscore character treated as a wildcard character
 * Page 332: Incorrect code sample
 * Page 335: The captions for tables 8-3 and 8-4 are reversed
 * Page 335: T1A used in place of T1
 * Page 345: .query method suggested in place of .value
 * Page 346: .query used in place of .value in Listing 8-10
 * Page 348: .query used in place of .value in Listing 8-11
 * Page 349: .query used in place of .value in code sample
 * Page 350: .query used in place of .value in listing 8-12
 * Page 353: &quot;unsafe&quot; used in place of &quot;external&quot;
 * Page 354: Comments in code sample incorrect
 * Page 357: Comment in code sample incorrect
 * Page 373: 'Version 2' referenced rather than 'Version 1'
 * Page 374: 'Version 2' referenced rather than 'Version 1'
 * Page 388: Column name used is incorrect
 * Page 405: Missing phrase &quot;code before the&quot; in TRY block explination
 * Page 435: &quot;off&quot; used in place of &quot;on&quot;
 * Page 439: Comment in code sample is incorrect
 * Page 440: &quot;Hello World&quot; used in place of &quot;Inventory&quot;
 * Page 446: Certificate name incorrect
 * Page 452: the word &quot;Account&quot; missing from code comment
 * Page 473: Comment text is incorrect
 * Page 480: Comment text is incorrect



Sample Code: Updated version of Chapter 8 sample code available
An updated version of the sample file installed to &quot;My Documents\Microsoft Press\Inside T SQL Programming\Chapter 08 - Triggers.sql&quot; is available for download from the Microsoft Download Center:

Ch8Trigr.exe

For additional information about how to download Microsoft Support files, click the following article number to view the article in the Microsoft Knowledge Base:

119591

How to Obtain Microsoft Support Files from Online Services Microsoft scanned this file for viruses. Microsoft used the most current virus-detection software that was available on the date that the file was posted. The file is stored on security-enhanced servers that help to prevent any unauthorized changes to the file.

Page 11: &quot;cover discuss&quot; should be &quot;cover&quot;
On page 11, the last sentence of the first paragraph contians incorrect wording.

Change:

&quot;I’ll cover discuss three techniques that involve overlaps: identifying overlaps, grouping overlaps, and max overlaps.&quot;

To:

&quot;I’ll cover three techniques that involve overlaps: identifying overlaps, grouping overlaps, and max overlaps.&quot;

Page 32: Missing definition of column xml_data in code sample
On page 32, the CREATE TABLE section of the code sample reads:

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

It should read:

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

Page 47: Incorrect reference to information printed earlier in the chapter
On page 47, the first sentence of the last paragraph in the &quot;Why Do We Need Complex Classes?&quot; section reads:

&quot;Note that as mentioned earlier in the chapter, the XML datatype can be adequate to store the state of objects using XML serialization in a database as well.&quot;

It should read:

&quot;Note that the XML datatype can be adequate to store the state of objects using XML serialization in a database as well.&quot;

Page 55: The DivCn method is missing a division by zero check
On page 55, the Division section of the code sample reads:

// 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)        ); }

It should read:

// 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)        ); }

Page 56: Drive letter missing in path to ComplexNumberCS.dl
On page 56, the second line of the first code sample reads:

FROM ' \ComplexNumberCS\ComplexNumberCS\bin\Debug\ComplexNumberCS.dll'

It should read:

FROM ' C:\ComplexNumberCS\ComplexNumberCS\bin\Debug\ComplexNumberCS.dll'

Page 58: Incorrect complex number referenced
On page 58, the first sentence of the first sentence reads:

&quot;You can see that the second complex number (2, 3i) is sorted before the first one (2, 3i)&quot;

It should read:

&quot;You can see that the second complex number (1, 7i) is sorted before the first one (2, 3i)&quot;

Pages 63-64: Missing check for divide by zero error, and error in code comments
On pages 63-64, the #Region &quot;arithmetic operations&quot; section in Listing 1-5 reads:

' 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
 * 1) Region &quot;arithmetic operations&quot;
 * 1) End Region

It should read:

' 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
 * 1) Region &quot;arithmetic operations&quot;
 * 1) End Region

Page 69: .vsd file referenced in place of .vdx
On page 69, the last sentence of the paragraph following Figure 1-7 reads:

&quot;To follow the demonstration, create the folder C:\VisioFiles and copy the .vsd files from the book’s CD to that folder.&quot;

It should read:

&quot;To follow the demonstration, create the folder C:\VisioFiles and copy the .vdx files from the book’s CD to that folder.&quot;

Page 71: &quot;.value&quot; used in place of &quot;value&quot;
On page 71, the first sentence of the last paragraph reads:

&quot;I used the .value method of the XML data type.&quot;

It should read:

&quot;I used the value method of the XML data type.&quot;

Page 74: The phrase &quot;up to three&quot; used in place of &quot;three other types of&quot;
On page 74, the second sentence of the first paragraph reads:

&quot;After creating the Primary XML index, you can create up to three secondary XML Indexes:&quot;

It should read:

&quot;After creating the Primary XML index, you can create three other types of secondary XML Indexes:&quot;

Page 77: Term Hobbie used in place of Hobby
On page 77, the third line of the last code sample reads:

Beer

It should read:

Beer

Page 78: Term Hobbie used in place of Hobby
On page 78, the third line of the list of errors reads:

English where element 'Foreign:Hobbie' was specified. Location: /*:Foreigns[1]/*:Hobbie[1]

It should read:

English where element 'Foreign:Hobby' was specified. Location: /*:Foreigns[1]/*:Hobby[1]

Page 82: Term Hobbie used in place of Hobby
On page 82, the fifth line of the last code sample reads:

insert Cigar

It should read:

insert Cigar

Page 92: Table #T2 referenced in place of table #T1
On page 92, the first line on the page reads:

&quot;though proc2’s code creates a table called #T2 with two columns and loads a row with two&quot;

It should read:

&quot;though proc2’s code creates a table called #T1 with two columns and loads a row with two&quot;

Pages 93 and 94: Table #T42 referenced in place of table #T
On pages 93 and 94, the sample code reads:

-- Assume @schema and @insert were constructed dynamically DECLARE @schema AS VARCHAR(1000), @insert AS VARCHAR(1000); SET @schema = 'col1 INT, col2 DECIMAL(10, 2)'; SET @insert = 'INSERT INTO #T42 VALUES(10, 20.30)';

-- In the outer level, create temp table #T with a single dummy column CREATE TABLE #T42(dummycol INT);

-- Within a dynamic batch: -- Alter #T adding the columns you need -- Alter #T dropping the dummy column -- Open another level of dynamic execution -- Populate #T EXEC(' ALTER TABLE #T42 ADD ' + @schema + '; ALTER TABLE #T42 DROP COLUMN dummycol; EXEC( + @insert + )'); GO

-- Back in the outer level, access #T in a new batch SELECT * FROM #T42;

-- Cleanup DROP TABLE #T42;

It should read:

-- Assume @schema and @insert were constructed dynamically DECLARE @schema AS VARCHAR(1000), @insert AS VARCHAR(1000); SET @schema = 'col1 INT, col2 DECIMAL(10, 2)'; SET @insert = 'INSERT INTO #T VALUES(10, 20.30)';

-- In the outer level, create temp table #T with a single dummy column CREATE TABLE #T(dummycol INT);

-- Within a dynamic batch: -- Alter #T adding the columns you need -- Alter #T dropping the dummy column -- Open another level of dynamic execution -- Populate #T EXEC(' ALTER TABLE #T ADD ' + @schema + '; ALTER TABLE #T DROP COLUMN dummycol; EXEC( + @insert + )'); GO

-- Back in the outer level, access #T in a new batch SELECT * FROM #T;

-- Cleanup DROP TABLE #T;

Page 98: 100000 used instead of 10000 in code sample
On page 98, the tenth line of the code sample reads:

SELECT n, (n - 1) % 100000 + 1 FROM dbo.Nums

It should read:

SELECT n, (n - 1) % 10000 + 1 FROM dbo.Nums

Page 100: 100000 used instead of 10000 in code sample
On page 100, the first line of the code sample reads:

SELECT n AS col1, (n - 1) % 100000 + 1 AS col2,

It should read:

SELECT n AS col1, (n - 1) % 10000 + 1 AS col2,

Page 119: Correction in caption for listing 3-3
On page 119, the caption under listing 3-3 reads:

&quot;Cursor code for custom aggregate&quot;

It should read:

&quot;Cursor code for running aggregations&quot;

Page 121: Correction in inline caption for Figure 3-1
On page 121, the inline caption for Figure 3-1 reads:

&quot;Max Concurrent Sessions Benchmark&quot;

It should read:

&quot;Running Aggregations Benchmark&quot;

Page 148: sp_droplinkedsrvlogin used in place of sp_addlinkedsrvlogin
On page 148, the third bullet point reads:

&quot;Use the sp_droplinkedsrvlogin stored procedure to map local logins to a security account on the remote server.&quot;

It should read:

&quot;Use the sp_addlinkedsrvlogin stored procedure to map local logins to a security account on the remote server.&quot;

Page 160: The term Inserts used in place of Updates
On page 160, the title of Table 4-6 reads:

&quot;Table 4-6 Contents of Computations Table After Inserts&quot;

It should read:

&quot;Table 4-6 Contents of Computations Table After Updates&quot;

Page 168: Underscore character treated as a wildcard character
On page 168, the seventh and eighth lines of the IF block in listing 4-7 read:

OR UPPER(@cols) LIKE UPPER(N'%xp_%') OR UPPER(@cols) LIKE UPPER(N'%sp_%')

They should read:

O R UPPER(@cols) LIKE UPPER(N'%xp[_]%') OR UPPER(@cols) LIKE UPPER(N'%sp[_]%')

Page 169: Underscore character treated as a wildcard character
On page 169, the seventh and eighth lines of the IF block in listing 4-8 read:

OR UPPER(@cols) LIKE UPPER(N'%xp_%') OR UPPER(@cols) LIKE UPPER(N'%sp_%')

They should read:

O R UPPER(@cols) LIKE UPPER(N'%xp[_]%') OR UPPER(@cols) LIKE UPPER(N'%sp[_]%')

Page 195: Missing terms from the code sample
On page 195, the ninth line of the first code sample reads:

JOIN dbo.VSalesRN AS Prv

It should read:

LEFT OUTER JOIN dbo.VSalesRN AS Prv

Page 197: JOIN used in place of LEFT OUTER JOIN
On page 197, the 13th line of the code sample reads:

JOIN CSalesRN AS Prv It should read:

LEFT OUTER JOIN CSalesRN AS Prv

Page 202: sys.sql.modules referenced in place of sys.sql_modules
On page 202, the second sentence of the last paragraph on the page reads:

&quot;If you don’t specify the ENCRYPTION option, SQL Server stores the text defining the body of the object/routine as clear text in sys.sql.modules (or in syscomments in SQL Server 2000).&quot;

It should read:

&quot;If you don’t specify the ENCRYPTION option, SQL Server stores the text defining the body of the object/routine as clear text in sys.sql_modules (or in syscomments in SQL Server 2000).&quot;

Page 288: &quot;schema&quot; should be &quot;owner&quot;
On page 288, the first bullet point on the page incorrectly uses the word &quot;schema&quot;.

Change:

&quot;The stored procedure and the underlying objects belong to the same schema.&quot;

To:

&quot;The stored procedure and the underlying objects belong to the same owner.&quot;

Page 303: Underscore character treated as a wildcard character
On page 303, the second and third lines read:

OR UPPER(@cols) LIKE UPPER(N'%xp_%') OR UPPER(@cols) LIKE UPPER(N'%sp_%')

They should read:

OR UPPER(@cols) LIKE UPPER(N'%xp[_]%') OR UPPER(@cols) LIKE UPPER(N'%sp[_]%')

Page 332: Incorrect code sample
On page 332, the SELECT statement in the code sample reads:

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;

It should read:

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;

Page 335: The captions for tables 8-3 and 8-4 are reversed
On page 335, the caption for table 8-3 reads:

&quot;Table 8-3 Contents of T1Audit&quot;

It should read:

&quot;Table 8-3 Contents of T1&quot;

The caption for table 8-4 reads:

&quot;Table 8-4 Contents of T1&quot;

It should read:

&quot;Table 8-4 Contents of T1Audit&quot;

Page 335: T1A used in place of T1
On page 335, the frist sentence at the top of the page reads:

&quot;Query the tables T1Audit and T1A, and you will get the results shown in Tables 8-3 and 8-4, respectively:&quot;

It should read:

&quot;Query the tables T1Audit and T1, and you will get the results shown in Tables 8-3 and 8-4, respectively:

Page 345: .query method suggested in place of .value
On page 345, the first two sentences of the paragraph following the More Info box read:

&quot;To extract a particular attribute from the XML value, you use the following XQuery expression: xml_value.query('data(//attribute_name)'). xml_value will typically be a variable to which you assigned the XML value returned by the eventdata function, and attribute_name is the name of the attribute you want to extract.&quot;

They should read:

&quot;To extract a particular attribute from the XML value, you use the following XQuery expression: xml_value.value('()[1]', ). xml_value will typically be a variable to which you assigned the XML value returned by the eventdata function, and  is the path to the attribute you want to extract.&quot;

Page 346: .query used in place of .value in Listing 8-10
On pages 346, lines 9-11 of Listing 8-10 read:

+ QUOTENAME(CAST(@eventdata.query('data(//SchemaName)') AS sysname)) + N'.' + QUOTENAME(CAST(@eventdata.query('data(//ObjectName)') AS sysname));

They should read:

+ QUOTENAME(@eventdata.value('(/EVENT_INSTANCE/SchemaName)[1]', 'sysname')) + N'.' + QUOTENAME(@eventdata.value('(/EVENT_INSTANCE/ObjectName)[1]', 'sysname'));

Page 348: .query used in place of .value in Listing 8-11
On page 348, lines 8-13 of the code in listing 8-11 read:

CAST(@eventdata.query('data(//PostTime)') AS VARCHAR(23)), CAST(@eventdata.query('data(//EventType)') AS sysname), CAST(@eventdata.query('data(//LoginName)') AS sysname), CAST(@eventdata.query('data(//SchemaName)') AS sysname), CAST(@eventdata.query('data(//ObjectName)') AS sysname), CAST(@eventdata.query('data(//TargetObjectName)') AS sysname),

They should read:

@eventdata.value('(/EVENT_INSTANCE/PostTime)[1]',        'VARCHAR(23)'), @eventdata.value('(/EVENT_INSTANCE/EventType)[1]',       'sysname'), @eventdata.value('(/EVENT_INSTANCE/LoginName)[1]',       'sysname'), @eventdata.value('(/EVENT_INSTANCE/SchemaName)[1]',      'sysname'), @eventdata.value('(/EVENT_INSTANCE/ObjectName)[1]',      'sysname'), @eventdata.value('(/EVENT_INSTANCE/TargetObjectName)[1]', 'sysname'),

Page 349: .query used in place of .value in code sample
On page 349, the second line of the code sample before Table 8-11 reads:

CAST(eventdata.query('data(//TSQLCommand)') AS NVARCHAR(2000))

It should read:

eventdata.value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]', 'NVARCHAR(MAX)')

Page 350: .query used in place of .value in listing 8-12
On page 350, lines 31-34 of Listing 8-12 read:

CAST(@eventdata.query('data(//PostTime)') AS VARCHAR(23)), CAST(@eventdata.query('data(//EventType)') AS sysname), CAST(@eventdata.query('data(//LoginName)') AS sysname), CAST(@eventdata.query('data(//ObjectName)') AS sysname), CAST(@eventdata.query('data(//LoginType)') AS sysname),

They should read:

@eventdata.value('(/EVENT_INSTANCE/PostTime)[1]',  'VARCHAR(23)'), @eventdata.value('(/EVENT_INSTANCE/EventType)[1]', 'sysname'), @eventdata.value('(/EVENT_INSTANCE/LoginName)[1]', 'sysname'), @eventdata.value('(/EVENT_INSTANCE/ObjectName)[1]', 'sysname'), @eventdata.value('(/EVENT_INSTANCE/LoginType)[1]', 'sysname'),

Page 353: &quot;unsafe&quot; used in place of &quot;external&quot;
On page 353, the line comment in the first code sample reads:

&quot;-- Create login and grant it with unsafe permission level&quot;

It should read:

&quot;-- Create login and grant it with external permission level&quot;

Page 354: Comments in code sample incorrect
On page 354, the first comment in the code sample reads:

// Check whether the action is Insert

It should read:

// Check type of action

Page 357: Comment in code sample incorrect
On page 357, the first line comment in the second block of code reads:

' Check whether the action is Insert

It should read:

' Check type of action

Page 373: 'Version 2' referenced rather than 'Version 1'
On page 373, the second sentence from the end of the page reads:

&quot;You get the output 'Version 2', and the process keeps a shared lock on the data because the transaction is still open.&quot;

It should read:

&quot;You get the output 'Version 1', and the process keeps a shared lock on the data because the transaction is still open.&quot;

Page 374: 'Version 2' referenced rather than 'Version 1'
On page 374, the second sentence on the page reads:

&quot;You still get 'Version 2' back, meaning you got a repeatable read even though another process attempted to change the data in between your reads.&quot;

It should read:

&quot;You still get 'Version 1' back, meaning you got a repeatable read even though another process attempted to change the data in between your reads.&quot;

Page 388: Column name used is incorrect
On page 388, the second paragraph under Deadlock with a Single Table reads:

&quot;Before I demonstrate such a scenario, let's first run the following UPDATE statement to make sure that T1.col2 is set to 102 where keycol =2:&quot;

It should read:

&quot;Before I demonstrate such a scenario, let's first run the following UPDATE statement to make sure that T1.col1 is set to 102 where keycol =2:&quot;

Page 405: Missing phrase &quot;code before the&quot; in TRY block explination
On page 405, the first sentence of the last paragraph reads:

&quot;The TRY block then sets @retry to 0 so that if all goes well, there won’t be another retry.&quot;

It should read:

&quot;The code before the TRY block then sets @retry to 0 so that if all goes well, there won’t be another retry.&quot;

Page 435: &quot;off&quot; used in place of &quot;on&quot;
On page 435, the comment in the third code sample block from the bottom reads:

-- Create the Inventory Queue which will be the target of

-- the conversations. This is created with activation off.

It should read:

-- Create the Inventory Queue which will be the target of

-- the conversations. This is created with activation on.

Page 439: Comment in code sample is incorrect
On page 439, the second block comment in the code sample reads:

-- Create the initiator queue. Activation is configured

-- but turned off

It should read:

-- Create the initiator queue. This is created with activation on.

Page 440: &quot;Hello World&quot; used in place of &quot;Inventory&quot;
On page 440, the third line comment from bottom of code sample reads:

-- Begin a dialog to the Hello World Service

It should read:

-- Begin a dialog to the Inventory Service

Page 446: Certificate name incorrect
On page 446, the first sentence of the third paragraph reads:

&quot;The private key certificate corresponding to the REMOTE SERVICE BINDING user of the initiator must have CONTROL permission on the target service, and the public key certificate corresponding to the initiator service owner’s certificate must have SEND permissions on the target service.&quot;

It should read:

&quot;The private key certificate corresponding to the REMOTE SERVICE BINDING user's certificate must have CONTROL permission on the target service, and the public key certificate corresponding to the initiator service owner’s certificate must have SEND permissions on the target service.&quot;

Page 452: the word &quot;Account&quot; missing from code comment
On page 452, the last code line comment on the page reads:

-- Grant Local System connect privilege

It should read:

-- Grant Local System Account connect privilege

Page 473: Comment text is incorrect
On page 473, the 13th code line from the bottom of the page reads:

// Check whether the action is Insert

It should read:

// Check type of action

Page 480: Comment text is incorrect
On page 480, the 17th line from the bottom of the page reads:

' Check whether the action is Insert

It should read:

' Check type of action

Microsoft Press is committed to providing informative and accurate books. All comments and corrections listed above are ready for inclusion in future printings of this book. If you have a later printing of this book, it may already contain most or all of the above corrections.

Additional query words: 0-7356-2197-7 978-0-7356-2197-8

Keywords: KB923020

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.