MSDN Magazine - September 2008 - (Page 67) archyID type. The first query produced a hierarchical listing of the bills from the top (bill 110) down by using a recursive common table expression. When I use the HierarchyID data type, the complete linage for any given bill is already represented within that value. For example, one of the bottommost bills in the hierarchy is bill 405, representing a CPU kit. How would I know what bills make up its lineage? This code will tell me: select billPath.ToString() from dbo.bill2 where billID=405; Determining which bills use a particular part can be queried using the GetAncestor method. That method allows you to query up a hierarchy. Here I need to use recursion to traverse upward through the list of bills: declare @partID int = 20; with c(billPath,descr) as ( select b.billPath,b.descr from dbo.part p join dbo.partList pl on p.partID = pl.partID join dbo.billPartList bpl on pl.partListID = bpl.partListID join dbo.bill2 b on bpl.billID = b.billID where p.partID = @partID union all select b.billPath,b.descr from dbo.bill2 b join c on b.billPath = c.billPath.GetAncestor(1)) select distinct descr,billPath from c where billPath hierarchyID::GetRoot() order by billPath; The output from that query is a string with the value “/110/210/310/405.” Now the question becomes how, exactly, can I get the bills represented by that string? That is a bit trickier since the HierarchyID type does not offer a method for converting the list of values into a vector. However, you can write your own using either TSQL or SQL/CLR. Here is the code for doing this using a TSQL tablevalued function: create function dbo.Vectorize(@i hierarchyID) returns @t table (position int identity(1,1) not null,nodeValue int not null) as begin declare @list varchar(max) = @i.ToString(); declare @delimit int; set @list = substring(@list,2,len(@list)-1); while len(@list) > 1 begin set @delimit = charindex('/',@list); insert into @t values (cast(substring(@list,1,@delimit-1) as int)); set @list = substring(@list,@delimit+1,len(@list)); end; return; end; Figure 6 added a new part and bill. No changes are needed in the code to insert the part or to create the part list. Creating a bill, however, does provide the opportunity to use the GetDescendant and GetReparentedValue methods of HierarchyID. I can start the process with the following code excerpt: begin begin transaction declare @mp int; declare @mpl int; select @mp = MAX(partID)+10 from dbo.part; insert into dbo.part(partID,descr,cost) output inserted.* values (@mp,'4GB USB 2.0 Memory Stick',20.0); select @mpl = MAX(partListID)+10 from dbo.partList; insert into dbo.partList(partListID,partID,quantity) output inserted.* values (@mpl,@mp,1); Now you have a simple way of examining the linage of any bill in the system with a single, nonrecursive query: declare @anyBill int = 405; select b1.billPath,b2.billID,b2.descr from dbo.bill2 b1 cross apply dbo.vectorize(b1.billPath) p join dbo.bill2 b2 on b2.billID = p.nodeValue where b1.billID = @anyBill; What about finding the parts used by a given bill? Unlike the prior implementation where I need to recursively query the list of bills, this query can take advantage of a HierarchyID’s ability to determine whether one ordered path is a descendent of another by using the IsDescendantOf method: declare @anyBill int = 110; declare @sourceBillPath hierarchyID; select @sourceBillPath = billPath from dbo.bill2 where billID = @ anyBill; select p.partID as 'partID', p.descr 'partName' from dbo.bill2 b2 left join dbo.billPartList bpl on b2.billID = bpl.billID left join dbo.partList pl on bpl.partListID = pl.partListID left join dbo.part p on pl.partID =p.partID where b2.billPath.IsDescendantOf(@sourceBillPath)=1 and p.partID is not null order by p.partid; With the part and parts list created, I can now create the related bill. The idea is to insert the new bill into the hierarchy to the right of all of the other bills making up the Super X100 Home Theatre System. To do that I need to know two things: the path for parent bill and the path for its rightmost child. Deleting a bill that is the parent of one or more other bills requires more complex code. Getting the path for the parent bill is a simple query. Finding its rightmost child requires using the IsDescendantOf and GetLevel methods, like this: declare @root hierarchyID; declare @newBillPath hierarchyID; declare @newBillID int; select @root = billPath from dbo.bill2 where billID = 110; select @newBillPath = max(billPath) from dbo.bill2 where billPath.IsDescendantOf(@root) =1 and billPath.GetLevel() = @root.GetLevel()+1; Calculating the MSRP of the whole system or any subbill can be done with a few modifications to the technique that I showed you previously: declare @anyBill int = 110; declare @sourceBillPath hierarchyID; select @sourceBillPath = billPath from dbo.bill2 where billID = @anyBill; select SUM(p.cost * pl.quantity)*2.0 from dbo.bill2 b2 left join dbo.billPartList bpl on b2.billID = bpl.billID left join dbo.partList pl on bpl.partListID = pl.partListID left join dbo.part p on pl.partID =p.partID where b2.billPath.IsDescendantOf(@sourceBillPath)=1; msdnmagazine.com September 2008 67 msdnmagazine.com
Table of Contents Feed for the Digital Edition of MSDN Magazine - September 2008 MSDN Magazine - September 2008 Contents Toolbox CLR Inside Out Data Points Advanced Basics Office Space Cutting Edge Hierarchy ID New Features for Microsoft SQL Server 2008 Prism Data Services Advanced WPF Test Run Security Briefs Foundations { End Bracket } MSDN Magazine - September 2008 MSDN Magazine - September 2008 - (Page Intro) MSDN Magazine - September 2008 - Contents (Page Cover1) MSDN Magazine - September 2008 - Contents (Page Cover2) MSDN Magazine - September 2008 - Contents (Page 1) MSDN Magazine - September 2008 - Contents (Page 2) MSDN Magazine - September 2008 - Contents (Page 3) MSDN Magazine - September 2008 - Contents (Page 4) MSDN Magazine - September 2008 - Contents (Page 5) MSDN Magazine - September 2008 - Contents (Page 6) MSDN Magazine - September 2008 - Contents (Page 7) MSDN Magazine - September 2008 - Contents (Page 8) MSDN Magazine - September 2008 - Contents (Page 9) MSDN Magazine - September 2008 - Contents (Page 10) MSDN Magazine - September 2008 - Toolbox (Page 11) MSDN Magazine - September 2008 - Toolbox (Page 12) MSDN Magazine - September 2008 - Toolbox (Page 13) MSDN Magazine - September 2008 - Toolbox (Page 14) MSDN Magazine - September 2008 - Toolbox (Page 15) MSDN Magazine - September 2008 - Toolbox (Page 16) MSDN Magazine - September 2008 - Toolbox (Page 17) MSDN Magazine - September 2008 - Toolbox (Page 18) MSDN Magazine - September 2008 - CLR Inside Out (Page 19) MSDN Magazine - September 2008 - CLR Inside Out (Page 20) MSDN Magazine - September 2008 - CLR Inside Out (Page 21) MSDN Magazine - September 2008 - CLR Inside Out (Page 22) MSDN Magazine - September 2008 - CLR Inside Out (Page 23) MSDN Magazine - September 2008 - CLR Inside Out (Page 24) MSDN Magazine - September 2008 - CLR Inside Out (Page 25) MSDN Magazine - September 2008 - CLR Inside Out (Page 26) MSDN Magazine - September 2008 - Data Points (Page 27) MSDN Magazine - September 2008 - Data Points (Page 28) MSDN Magazine - September 2008 - Data Points (Page 29) MSDN Magazine - September 2008 - Data Points (Page 30) MSDN Magazine - September 2008 - Data Points (Page 31) MSDN Magazine - September 2008 - Data Points (Page 32) MSDN Magazine - September 2008 - Data Points (Page 33) MSDN Magazine - September 2008 - Data Points (Page 34) MSDN Magazine - September 2008 - Advanced Basics (Page 35) MSDN Magazine - September 2008 - Advanced Basics (Page 36) MSDN Magazine - September 2008 - Advanced Basics (Page 37) MSDN Magazine - September 2008 - Advanced Basics (Page 38) MSDN Magazine - September 2008 - Advanced Basics (Page 39) MSDN Magazine - September 2008 - Advanced Basics (Page 40) MSDN Magazine - September 2008 - Advanced Basics (Page 41) MSDN Magazine - September 2008 - Advanced Basics (Page 42) MSDN Magazine - September 2008 - Advanced Basics (Page 43) MSDN Magazine - September 2008 - Advanced Basics (Page 44) MSDN Magazine - September 2008 - Office Space (Page 45) MSDN Magazine - September 2008 - Office Space (Page 46) MSDN Magazine - September 2008 - Office Space (Page 47) MSDN Magazine - September 2008 - Office Space (Page 48) MSDN Magazine - September 2008 - Office Space (Page 49) MSDN Magazine - September 2008 - Office Space (Page 50) MSDN Magazine - September 2008 - Office Space (Page 51) MSDN Magazine - September 2008 - Office Space (Page 52) MSDN Magazine - September 2008 - Cutting Edge (Page 53) MSDN Magazine - September 2008 - Cutting Edge (Page 54) MSDN Magazine - September 2008 - Cutting Edge (Page 55) MSDN Magazine - September 2008 - Cutting Edge (Page 56) MSDN Magazine - September 2008 - Cutting Edge (Page 57) MSDN Magazine - September 2008 - New Features for Microsoft SQL Server 2008 (Page 58) MSDN Magazine - September 2008 - New Features for Microsoft SQL Server 2008 (Page 59) MSDN Magazine - September 2008 - New Features for Microsoft SQL Server 2008 (Page 60) MSDN Magazine - September 2008 - New Features for Microsoft SQL Server 2008 (Page 61) MSDN Magazine - September 2008 - New Features for Microsoft SQL Server 2008 (Page 62) MSDN Magazine - September 2008 - New Features for Microsoft SQL Server 2008 (Page 63) MSDN Magazine - September 2008 - New Features for Microsoft SQL Server 2008 (Page 64) MSDN Magazine - September 2008 - New Features for Microsoft SQL Server 2008 (Page 65) MSDN Magazine - September 2008 - New Features for Microsoft SQL Server 2008 (Page 66) MSDN Magazine - September 2008 - New Features for Microsoft SQL Server 2008 (Page 67) MSDN Magazine - September 2008 - New Features for Microsoft SQL Server 2008 (Page 68) MSDN Magazine - September 2008 - New Features for Microsoft SQL Server 2008 (Page 69) MSDN Magazine - September 2008 - Prism (Page 70) MSDN Magazine - September 2008 - Prism (Page 71) MSDN Magazine - September 2008 - Prism (Page 72) MSDN Magazine - September 2008 - Prism (Page 73) MSDN Magazine - September 2008 - Prism (Page 74) MSDN Magazine - September 2008 - Prism (Page 75) MSDN Magazine - September 2008 - Prism (Page 76) MSDN Magazine - September 2008 - Prism (Page 77) MSDN Magazine - September 2008 - Prism (Page 78) MSDN Magazine - September 2008 - Prism (Page 79) MSDN Magazine - September 2008 - Data Services (Page 80) MSDN Magazine - September 2008 - Data Services (Page 81) MSDN Magazine - September 2008 - Data Services (Page 82) MSDN Magazine - September 2008 - Data Services (Page 83) MSDN Magazine - September 2008 - Data Services (Page 84) MSDN Magazine - September 2008 - Data Services (Page 85) MSDN Magazine - September 2008 - Data Services (Page 86) MSDN Magazine - September 2008 - Advanced WPF (Page 87) MSDN Magazine - September 2008 - Advanced WPF (Page 88) MSDN Magazine - September 2008 - Advanced WPF (Page 89) MSDN Magazine - September 2008 - Advanced WPF (Page 90) MSDN Magazine - September 2008 - Advanced WPF (Page 91) MSDN Magazine - September 2008 - Advanced WPF (Page 92) MSDN Magazine - September 2008 - Advanced WPF (Page 93) MSDN Magazine - September 2008 - Advanced WPF (Page 94) MSDN Magazine - September 2008 - Advanced WPF (Page 95) MSDN Magazine - September 2008 - Advanced WPF (Page 96) MSDN Magazine - September 2008 - Test Run (Page 97) MSDN Magazine - September 2008 - Test Run (Page 98) MSDN Magazine - September 2008 - Test Run (Page 99) MSDN Magazine - September 2008 - Test Run (Page 100) MSDN Magazine - September 2008 - Test Run (Page 101) MSDN Magazine - September 2008 - Test Run (Page 102) MSDN Magazine - September 2008 - Test Run (Page 103) MSDN Magazine - September 2008 - Test Run (Page 104) MSDN Magazine - September 2008 - Security Briefs (Page 105) MSDN Magazine - September 2008 - Security Briefs (Page 106) MSDN Magazine - September 2008 - Security Briefs (Page 107) MSDN Magazine - September 2008 - Security Briefs (Page 108) MSDN Magazine - September 2008 - Security Briefs (Page 109) MSDN Magazine - September 2008 - Security Briefs (Page 110) MSDN Magazine - September 2008 - Security Briefs (Page 111) MSDN Magazine - September 2008 - Security Briefs (Page 112) MSDN Magazine - September 2008 - Foundations (Page 113) MSDN Magazine - September 2008 - Foundations (Page 114) MSDN Magazine - September 2008 - Foundations (Page 115) MSDN Magazine - September 2008 - Foundations (Page 116) MSDN Magazine - September 2008 - Foundations (Page 117) MSDN Magazine - September 2008 - Foundations (Page 118) MSDN Magazine - September 2008 - Foundations (Page 119) MSDN Magazine - September 2008 - { End Bracket } (Page 120) MSDN Magazine - September 2008 - { End Bracket } (Page Cover3) MSDN Magazine - September 2008 - { End Bracket } (Page Cover4)
For optimal viewing of this digital publication, please enable JavaScript and then refresh the page. If you would like to try to load the digital publication without using Flash Player detection, please click here.