【问题标题】:SQL Server : recursive update statementSQL Server:递归更新语句
【发布时间】:2013-07-06 03:17:02
【问题描述】:

我对 SQL 有点陌生,我正在尝试找出在 SQL Server 2012 中无需对更新语句进行硬编码的最佳方法。

基本上,我有一个带有列 (CompanyID, ParentID, ParentPriceAdj, CompanyPriceAdj) 的公司分层表(想想供应链)。每家公司都由其母公司分配一个价格调整,该调整修改了PartMaster 表中的标价,最终价格是通过将调整从父级传递到子级来计算的。

如果父母的价格调整得到更新,我希望这反映在他所有的子公司等等

又名:

当为给定的updatedcompanyID 更新CompanyPriceAdj 时,我想递归地找到孩子CompanyID 的(ParentId = updatedCompanyID)并将他们的ParentPriceAdj 更新为ParentCompany 的(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

【问题讨论】:

    标签: sql sql-server recursion sql-update sql-server-2012


    【解决方案1】:

    您可以在 t-sql 中使用 WITH 表达式来获取给定子记录的所有父记录。并且可以根据您的逻辑相应地更新记录集中的每条记录。

    这里是 WITH 表达式的链接 --

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

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

    【讨论】:

      【解决方案2】:

      您是否考虑过使用 CURSOR?这有点开销,但它可能会给你你需要的东西。如果您不熟悉,以下是基本大纲。它允许您一次提取每个公司 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
      

      希望这会有所帮助。如果我误解了,我深表歉意。

      【讨论】:

        【解决方案3】:

        递归 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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-10-30
          • 2016-12-21
          • 1970-01-01
          • 2016-03-28
          • 2021-12-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多