Northwind Database (Document! X Sample)
AdventureWorks Database / dbo Schema / dbo.uspGetWhereUsedProductID Stored Procedure
In This Topic
    dbo.uspGetWhereUsedProductID Stored Procedure
    In This Topic
    Description
    Stored procedure using a recursive query to return all components or assemblies that directly or indirectly use the specified ProductID.
    Properties
    Creation Date27/10/2017 14:33
    Encrypted
    Ansi Nulls
    Parameters
    ParameterDirectionDescriptionData TypeSize
    InInput parameter for the stored procedure uspGetWhereUsedProductID. Enter a valid ProductID from the Production.Product table.Integer4
    InInput parameter for the stored procedure uspGetWhereUsedProductID used to eliminate components not used after that date. Enter a valid date.DBTimeStamp4
    Return Value Integer4
    Objects that dbo.uspGetWhereUsedProductID depends on
     Database ObjectObject TypeDescriptionDep Level
    Production.BillOfMaterials tableProduction.BillOfMaterialsTableItems required to make bicycles and bicycle subassemblies. It identifies the heirarchical relationship between a parent product and its components.1
    dbo.Flag datatypedbo.FlagUser Defined Data Type 4
    Production.Product tableProduction.ProductTableProducts sold or used in the manfacturing of sold products.1
    Production.ProductCategory tableProduction.ProductCategoryTableHigh-level product categorization.3
    Production.ProductModel tableProduction.ProductModelTableProduct model classification.2
    Production.ProductSubcategory tableProduction.ProductSubcategoryTableProduct subcategories. See ProductCategory table.2
    Production.UnitMeasure tableProduction.UnitMeasureTableUnit of measure lookup table.2
    Procedure Source Code
    CREATE PROCEDURE [dbo].[uspGetWhereUsedProductID]
        @StartProductID [int],
        @CheckDate [datetime]
    AS
    
    BEGIN
        SET NOCOUNT ON;
    
        --Use recursive query to generate a multi-level Bill of Material (i.e. all level 1 components of a level 0 assembly, all level 2 components of a level 1 assembly)
        WITH [BOM_cte]([ProductAssemblyID], [ComponentID], [ComponentDesc], [PerAssemblyQty], [StandardCost], [ListPrice], [BOMLevel], [RecursionLevel]) -- CTE name and columns
        AS (
            SELECT b.[ProductAssemblyID], b.[ComponentID], p.[Name], b.[PerAssemblyQty], p.[StandardCost], p.[ListPrice], b.[BOMLevel], 0 -- Get the initial list of components for the bike assembly
            FROM [Production].[BillOfMaterials] b
                INNER JOIN [Production].[Product] p 
                ON b.[ProductAssemblyID] = p.[ProductID] 
            WHERE b.[ComponentID] = @StartProductID 
                AND @CheckDate >= b.[StartDate] 
                AND @CheckDate <= ISNULL(b.[EndDate], @CheckDate)
            UNION ALL
            SELECT b.[ProductAssemblyID], b.[ComponentID], p.[Name], b.[PerAssemblyQty], p.[StandardCost], p.[ListPrice], b.[BOMLevel], [RecursionLevel] + 1 -- Join recursive member to anchor
            FROM [BOM_cte] cte
                INNER JOIN [Production].[BillOfMaterials] b 
                ON cte.[ProductAssemblyID] = b.[ComponentID]
                INNER JOIN [Production].[Product] p 
                ON b.[ProductAssemblyID] = p.[ProductID] 
            WHERE @CheckDate >= b.[StartDate] 
                AND @CheckDate <= ISNULL(b.[EndDate], @CheckDate)
            )
        -- Outer select from the CTE
        SELECT b.[ProductAssemblyID], b.[ComponentID], b.[ComponentDesc], SUM(b.[PerAssemblyQty]) AS [TotalQuantity] , b.[StandardCost], b.[ListPrice], b.[BOMLevel], b.[RecursionLevel]
        FROM [BOM_cte] b
        GROUP BY b.[ComponentID], b.[ComponentDesc], b.[ProductAssemblyID], b.[BOMLevel], b.[RecursionLevel], b.[StandardCost], b.[ListPrice]
        ORDER BY b.[BOMLevel], b.[ProductAssemblyID], b.[ComponentID]
        OPTION (MAXRECURSION 25) 
    END;
    
    See Also