2013-07-08 22 views
8

Ben SQL'e biraz yeniyim ve ben 2012.SQL Server: özyinelemeli güncelleme bildirimi

Temelde şirketlerin hiyerarşik tablo var SQL Server güncelleme ifadeleri hardcoding olmadan bunu yapmanın en iyi yolu anlamaya çalışıyorum (tedarik zincirini düşünün) sütunlarla (CompanyID, ParentID, ParentPriceAdj, CompanyPriceAdj). Her şirket, ebeveynleri tarafından PartMaster tablosunda bir liste fiyatını değiştiren bir fiyat ayarlaması alır ve nihai fiyat, ebeveynlerden çocuğa ayarlamaların basamaklandırılmasıyla hesaplanır.

bir updatedcompanyID verilen bir CompanyPriceAdj güncellenmesi, ben yinelemeli bulmak istiyorum: Bir anne fiyat ayarlaması güncellenir Eğer

, ben o kadar ileri

aka çocuğunun şirketlerin tüm yansıtmak ve istediğiniz çocuk CompanyID 'ın (ParentId = updatedCompanyID) ve güncelleme onların ParentPriceAdjParentCompany için' ler (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 

Güncellemeyi saklı tutan bir prosedürü kullanmayı düşünüyordum, sonra tekrar güncellenen her çocuk için kendini tekrar tekrar çağırıyordu ve sonradan çocuklarını güncelledi .... şirkete sahip olmayan çocuklar

Ben etrafa bakmayı denedim t Bu şu anda

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 

cevap

8

, gibi bir şey: müthiş

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

!! Bu mükemmel çalışıyor. Teşekkür ederim! – markymark

0

bir CURSOR kullanarak baktınız mı -

İşte ifadesi İLE için bağlantı? Biraz fazla, ama sana ihtiyacın olanı verebilir. Tanıdık değilseniz, aşağıda temel bir taslaktır. Her bir şirket kimliğini bir kerede çekmenize, değişikliklerinizi yapmanıza ve devam etmenize izin verir. Bunları yuvaya yerleştirebilir, döngülere dahil edebilir veya bunlara döngüler ekleyebilirsiniz, dikkat gerektiren herhangi bir eylem gerçekleşene kadar eylemler gerçekleştiren bir listeden geçmeniz gereken her şey.

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 

Bu yardımcı olur umarım. Yanlış anlamış olursam özür dilerim. Recursive CTE hiyerarşisini yürümek için kullanılabilir