处理错误消息的最佳方法“数据库中已经有一个名为'#Tablename'的对象。”

时间:2016-06-23 18:10:16

标签: sql-server

我有一个在SQL Server 2005上运行的递归存储过程。我测试了它并且运行良好。但当我尝试添加其他功能时,我收到了消息:

  

数据库中已经有一个名为'#BOM'的对象。

问题是我需要根据参数以不同的方式创建初始临时表。临时表用于扩展BOM(物料清单)的一组报告。 BOM可以包含具有自己的BOM的子装配的零件。在最简单的形式中,我需要这个工作:

create PROCEDURE [dbo].[ExpandBOMTestError2]
(
    @Similiar bit = 0
)AS
BEGIN

    IF @Similiar = 0
        SELECT '1' As Col INTO #BOM
    ELSE
        SELECT '2' As Col INTO #BOM

    SELECT * FROM #BOM

END

我甚至试过这个,虽然我宁愿避免这种丑陋和混乱的事情我会接受它,如果它会起作用:

create PROCEDURE [dbo].[ExpandBOMTestError]
(
    @Similiar bit = 0
)AS
BEGIN

    IF @Similiar = 0
        BEGIN
            IF (SELECT object_id('TempDB..#BOM')) IS NOT NULL
                DROP TABLE #BOM
            SELECT '1' As Col INTO #BOM
        END
    ELSE
        BEGIN
            IF (SELECT object_id('TempDB..#BOM')) IS NOT NULL
                DROP TABLE #BOM
            SELECT '2' As Col INTO #BOM
        END

    SELECT * FROM #BOM

END

我也附上原始程序,因为任何人都希望提供替代解决方案,这些解决方案可能适用于我的精简版示例,但不适用于实际生产代码。

create PROCEDURE [dbo].[ExpandBOMList]
(
    @ItemID varchar(100),
    @Level int,
    @EffectiveDate datetime = null,
    @ExcludeIgnoreCost bit = 0,
    @MaxBOMLevel int = 99,
    @Similiar bit = 0
)AS
BEGIN

    DECLARE @NewLevel int

    IF @Level = 0
        BEGIN
            IF @Similiar = 0
                SELECT @ItemID AS SubAssembly, @ItemID AS Component, Null AS EffectiveDate, 1 AS QPA, 0 AS BOMLevel INTO #BOM
            ELSE
                SELECT IMA_ItemID AS SubAssembly, IMA_ItemID AS Component, Null AS EffectiveDate, 1 AS QPA, 0 AS BOMLevel INTO #BOM FROM Item WHERE IMA_ItemID LIKE @ItemID + '%' 
            SET @NewLevel = @Level + 1
            EXEC ExpandBOMList @ItemID, @NewLevel, @ExcludeIgnoreCost, @MaxBOMLevel
        END
    ELSE
        BEGIN
            INSERT #BOM SELECT ItemParent.IMA_ItemID, ItemChild.IMA_ItemID, Null, PST_QtyPerAssy, @Level
                            FROM ProductStructureHeader
                                JOIN ProductStructure ON PST_PSH_RecordID = PSH_RecordID
                                LEFT OUTER JOIN Item AS ItemParent ON PSH_IMA_RecordID = ItemParent.IMA_RecordID 
                                LEFT OUTER JOIN Item AS ItemChild ON PST_IMA_RecordID = ItemChild.IMA_RecordID 
                                JOIN #BOM ON ItemParent.IMA_ItemID = Component AND BOMLevel = @Level - 1
                            WHERE PST_QtyPerAssy <> 0 AND PST_EffStopDate IS NULL AND BOMLevel <= @MaxBOMLevel

            IF @@rowcount > 0
                BEGIN
                    SET @Level = @Level + 1
                    EXEC ExpandBOMList @ItemID, @Level, @ExcludeIgnoreCost, @MaxBOMLevel
                END
        END

        IF @Level = 0
            SELECT Component AS ItemID, IMA_ItemName AS ItemName, BOMLevel
                FROM #BOM
                    JOIN Item on IMA_ItemID = Component


END

我希望有一个好主意,然后才能让这个真正丑陋。

1 个答案:

答案 0 :(得分:1)

对于简单示例,我将执行以下操作。如果我可以提供任何建议,我会查看您发布的原始程序并更新我的答案。它看起来像你正在做的一些相当复杂的东西。我需要时间和数据来尝试解决除了你正在做的事情以外的事情。直觉是使用层次结构可能是合适的。

编辑我的原始答案以说明递归性质。

create PROCEDURE [dbo].[ExpandBOMTestError2]
(
    @Similiar bit = 0
)AS
BEGIN    
  IF (SELECT object_id('TempDB..#BOM')) IS NULL
      Create Table #BOM (Col Int)
  IF @Similiar = 0
      Insert #BOM SELECT '1' 
  ELSE
      Insert #BOM SELECT '2' 

  SELECT * FROM #BOM
END