2011-03-04 6 views
2

私はVisaul Studio 2010を使用して、SQL Server 2008データベースにテーブルを維持するためのWindows Formsアプリケーションを構築しています。テーブルには、CASHBOOKという名前で、ここでは詳細は:VB.NETを使用してSQL Serverデータベースの合計をどのように維持できますか?

DATE | DESCRIPTION | DEBIT | CREDIT | BALANCE 
--------|----------------|---------|-----------|--------- 
1/1/2011| CASH BALANCE |   |   | 5000 
1/1/2011| SALES   | 2500 |   | 7500 
2/1/2011| PURCHASE  |   | 3000  | 4500 
2/1/2011| RENT   |   | 4000  | 500 
2/1/2011| SALES   | 5000 |   | 5500 

私が適切に挿入するためにCASHBOOKTABLEADAPTER.INSERT(...)を使用することができますが、私の問題は、どのように私はBALANCE列を更新しますか?

+3

http://www.livephysics.com/ptools/convert-case.phpわかりやすいケースに変換する。 –

+0

2011年1月1日に別の行を挿入すると、歴史的に(つまり、日付の昇順ではなく)行を挿入するかどうかについて考える必要があります。すべてのその後の行は厄介なヒットになる可能性があります – AdaTheDev

+1

私はそう言うでしょう...あなたはすべきではありません!これらはSQL Serverデータベースの最下位レベルで実行する必要があります。 –

答えて

0

あなたは、サブクエリで次のようなものの挿入を試すことができます。

INSERT INTO CASHBOOK (DESCRIPTION, DEBIT, BALANCE) 
'asdf', 2500, SELECT TOP(1) BALANCE FROM CASHBOOK + 2500 
0

それが利き少し重いですが、ここでは残高情報との完全なテーブルを更新するための方法ですが。

update 
    a 
set 
    a.Balance = (
     select sum(isnull(x.debit, 0.0) - isnull(x.credit, 0.0)) 
     from cashbook x 
     where x.Date < a.Date 
     or (x.Date = a.Date and x.ID <= a.ID) 
    ) + (
     select top 1 y.Balance 
     from cashbook y 
     where y.debit is null 
     and y.credit is null 
     order by y.ID 
    ) 
from 
    cashbook a 

これは、テーブルに残高がある場合にのみ有効です。より適切な解決策は、このロジックを含むUDFを作成し、必要なときにのみ特定の行の残高フィールドを計算することです。それは本当にあなたの使い方によって異なります。

create function dbo.GetBalance(@id int) returns decimal(12, 2) as 
begin 

declare @result decimal(12, 2) = 0.0 

select 
     @result = (
      select sum(isnull(x.debit, 0.0) - isnull(x.credit, 0.0)) 
      from cashbook x 
      where x.Date < a.Date 
      or (x.Date = a.Date and x.ID <= a.ID) 
     ) + (
      select top 1 y.Balance 
      from cashbook y 
      where y.debit is null 
      and y.credit is null 
      order by y.ID 
     ) 
from 
    cashback a 
where 
    a.ID = @id 

return @result 

end 
0

ことで、この記事を参照してください?これは、レポート/表示機能として計算されるべきものです。私は、実行中の合計列(これを達成するためのさまざまな方法)でビューを作成することをお勧めします。

また、VB.Netでこれを表示している場合は、アプリで計算してください。

+0

実行中の合計列を含むビューの作成:この列には、三角形結合を使用してどのようにデータが入力されているとお考えですか?必要な作業は、行数の2乗に比例して増加します。アプリケーションでそれを計算する:したがって、OPはアプリケーションにすべての行を戻す必要がありますし、それらのすべての時間を合計する必要がありますか? –

0

私はJoelに同意します。実行時にこれを計算して、合計をデータベースに格納しないでください。ここでは、SQLサーバーで再帰CTEを使用して、実行中の合計を把握する方法の例を示します。

declare @values table (ID int identity(1,1), Value decimal(4,2)) 
declare @i int 

insert into @values values (1.00) 
insert into @values values (2.00) 
insert into @values values (3.00) 
insert into @values values (4.00) 
insert into @values values (5.00) 
insert into @values values (6.00) 

select @i=min(ID) from @values 

;with a as 
(
    select ID, Value, Value as RunningTotal 
    from @values 
    where [email protected] 

    union all 
    select b.ID, b.Value, cast(b.Value + a.RunningTotal as decimal(4,2)) as RunningTotal 
    from @values b 
     inner join a 
      on b.ID=a.ID+1 

) 
select * from a 

は、ここでは再帰クエリのブログだ:合計の実行についてのRecursive CTEs

またhere's長いdiscusson。

0

再帰的CTEの潜在的な問題の1つは、最大深度制限32767です。これは、運用環境では不可能なことがあります。

このソリューションでは、トランザクションシーケンスの序数であるid列を追加して、残りの場所に残高列を更新します。

declare @t table(id int identity(1,1) not null 
, [DATE] date not null 
, [DESCRIPTION] varchar(80) null 
, [DEBIT] money not null default(0) 
, [CREDIT] money not null default(0) 
, [BALANCE] money not null default(0) 
); 

declare @bal money=0; 

insert into @t([DATE],[DESCRIPTION],[DEBIT],[CREDIT],[BALANCE]) 
select '1/1/2011','CASH BALANCE',0,0,5000 UNION ALL 
select '1/1/2011','SALES',2500,0,0 UNION ALL 
select '2/1/2011','PURCHASE',0,3000,0 UNION ALL 
select '2/1/2011','RENT',0,4000,0 UNION ALL 
select '2/1/2011','SALES',5000,0,0; 


set @bal=(select top 1 [BALANCE] from @t order by id); /* opening balance is stored but not computed, so we simply look it up here. */ 

update t 
set @bal=t.[BALANCE]=(t.[DEBIT]-t.[CREDIT])[email protected] 
output 
inserted.* 
from @t t 
left join @t t0 on t0.id+1=t.id; /*should order by id by default, but to be safe we force the issue here. */ 
関連する問題