2017-12-18 157 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,这种结构仍然在设计中,我有时间在产品投入生产之前对其进行重新设计。 –