2013-07-08 8 views
8

Ich bin etwas Neues zu SQL und ich versuche, die beste Art und Weise, dies zu tun, um herauszufinden, ohne Update-Anweisungen in SQL Server 2012 hartzucodierenSQL Server: rekursive Update-Anweisung

Grundsätzlich ich eine hierarchische Tabelle der Unternehmen haben (Denken Sie an eine Lieferkette) mit Spalten (CompanyID, ParentID, ParentPriceAdj, CompanyPriceAdj). Jedem Unternehmen wird von seinem Elternteil eine Preisanpassung zugewiesen, die einen Listenpreis in der Tabelle PartMaster ändert, und der Endpreis wird berechnet, indem die Anpassungen von Eltern zu Kind kaskadiert werden.

Wenn ein Eltern Preisanpassung aktualisiert wird, möchte ich, dass auf allen seinem Kind Unternehmen reflektieren und so weiter

aka:

Wenn ein CompanyPriceAdj für eine updatedcompanyID gegeben Aktualisierung, möchte ich rekursiv finden das Kind CompanyID 's (ParentId = updatedCompanyID) und deren ParentPriceAdj-ParentCompany aktualisieren' 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 

Ich dachte daran, eine gespeicherte Prozedur zu verwenden, die sich dann wiederholt für jedes Kind aufruft, das gerade aktualisiert wurde und anschließend seine Kinder aktualisiert hat .... bis das Unternehmen keine Kinder hat

Ich habe versucht, mich umzusehen t keine Beispiele finden, wie dies

Das ist, was ich jetzt können

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 

Antwort

8

rekursive CTE verwendet werden kann Hierarchie gehen, so etwas wie:

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

awesome !! das funktioniert perfekt. Vielen Dank! – markymark

0

Haben Sie sich mit einem CURSOR geschaut? Es ist ein bisschen Overhead, aber es kann Ihnen geben, was Sie brauchen. Wenn Sie nicht vertraut sind, ist unten eine grundlegende Gliederung. Sie können jede Firmen-ID einzeln erfassen, Änderungen vornehmen und weitermachen. Sie können sie verschachteln, sie in Schleifen einschließen oder Schleifen darin einschließen, was auch immer Sie benötigen, um eine Liste mit Aktionen auszuführen, bis keine Aktionen mehr übrig sind, die Aufmerksamkeit benötigen.

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 

Ich hoffe, dies ist hilfreich. Ich entschuldige mich, wenn ich es falsch verstanden habe.