更新庫存SQL算法2.0版

Create        Procedure sp_ComputeStock
   
@StoreroomId INT = NULL,--庫房編號
  @EquipmentIds VARCHAR(5000= NULL,--設備編號,各設備編號間用逗號隔開,例如:1,2,3,4
  @EquipmentMount VARCHAR(5000= NULL,--設備數量,各設備數量間用逗號隔開,例如:11,15,20,5

  
@Out_equipIdNotExists VARCHAR(5000) OUTPUT,  --不存在的設備ID,各設備用逗號隔開
  @Out_equipNameNotExists VARCHAR(5000) OUTPUT,  --不存在的設備名稱,各設備用逗號隔開
  @Out_equipIdNotEnough VARCHAR(5000) OUTPUT,   --庫存不夠的設備ID,各設備用逗號隔開
  @Out_equipNameNotEnough VARCHAR(5000) OUTPUT,   --庫存不夠的設備名稱,各設備用逗號隔開
  @Out_Stockpile VARCHAR(5000) OUTPUT  --設備ID的庫存量,各設備用逗號隔開
 AS

  
SET NOCOUNT ON
  
SET CURSOR_CLOSE_ON_COMMIT OFF    --設置手動關閉遊標,使事務不會影響到遊標的打開和關閉

  
DECLARE 
    
@Empty CHAR(1), --空串
    @Split CHAR(1),--分隔符
    @equipName VARCHAR(100)
  
SET @Empty = ''
  
SET @Split = ',' 
  
SET @Out_equipIdNotExists = @Empty  --初始化爲空串
  SET @Out_equipIdNotEnough = @Empty
  
SET @Out_equipNameNotExists = @Empty
  
SET @Out_equipNameNotEnough = @Empty
  
SET @Out_Stockpile = @Empty

  
DECLARE 
     
@tb_EquipmentIds TABLE([Id] INT IDENTITY (1,1),EquipmentId INT)--表變量,設備編號表
  DECLARE 
     
@tb_EquipmentMount TABLE([Id] INT IDENTITY (1,1),EquipmentMount INT)--表變量,設備數量表

  
INSERT INTO @tb_EquipmentIds SELECT * FROM dbo.f_splitSTR(@EquipmentIds,@Split)
      
--拆分設備編號,並將結果插入到設備編號表(表變量)中
  INSERT INTO @tb_EquipmentMount SELECT * FROM dbo.f_splitSTR(@EquipmentMount,@Split)
     
--拆分設備數量,並將結果插入到設備數量表(表變量)中

  
  
DECLARE @au_equipmentId VARCHAR(10), --設備編號
          @au_equipmentMount INT,--設備數量
          @var_Mount INT--庫存數量
 
    
--將設備編號表和設備數量表關聯,按設備編號分組統計出各設備的出庫數量
    --注意遍歷了兩次該遊標,第一次用來檢查設備,第二次用來更新設備
    --(若第一次遍歷設備通過後,才進行第二次,否則不進行)

  
DECLARE stockBill_cursor CURSOR LOCAL FAST_FORWARD FOR --聲明並定義快速只進的本地遊標
  SELECT                                                     
     EquipmentId,                                           
     
SUM(EquipmentMount) AS Mount
  
FROM 
    
@tb_EquipmentIds AS a
  
INNER JOIN  
    
@tb_EquipmentMount AS b
  
ON 
    a.
[ID] = b.[ID]
  
GROUP BY EquipmentId
  
  
OPEN stockBill_cursor
    
--第一次遍歷:檢查設備是否在庫房中存在,檢查設備的庫存是否不足。若存在且庫存夠,
    --才進行第二次遍歷(更新庫存)
  FETCH NEXT FROM stockBill_cursor
  
INTO @au_equipmentId@au_equipmentMount
       
--將當前設備編號保存到@au_equipmentId中,將當前設備數量保存到@au_equipmentMount中
  WHILE @@FETCH_STATUS = 0
    
BEGIN
      
SET @var_Mount = NULL
       
--根據庫房號和設備編號從庫存表中找出該設備的存庫數量,並保存到@var_Mount中
      SELECT 
        
@var_Mount = Mount         
      
FROM 
        tb_Stock 
      
WHERE 
        F_StoreroomId 
= @StoreroomId 
      
AND 
        F_EquipmentId 
= @au_equipmentId
    
      
SELECT @equipName = EquipmentName FROM dbo.tb_Equipment WHERE P_EquipmentId = @au_equipmentId

      
IF(@var_Mount IS NULL--若@var_Mount=NULL表明不存在該設備
      BEGIN
        
SET @Out_equipIdNotExists = @Out_equipIdNotExists + @au_equipmentId + @Split
        
SET @Out_equipNameNotExists = @Out_equipNameNotExists + @equipName + @Split
      
END
      
ELSE
      
BEGIN                 --否則存在該設備
        --所取數量與庫存數量比較,若大於庫存數量, 將該設備編號記錄下來。
        IF (@au_equipmentMount > @var_Mount)
        
BEGIN    
          
SET @Out_equipIdNotEnough = @Out_equipIdNotEnough + @au_equipmentId + @Split-
             
-記錄庫存不夠的設備,用逗號隔開
          
SET @Out_equipNameNotEnough = @Out_equipNameNotEnough + @equipName + @Split
          
SET @Out_Stockpile = @Out_Stockpile + LTRIM(STR(@var_Mount))+@Split
        
END     
      
END --  IF(@var_Mount IS NULL)
     FETCH NEXT FROM stockBill_cursor        --取下一條
     INTO @au_equipmentId@au_equipmentMount
    
END -- WHILE 
   
    
--若@Out_equipmentNotExists和@Out_equipmentNotEnough都是空串,表明
   --即不存在庫存不夠的設備,  也沒有庫房中不存在的設備
   IF(@Out_equipIdNotExists = @Empty AND @Out_equipIdNotEnough = @Empty)    
    
BEGIN
       
CLOSE stockBill_cursor    --關閉遊標   
       OPEN stockBill_cursor     --再次打開遊標
       FETCH NEXT FROM stockBill_cursor --第二次遍歷,更新庫存.
       INTO @au_equipmentId@au_equipmentMount
       
BEGIN TRANSACTION

       
WHILE @@FETCH_STATUS = 0
       
BEGIN
         
SET @var_Mount = NULL
           
--根據庫房號和設備編號從庫存表中找出該設備的存庫數量,並保存到@var_Mount中
         SELECT 
           
@var_Mount = Mount        
         
FROM 
           tb_Stock 
         
WHERE 
           F_StoreroomId 
= @StoreroomId 
         
AND 
           F_EquipmentId 
= @au_equipmentId

        
UPDATE 
          tb_Stock
        
SET 
          Mount 
= Mount - @au_equipmentMount
        
WHERE 
          F_StoreroomId 
= @StoreroomId 
        
AND 
          F_EquipmentId 
= @au_equipmentId

        
IF @@ERROR <> 0  --未知錯誤
          BEGIN                          
            
ROLLBACK TRANSACTION  --回滾
            CLOSE stockBill_cursor --關閉遊標
            DEALLOCATE stockBill_cursor
            
RETURN @@ERROR --返回錯誤代碼
          END
         
FETCH NEXT FROM stockBill_cursor --取下一條
         INTO @au_equipmentId@au_equipmentMount
       
END -- WHILE
       COMMIT TRANSACTION       --提交事務
    END --IF(@Out_equipmentNotExists = @Empty AND @Out_equipmentNotEnough = @Empty)
 
   
CLOSE stockBill_cursor    --關閉遊標
   DEALLOCATE stockBill_cursor 
   
RETURN 0               --成功返回(執行該過程沒有系統出錯錯誤)
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章