2017-12-18 18 views
2

私はユーザーの在庫ステータスを計算するストアドプロシージャを作成しています。SQL在庫と取引に基づく残高の計算

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 

と呼ば:

次の表を想像してみては、多くの番号の列を持つuser_inventoryと呼ばれますすべてのユーザートランザクションの合計を減算した後、次のようになります。

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

追加の障害物は、I)は、(whileループを使用して、動的SQLとSUMを使用して、一度に1つの列を更新しようとしたが、範囲と性能の両方を持っていた0から499

に標識された列があるということですそれがこの問題の良いアプローチであるかどうかはわかりません。私は、これはMust declare the scalar variable "@amount".複数回返された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 

SQL Serverを使用しています。 私はこれが醜いアプローチであることを認識しています。この問題に対する提案は非常に感謝しています。

+1

内部変数を宣言することによって、これを試すことができますが、私にとっては悪夢にかなり近いです。データ構造を修正する必要があります。それらの列に入るものは、おそらく別々の行にあるはずです。 –

+1

したがって、この構造の代わりに、 "id、inventoryID、amount"のような列を持つユーザーアカウントあたり500行のものが、より高速で優れたものになりますか? –

+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、この構造はまだ設計されており、私はそれが生産に当たる前にそれを再加工する時間があります。 –

関連する問題