不明白你的意思。如果不drop掉ReTable,ReTable数据不是越添越多,根本就得不到正确结果嘛问题肯定就出在retable上,不知道这个ReTable你到底是怎么处理的。

解决方案 »

  1.   

    ReTable是正式表,而处理前没见你清理过该表的记录,问题应该在这吧.在存储过程的as后加上
    truncate table ReTable
      

  2.   

    當第一次運行完該存儲過在最後應該把相應的虛擬表刪除
    否則記錄會重復。也就是drop table #stack 
    之類的。
      

  3.   

    因为是测试,所以在存储过程中,没有直接drop talbe ,而是在查询分析中的,在存储过程外执行的delete table /drop table
      

  4.   

    to  xspf ,说得没错,不drop掉ReTable,ReTable数据不是越添越多,由于我是在测试过程,所以每次执行存储过程前,我都会在查询分析器中手工执行删除的东作。我也认为是表的问题,可是为何同一个表,我每执行第一次都是正确的。
      

  5.   

    --如果改用临时表呢?
       CREATE PROCEDURE EXPBOM (@PR char(20)) AS
       begin
       SET NOCOUNT ONCreate Table #ReTable (Lvl char(15),item char(20),MD006 numeric(11,3),MD007 numeric(11,3)) 
       DECLARE @lvl int, @line char(20), @qy1 numeric(11,3), @qy2 numeric(11,3)
       CREATE TABLE #stack (lvl char(15),item char(20), MD006 numeric(11,3), MD007 numeric(11,3))
       INSERT INTO #stack VALUES ('1',@PR,1,1)
       Set @lvl = 1
       WHILE @lvl > 0
          BEGIN 
             IF EXISTS (SELECT * FROM #stack WHERE lvl = Ltrim(cast(@lvl as char(2))))
                BEGIN
    SELECT @PR = item,@QY1=MD006,@QY2=MD007 FROM #stack WHERE lvl = Ltrim(cast(@lvl as char(2))) Order By item DESC
             SELECT @line =Replicate('0',@lvl-1)+Ltrim(Cast(@lvl as char(15)))+Space(10)            
    PRINT @line+@PR --测试用
        Insert into #ReTable(Lvl,item,MD006,MD007) values(@line,@PR,@QY1,@QY2)
             DELETE FROM #stack WHERE lvl = Ltrim(cast(@lvl as char(2))) AND item = @PR
             INSERT #stack SELECT  Ltrim(cast(@lvl+1 as char(2))),MD003,MD006,MD007 FROM BOM WHERE MD001 = @PR  Order BY MD001
             IF @@ROWCOUNT > 0
                  SELECT @lvl = @lvl + 1
             END
             ELSE
                SELECT @lvl = @lvl - 1
         END  
    Select Lvl,item,MD006,MD007 
    from #ReTable --left join INVMB ON item = MB001 
     SET NOCOUNT OFF 
    end
      

  6.   

    谢谢,版主邹键,用 TRUNCATE TABLE(删除表中的所有行,而不记录单个行删除操作),问题解决了,可能是用Delete Tabel 记录单个行删除操作,当第二次插入时,打乱了它的排序。目前老象只有这种解释,不知各位是否还有别的想法。
      

  7.   

    CREATE TABLE BOM(MD001 CHAR(20),MD003 CHAR(20),MD006 numeric(11,3),MD007 numeric(11,3))
      INSERT INTO BOM VALUES('1210-00307000','3250-01307000',1,1)
      INSERT INTO BOM VALUES('1210-00307000','1250-01307001',1,1)
      INSERT INTO BOM VALUES('1210-00307000','3250-01307002',1,1)
      INSERT INTO BOM VALUES('1210-00307000','LA-CHL-50001',1,1)
      INSERT INTO BOM VALUES('1250-01307001','4250-01307000',1,1)
      INSERT INTO BOM VALUES('1250-01307001','4250-01307001',1,1)
      INSERT INTO BOM VALUES('1250-01307001','4250-01307002',1,1)
      INSERT INTO BOM VALUES('LA-CHL-50001','2101-03001000',1,1)
      INSERT INTO BOM VALUES('LA-CHL-50001','2101-03001001',1,1)
      INSERT INTO BOM VALUES('LA-CHL-50001','2101-03001002',1,1)
      INSERT INTO BOM VALUES('LA-CHL-50001','2101-03001003',1,1)
    go   CREATE PROCEDURE EXPBOM (@PR char(20)) AS
       begin
       SET NOCOUNT ONCreate Table #ReTable (Lvl char(15),item char(20),MD006 numeric(11,3),MD007 numeric(11,3)) 
       DECLARE @lvl int, @line char(20), @qy1 numeric(11,3), @qy2 numeric(11,3)
       CREATE TABLE #stack (lvl char(15),item char(20), MD006 numeric(11,3), MD007 numeric(11,3))
       INSERT INTO #stack VALUES ('1',@PR,1,1)
       Set @lvl = 1
       WHILE @lvl > 0
          BEGIN 
             IF EXISTS (SELECT * FROM #stack WHERE lvl = Ltrim(cast(@lvl as char(2))))
                BEGIN
    SELECT @PR = item,@QY1=MD006,@QY2=MD007 FROM #stack 
    WHERE lvl = Ltrim(cast(@lvl as char(2))) Order By item DESC
             SELECT @line =Replicate('0',@lvl-1)+Ltrim(Cast(@lvl as char(15)))+Space(10)            
    PRINT @line+@PR --测试用
        Insert into #ReTable(Lvl,item,MD006,MD007) values(@line,@PR,@QY1,@QY2)
             DELETE FROM #stack WHERE lvl = Ltrim(cast(@lvl as char(2))) AND item = @PR
             INSERT #stack SELECT  Ltrim(cast(@lvl+1 as char(2))),MD003,MD006,MD007 FROM BOM 
    WHERE MD001 = @PR  Order BY MD001
             IF @@ROWCOUNT > 0
                  SELECT @lvl = @lvl + 1
             END
             ELSE
                SELECT @lvl = @lvl - 1
         END  
    Select Lvl,item,MD006,MD007 
    from #ReTable --left join INVMB ON item = MB001 
     SET NOCOUNT OFF 
    end
    goEXEC EXPBOM '0401-95155010' 
    EXEC EXPBOM '0401-95155010' 
    go
    drop proc EXPBOM
    drop table bom/*--结果
    1                   0401-95155010       
    Lvl             item                 MD006         MD007         
    --------------- -------------------- ------------- ------------- 
    1               0401-95155010        1.000         1.0001                   0401-95155010       
    Lvl             item                 MD006         MD007         
    --------------- -------------------- ------------- ------------- 
    1               0401-95155010        1.000         1.000
    --*/
      

  8.   

    临时表可以的,只不过你的测试数据的bom表使用的字段是M006,而存储过程中使用的字段是MD006,两个不对应
      

  9.   

    TO 邹键 Sorry,别外,我把结果集LEFT JOIN 别的表时,能否不让它重新排序,以便保持我展开的BOM结构。 
      

  10.   

    别外,我把结果集LEFT JOIN 别的表时,能否不让它重新排序,以便保持我展开的BOM结构。 
    不能,关联后的顺序不能保证,其实你可以在#ReTable 中增加一个标识列来保证顺序.
    Create Table #ReTable (Lvl char(15),item char(20),MD006 numeric(11,3),MD007 numeric(11,3)
    id int identity) --最后的查询改为:
    Select Lvl,item,MD006,MD007 
    from #ReTable a left join INVMB b ON a.item = b.MB001 
    order by a.id
      

  11.   

    可能确实是delete table的问题,以前看的不知道哪一份资料上说,SQL Server使用delete删除数据行后,并不会立即将该行数据从数据页面中删除,而是仅仅做一个标记,留待专门的维护线程清除(好象记得是这么回事来着)。
    会不会当delete table后立即插入同样的数据时,当时数据页中的原有数据还没有来得及清除,于是SQL Server将其删除标记简单去除,于是表中数据的位置就保留了上一次插入的印记?
      

  12.   

    谢谢楼上的各位,这个展BOM最后还是实行了,但还是留下一些疑问。结贴。