Changes to MERGE and HIERARCHYID
Itzik describes changes to the MERGE statement and the HIERARCHYID datatype that will appear after CTP 6.
April 23, 2008
For those of you who already had the chance to play with the MERGE statement and the HIERARCHYID datatype in Microsoft SQL Server 2008, you might be interested to know that Microsoft made a few changes to those that will show up after CTP 6 (CTP Refresh and of course RTM).
Changes to MERGE
In CTP 6 the MERGE statement supports the following clauses (among others):
WHEN [TARGET] NOT MATCHED THEN
WHEN SOURCE NOT MATCHED THEN
Due to the efforts of Taylen Wong, Microsoft decided to change these two clauses. Taylen submitted to Microsoft that the existing syntax is ambiguous. Namely, that it is not really clear in the existing syntax which clause represents the case where a source row has no match in the target table, and which where a target row has no match in the source table.
In the next public CTP (CTP Refresh) and of course in RTM, Microsoft will change the syntax of the above clauses to the following nonambiguous syntax:
WHEN NOT MATCHED [BY TARGET] THEN
WHEN NOT MATCHED BY SOURCE THEN
For example, consider the following MERGE statement that uses the CTP 6 syntax:
MERGE INTO dbo.Customers AS TGT
USING dbo.CustomersStage AS SRC
ON TGT.custid = SRC.custid
WHEN MATCHED THEN
UPDATE SET
TGT.companyname = SRC.companyname,
TGT.phone = SRC.phone,
TGT.address = SRC.address
WHEN TARGET NOT MATCHED THEN
INSERT (custid, companyname, phone, address)
VALUES (SRC.custid, SRC.companyname, SRC.phone, SRC.address)
WHEN SOURCE NOT MATCHED THEN
DELETE;
After CTP 6, the valid syntax for this statement will be:
MERGE INTO dbo.Customers AS TGT
USING dbo.CustomersStage AS SRC
ON TGT.custid = SRC.custid
WHEN MATCHED THEN
UPDATE SET
TGT.companyname = SRC.companyname,
TGT.phone = SRC.phone,
TGT.address = SRC.address
WHEN NOT MATCHED BY TARGET THEN
INSERT (custid, companyname, phone, address)
VALUES (SRC.custid, SRC.companyname, SRC.phone, SRC.address)
WHEN NOT MATCHED BY SOURCE THEN
DELETE;
Changes to HIERARCHYID
There were submissions to Microsoft asking to change the methods IsDescendant and Reparent of the HIERARCHYID datatype, reasoning that the existing naming of the methods in CTP 6 is problematic.
In CTP 6, the method IsDescndent is applied to an ancestor and accepts a child as input:
.IsDescendant()
It makes more sense that it would be the other way around. Microsoft accepted this reasoning and will change the method after CTP 6 to:
.IsDescendant()
As an example, consider the following query used in CTP 6 to return an employee and all of his/her subordinates in all levels:
SELECT C.empid, C.empname, C.lvl
FROM dbo.Employees AS P
JOIN dbo.Employees AS C
ON P.empid = 3
AND P.hid.IsDescendant(C.hid) = 1;
After CTP, 6 this query should be revised to:
SELECT C.empid, C.empname, C.lvl
FROM dbo.Employees AS P
JOIN dbo.Employees AS C
ON P.empid = 3
AND C.hid.IsDescendantOf(P.hid) = 1;
Also, the method Reparent in CTP 6 will be renamed to GetReparentedValue after CTP 6 since it doesn’t actually reparent a node, rather just returns a value that can be used to reparent a node.
For example, if you used the following code to reparent nodes in CTP 6:
UPDATE dbo.Employees
SET hid = hid.Reparent(@old_root, @new_root)
WHERE @old_root.IsDescendant(hid) = 1;
You would need to revise it after CTP 6 as follows:
UPDATE dbo.Employees
SET hid = hid.GetReparentedValue(@old_root, @new_root)
WHERE hid.IsDescendantOf(@old_root) = 1;
Cheers,
BG
About the Author
You May Also Like