2013-07-08 11 views
8

Jestem trochę nowych do SQL i próbuję dowiedzieć się, najlepszy sposób to zrobić bez hardcoding sprawozdania aktualizacyjne w SQL Server 2012.SQL Server: rekurencyjne instrukcja aktualizacji

Zasadniczo mam hierarchiczny spis firm (myśl o łańcuchu dostaw) z kolumnami (CompanyID, ParentID, ParentPriceAdj, CompanyPriceAdj). Każdej firmie przypisuje się korektę ceny przez rodzica, która modyfikuje cenę w tabeli PartMaster, a ostateczna cena jest obliczana poprzez kaskadowanie korekt z rodzica na dziecko.

Jeżeli regulacja rodzice cena jest aktualizowany, chcę to do refleksji na temat wszystkich swoich spółkach dzieci i tak dalej

aka:

Podczas aktualizowania CompanyPriceAdj dla danego updatedcompanyID chcę rekursywnie znaleźć dziecko CompanyID 's (ParentId = updatedCompanyID) i aktualizować swoje ParentPriceAdj do ParentCompany' s (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 

Myślałem o użyciu procedury przechowywanej, która aktualizuje się, a następnie wielokrotnie wywołuje się dla każdego dziecka, które zostało właśnie zaktualizowane, a następnie aktualizuje swoje dzieci ... aż firma nie ma dzieci

Próbowałem rozglądać się po okolicy. t znaleźć żadnych przykładów jak ten

to co mam teraz

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 

Odpowiedz

8

rekurencyjne CTE można stosować chodzić hierarchię, coś jak:

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

niesamowite !! to działa idealnie. Dziękuję Ci! – markymark

0

Szukały przy użyciu kursora? To trochę nad głową, ale może dać ci to, czego potrzebujesz. Jeśli nie jesteś zaznajomiony, poniżej znajduje się podstawowy zarys. Pozwala to na pobieranie identyfikatora każdej firmy po jednym na raz, wprowadzanie zmian i kontynuowanie. Możesz je zagnieżdżać, dołączać do pętli lub dołączać do nich pętle, bez względu na to, czego potrzebujesz, aby przejść przez listę wykonującą akcje, dopóki nie pozostawisz żadnych działań wymagających uwagi.

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 

Mam nadzieję, że to jest pomocne. Przepraszam, jeśli źle zrozumiałem.

Powiązane problemy