12

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

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

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

又名:

CompanyPriceAdj为给定更新 a 时updatedcompanyID,我想递归地找到孩子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
4

3 回答 3

12

递归 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
于 2013-07-08T19:55:40.640 回答
3

您可以在 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

于 2013-07-08T18:38:57.900 回答
-1

你看过使用 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

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

于 2013-07-08T18:50:18.057 回答