2013-07-08 13 views
8

मैं कुछ एसक्यूएल के लिए नया हूँ और मैं एसक्यूएल सर्वर में अद्यतन बयान हार्डकोड बिना ऐसा करने का सबसे अच्छा तरीका है यह पता लगाने की 2012एसक्यूएल सर्वर: पुनरावर्ती अद्यतन बयान

मूल रूप से मैं कंपनियों के एक श्रेणीबद्ध तालिका है कोशिश कर रहा हूँ (आपूर्ति श्रृंखला के बारे में सोचें) कॉलम के साथ (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 

मैं एक संग्रहीत प्रक्रिया का उपयोग करने के बारे में सोच रहा था, जो अपडेट तब बार-बार अपने बच्चे के लिए कॉल करता है जिसे अद्यतन किया गया था और उसके बाद उसके बच्चों को अपडेट किया गया .... जब तक कि कंपनी के बच्चे नहीं हैं

मैंने चारों ओर देखने की कोशिश की है ' टी इस

की तरह किसी भी उदाहरण मिल जाए यह वही है मैं अभी

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

3

आप T-SQL में अभिव्यक्ति के साथ उपयोग कर सकते हैं दिया बच्चे को रिकार्ड के लिए सभी माता पिता रिकॉर्ड प्राप्त करने के लिए है। और आपके तर्क के अनुसार रिकॉर्ड सेट में प्रत्येक रिकॉर्ड को अपडेट कर सकते हैं।

http://msdn.microsoft.com/en-us/library/ms175972.aspx

http://msdn.microsoft.com/en-us/library/ms186243(v=sql.105).aspx

0

आप एक कर्सर का उपयोग को देखा है -

यहाँ अभिव्यक्ति के साथ के लिए लिंक कर रहे हैं? यह ओवरहेड का थोड़ा सा है, लेकिन यह आपको जो चाहिए वह आपको दे सकता है। यदि आप परिचित नहीं हैं, तो नीचे एक मूल रूपरेखा है। यह आपको एक समय में प्रत्येक कंपनी आईडी खींचने, अपने परिवर्तन करने और आगे बढ़ने की अनुमति देता है। आप उन्हें घोंसला कर सकते हैं, उन्हें लूप में शामिल कर सकते हैं या उनमें लूप शामिल कर सकते हैं, जो कुछ भी आपको कार्य करने की सूची में जाने की ज़रूरत है जब तक कि ध्यान देने की कोई आवश्यकता नहीं है।

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 

आशा है कि यह सहायक होगा। अगर मैंने गलत समझा है तो मैं क्षमा चाहता हूं।

संबंधित मुद्दे