2016-06-23 45 views
0

我有一個在SQL Server 2005上運行的遞歸存儲過程。我測試了它,它運行良好。但是,當我嘗試向其添加其他功能時,我收到以下消息:處理錯誤消息的最佳方法「數據庫中已有一個名爲'#Tablename'的對象。」

數據庫中已有一個名爲'#BOM'的對象。

問題是我需要根據參數創建初始臨時表2種不同的方式。臨時表用於擴展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 

我希望有人有一個好主意,然後我必須使這真正醜陋。

+0

遞歸存儲過程?這看起來像你可以用遞歸cte來代替它。將會比這更簡單地處理。爲了讓你的代碼和你正在做的程序一起工作,需要動態的sql。這將很快失去控制,併成爲維護的噩夢。 –

+0

@Sean這不需要任何動態SQL,這簡直是不真實的。當人們堅持事實並在門外留下他們的意見時,SO最有效。記住,僅僅因爲對你來說簡單的事情並不意味着對每個人來說簡單。加上猜測並沒有幫助任何人來到這裏尋找答案。 – Joe

+0

也許你可以分享你的表格結構,樣本數據和所需的輸出。我很樂意演示如何爲此使用遞歸cte。那麼當你發佈了所有必要的事實來幫助你時,我會堅持這些事實。由於他們不是全部貼出來,我不得不推測。 –

回答

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 
+0

太棒了!我不相信我沒有想到它。當我遇到那個錯誤時,我的大腦肯定已經滿了,完美的工作! – Joe

相關問題