2013-07-08 145 views
8

我有點新的SQL,我試圖找出這樣做的最好辦法,而不在SQL Server硬編碼更新語句2012SQL服務器:遞歸更新語句

基本上我有公司的分級表(想象一下供應鏈)與列(CompanyID, ParentID, ParentPriceAdj, CompanyPriceAdj)。每家公司都會獲得父母的價格調整,修改PartMaster表中的清單價格,最終價格通過級聯調整從父母到小孩進行計算。

如果父母調價得到更新,我想,要反映他的所有孩子公司等

又名:

當更新對於給定updatedcompanyID一個CompanyPriceAdj,我想遞歸地找到孩子CompanyID的(ParentId = updatedCompanyID)和更新他們的ParentPriceAdjParentCompany的(parentPriceAdj * (1 + CompanyPriceAdj)

CompanyId  ParentID  ParentPriceAdj CompanyPriceAdj 
    5    6    0.96    .10 
    6    8    1     .20 
    7    6    0.96    .15 
    8    11    1     0 
10    6    0.96    0 
11    12    1     0 

我正在考慮使用存儲過程更新,然後反覆調用自己爲每個剛剛更新的孩子,然後更新他的孩子....直到公司沒有孩子

我試過環顧四周couldn'找不到這樣

任何例子這是我現在所擁有的

ALTER PROCEDURE [dbo].[UpdatePricing] 
@updatedCompanyID int, @PriceAdj decimal 
AS 
BEGIN 
SET NOCOUNT ON; 

    WHILE (Select CompanyID From CompanyInfo Where ParentID = @updatedCompanyID) IS NOT NULL 
     UPDATE CompanyInfo 
     SET ParentPriceAdj = @PriceAdj * (1+CompanyPriceAdj), 
      @updatedCompanyId = CompanyID, 
      @PriceAdj = CompanyPriceAdj   
     WHERE ParentID = @updatedCompanyID 

     --- some method to call itself again for each (@updatedCompanyID, @PriceAdj) 
END 

回答

8

遞歸CTE可以用來走路的層次結構,是這樣的:

ALTER PROCEDURE [dbo].[UpdatePricing] 
(
    @companyID int, 
    @PriceAdj decimal 
) 
as 
begin 
    set nocount on 

    update CompanyInfo 
    set CompanyPriceAdj = @PriceAdj 
    where CompanyID = @companyID 

    ;with Hierarchy(CompanyID, ParentID, InPriceAdj, OutPriceAdj) 
    as (
     select D.CompanyID, D.ParentID, cast(D.ParentPriceAdj as float), 
      cast(D.ParentPriceAdj as float) * cast(1 + D.CompanyPriceAdj as float) 
     from CompanyInfo D 
     where CompanyID = @companyID 
     union all 
     select D.CompanyID, D.ParentID, 
      H.OutPriceAdj, H.OutPriceAdj * (1 + D.CompanyPriceAdj) 
     from Hierarchy H 
      join CompanyInfo D on D.ParentID = H.CompanyID 
    ) 
    update D 
    set D.ParentPriceAdj = H.InPriceAdj 
    from CompanyInfo D 
     join Hierarchy H on H.CompanyID = D.CompanyID 
    where 
     D.CompanyID != @companyID 

end 
+0

真棒!這工作完美。謝謝! – markymark

0

你看着使用遊標?這是一個開銷,但它可能會給你你需要的東西。如果你不熟悉,下面是一個基本概述。它允許您一次抽取一個公司ID,進行更改,然後繼續。您可以將它們嵌套,將它們包含在循環中或包含循環,無論您需要通過執行操作的列表,直到沒有需要注意的操作。

declare @updatedCompanyID Varchar(5) 
DECLARE D_cursor CURSOR FOR Select updatedCompanyID from        
OPEN D_cursor 
FETCH NEXT FROM D_cursor into @updatedCompanyID 
WHILE @@FETCH_STATUS =0 
BEGIN 
    --Run Your Code 
    WHERE parentID = @updatedCompanyID 
FETCH NEXT FROM D_cursor into @updatedCompanyID 
END 
Close D_cursor 
DEALLOCATE D_cursor 

希望這會對您有所幫助。如果我誤解了,我很抱歉。