2013-04-11 177 views
3

我有一個存儲過程,更新多個位置的庫存項目。我主要試圖做的是允許正確記錄庫位之間的庫存轉移。更新記錄,如果失敗,插入記錄,然後更新

我遇到的問題是,某些位置沒有爲大多數類型的庫存物品的記錄,所以當我嘗試更新的數量(-1從開始的位置,+1到新的位置)有沒有記錄要更新。

這裏是我的存儲過程:

CREATE procedure dbo.Inv_Transfer (@p_hStock numeric, 
@p_sFProp varchar(20), @p_hTProp numeric, 
@p_dQuan numeric, @p_Date datetime, 
@p_sUser1 varchar(1000),@p_sUser2 varchar(1000)) 
as 
declare 
    @v_FInvhMy numeric, 
    @v_TInvhMy numeric, 
    @v_sStockCode varchar(10), 
    @v_hFProp numeric, 
    @v_ibegin int, 
    @v_iend int 
begin 

    set @v_ibegin = charindex('(', @p_sFProp ) 
    if @v_ibegin <= 0 
    begin 
     raiserror('From property string not readable',16,1, @p_sFProp) 
     return(0) 
    end 
    else 
    begin 
     set @v_iend = charindex (')',@p_sFProp) 
     set @v_hFProp = substring(@p_sFProp,@v_ibegin + 1,@v_iend - @v_ibegin -1) 
    end 

    select @v_sStockCode = sCode from mm2stock where hMy = @p_hStock 
    if @@ERROR<> 0 
    begin 
     raiserror('Stock read failed ',16,1) 
     return(0) 
    end 
    select @v_FInvhMy = hMy from mm2inventory where hStock = @p_hStock and hStoreProp = @v_hFprop 
    if @@ERROR<> 0 
    begin 
     raiserror('From inventory read failed ',16,1) 
     return(0) 
    end 
    select @v_TInvhMy = hMy from mm2inventory where hstock = @p_hStock and hStoreProp = @p_hTProp 
    if @@ERROR<> 0 
    begin 
     raiserror('To inventory read failed ',16,1) 
     return(0) 
    end 
    update mm2inventory set iQtyonHand = iQtyonHand - @p_dquan where hmy = @v_FInvhMy 
    if @@ERROR<> 0 
    begin 
     raiserror('Update from inventory failed ',16,1) 
     return(0) 
    end   
    update mm2inventory set iQtyonHand = iQtyonHand + @p_dquan where hmy = @v_TInvhMy 
    if @@ERROR<> 0 
    begin 
     raiserror('Update to inventory failed ',16,1) 
     return(0) 
    end  
    else 
    begin 
     INSERT INTO mm2inventory (scode, hstock, hstoreprop, dcosteach, dbillprice, ireorderlevel, ireorderqty, iqtyonorder, iqtyonhand, suser1, suser2, suser3, suser4, snotes) 
     SELECT (SELECT hmy + 1 where hmy in (select max(hmy) from mm2inventory)),@p_hStock,@p_hTProp,(SELECT dcosteach from mm2inventory where hstock = @p_hStock and hstoreprop = @v_hFProp),(SELECT dbillprice from mm2inventory where hstock = @p_hStock and hstoreprop = @v_hFProp),(SELECT ireorderlevel from mm2inventory where hstock = @p_hStock and hstoreprop = @v_hFProp),(SELECT ireorderqty from mm2inventory where hstock = @p_hStock and hstoreprop = @v_hFProp),0,0,'','','','','' FROM mm2inventory 

     update mm2inventory set iQtyonHand = iQtyonHand + @p_dquan where hmy = @v_TInvhMy 
    end 
    insert into mm2InvXfer(sStock,hinvfrom,hinvto,dquant,dtdate,sUser1,sUser2) 
     values (@v_sStockCode,@v_FinvhMy, @v_TInvhMy, @p_dquan, 
     isnull(@p_Date,getdate()), @p_sUser1, @p_sUser2) 
    if @@ERROR<> 0 
    begin 
     raiserror('Insert into inventoryxfer table failed ',16,1) 
     return(0) 
    end 
end 

摘錄我的工作:

update mm2inventory set iQtyonHand = iQtyonHand - @p_dquan where hmy = @v_FInvhMy 
    if @@ERROR<> 0 
    begin 
     raiserror('Update from inventory failed ',16,1) 
     return(0) 
    end   
    update mm2inventory set iQtyonHand = iQtyonHand + @p_dquan where hmy = @v_TInvhMy 
    if @@ERROR<> 0 
    begin 
     raiserror('Update to inventory failed ',16,1) 
     return(0) 
    end  
    else 
    begin 
     INSERT INTO mm2inventory (scode, hstock, hstoreprop, dcosteach, dbillprice, ireorderlevel, ireorderqty, iqtyonorder, iqtyonhand, suser1, suser2, suser3, suser4, snotes) 
     SELECT (SELECT hmy + 1 where hmy in (select max(hmy) from mm2inventory)),@p_hStock,@p_hTProp,(SELECT dcosteach from mm2inventory where hstock = @p_hStock and hstoreprop = @v_hFProp),(SELECT dbillprice from mm2inventory where hstock = @p_hStock and hstoreprop = @v_hFProp),(SELECT ireorderlevel from mm2inventory where hstock = @p_hStock and hstoreprop = @v_hFProp),(SELECT ireorderqty from mm2inventory where hstock = @p_hStock and hstoreprop = @v_hFProp),0,0,'','','','','' FROM mm2inventory 

     update mm2inventory set iQtyonHand = iQtyonHand + @p_dquan where hmy = @v_TInvhMy 
    end 

所以,你可以在上面看到,我試圖更新(工作正常如果兩個存儲位置的庫存項目都存在記錄),但是如果出現錯誤,那麼我想爲該特定庫存項目插入新行,然後使用新數量值更新它,但是我做錯了某些事情。

誰能告訴我我做錯了什麼? 感謝

+1

建議:使用交易。當您必須更新多個表並出錯時,您應該能夠撤消(回滾)所有更改以保持數據有效。 – ZippyV 2013-04-11 20:03:20

+2

另一個建議:使用關鍵字'EXISTS'來檢查一行是否已經存在。 http://msdn.microsoft.com/en-us/library/ms188336.aspx – ZippyV 2013-04-11 20:05:10

+2

感謝您的建議Zippy。至於'EXISTS',可能是這樣的: IF(EXISTS(SELECT'record' FROM'table' WHERE' inventory_Item_May_exist'))'UPDATE' ELSE'INSERT_THEN_UPDATE'? – reubenCanowski 2013-04-11 20:14:02

回答

1

這裏是你可以做的一個簡單的示例,你不需要幾乎一樣多的錯誤處理(我假設有上product_code唯一約束):

--Make sure the inventory record exists: 

INSERT INTO inventory (product_code, product_name) 
SELECT product_code, product_name FROM source s 
WHERE NOT EXISTS (
    SELECT product_code 
    FROM inventory i 
    WHERE i.product_code = s.product_code) 

--Updates the inventory record because you now know it exists: 

UPDATE i 
SET i.qty = i.qty + s.qty --obviously change sign where appropriate 
FROM inventory i 
JOIN source s ON s.product_code = i.product_code 

這是什麼意志do每次都嘗試INSERT,但它自然會過濾掉任何已存在的內容。如果對INSERT沒有任何影響,則不會發生任何事情。那麼你可以輕鬆地追求UPDATE