2017-12-18 119 views
2

我正在創建一個用於計算用戶庫存狀態的存儲過程。SQL根據庫存和交易計算餘額

設想以下的表稱爲user_inventory許多偶數列:

id_inventory id_user 0 1 2 3 
------------ ------- - - - - 
      2   4 5 0 14 21 

而另一位叫user_transactions

id_tran id_user 0 1 2 3 
------- ------- - - - - 
    54   4 1 0 3 7 
    55   4 2 0 9 8 
    56   4 1 0 2 4 

我想是計算每一列的剩餘庫存狀態的方法減去所有用戶交易的總和後,如下所示:

id_availableInventory id_user 0 1 2 3 
--------------------- ------- - - - - 
        2   4 1 0 0 2 

附加障礙是,有從0標記的列499。

我試圖使用while循環和使用動態SQL和SUM()在更新一次一列,但有兩個範圍和性能問題 - 我不確定這是否是解決此問題的好方法。我使用SQL Server 2012的

DECLARE @counter int 
DECLARE @userid int 
DECLARE @amount int 
DECLARE @sum int 
declare @sql nvarchar(1000) 
SET @counter = 0 
SET @userid = 4 
WHILE @counter < 500 
BEGIN 
    set @sql = 'SELECT @amount = [' + CAST(@counter AS nvarchar) + '] FROM user_inventory WHERE ID_User = ' +CAST(@userid AS nvarchar) 
    EXEC(@sql) 
    set @sql = 'SELECT @sum = SUM([' + CAST(@counter AS nvarchar) + ']) FROM user_transactions WHERE ID_User = ' +CAST(@userid AS nvarchar) 
    EXEC(@sql) 
    set @sql = 'UPDATE user_availableinventory SET [' + CAST(@counter AS nvarchar) + '] = @amount - @sum WHERE ID_User = ' +CAST(@userid AS nvarchar) 
    EXEC(@sql) 
    SET @counter = @counter + 1 
END 

這回Must declare the scalar variable "@amount".多次。 我知道這是一個醜陋的方法,對此問題的任何建議都非常感激。

+1

想象有許多數列的表中的變量試試這個是比較接近我的噩夢。你應該修復你的數據結構。無論進入那些列應該可能在不同的行中。 –

+1

因此,而不是這種結構,每個用戶帳戶500行與「id,inventoryID,數量」列將是一個更快,更好的一個? –

+0

這不是關係數據庫的任何類似於合理數據結構的東西。第0,1,2,3列不知道爲什麼你要循環做這件事。這應該是單個更新聲明。你迫切需要修復這個數據結構,或者考慮使用noSQL類型的存儲。 –

回答

1

您正在接收錯誤,因爲您正在使用變量範圍之外的變量。查詢字符串作爲單獨的會話執行,因此您需要在查詢字符串中聲明變量。

可以通過聲明的查詢字符串

DECLARE @counter int 
DECLARE @userid int 
declare @sql nvarchar(1000) 
SET @counter = 0 
SET @userid = 4 
WHILE @counter < 500 
BEGIN 
    set @sql = ' 
    DECLARE @sum int 
    DECLARE @amount int 

    SELECT 
     @amount = [' + CAST(@counter AS nvarchar) + '] 
     FROM user_inventory WHERE ID_User = ' +CAST(@userid AS nvarchar)+' 

    SELECT 
     @sum = SUM([' + CAST(@counter AS nvarchar) + ']) 
     FROM user_transactions WHERE ID_User = ' +CAST(@userid AS nvarchar)+' 

    UPDATE user_availableinventory SET [' + CAST(@counter AS nvarchar) + '] = @amount - @sum WHERE ID_User = ' +CAST(@userid AS nvarchar) 

    EXEC(@sql) 
    SET @counter = @counter + 1 

END 
+0

這解決了這個錯誤,但沒有解決這個災難的可怕設計。你仍然值得擁有+1,但是哇......我對OP感到不好,他們將不得不使用這個。 –

+0

當你已經有表中的數據時,討論設計問題已經太遲了 –

+0

這實現了我所要做的,但是這個過程非常緩慢(13秒)。我將需要改變我的整個結構。 Fortunetaly,這種結構仍然在設計中,我有時間在產品投入生產之前對其進行重新設計。 –