Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何使用VB.NET在SQL Server数据库中维护运行总数?_Sql Server_Vb.net_Sql Server 2008 - Fatal编程技术网

Sql server 如何使用VB.NET在SQL Server数据库中维护运行总数?

Sql server 如何使用VB.NET在SQL Server数据库中维护运行总数?,sql-server,vb.net,sql-server-2008,Sql Server,Vb.net,Sql Server 2008,我正在使用Visaul Studio 2010构建一个Windows窗体应用程序,以维护SQL Server 2008数据库中的表。该表名为现金簿,以下是进一步的详细信息: DATE | DESCRIPTION | DEBIT | CREDIT | BALANCE --------|----------------|---------|-----------|--------- 1/1/2011| CASH BALANCE | | |

我正在使用Visaul Studio 2010构建一个Windows窗体应用程序,以维护SQL Server 2008数据库中的表。该表名为现金簿,以下是进一步的详细信息:

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 INTO CASHBOOK  ( DESCRIPTION, DEBIT, BALANCE )
'asdf', 2500, SELECT TOP(1) BALANCE FROM CASHBOOK + 2500

这有点笨手笨脚,但这里有一种用余额信息更新整个表的方法

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,并仅在需要时调用该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
参见本文作者


你为什么要这么做?这是应该作为报告/查看功能计算的内容。我建议通过各种方法创建一个包含运行总计列的视图


或者,如果您在VB.Net中查看此信息,请在应用程序中计算。

我同意Joel的观点,您应该在运行时计算此信息,而不是将运行总数存储在数据库中。以下是如何在sql server中使用递归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 ID=@i

    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
下面是一个关于递归查询的博客:


此外,还对运行总计进行了冗长的讨论。

递归CTE的一个潜在问题是最大深度限制为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])+@bal
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. */

整体转换为合理的情况。您需要考虑的一个问题是,如果您将按历史顺序插入行,即不只是按升序插入-假设您在2011年1月1日插入另一行,那么您将不得不更新所有后续行的余额,这可能是一个令人讨厌的HIT,我会说…您不应该!这些事情应该在最底层完成:在SQL Server数据库中。创建一个包含运行总计列的视图:您建议如何填充此列-通过三角形联接?所需的工作量与行数的平方成正比。在应用程序中计算:所以OP需要将每一行返回到他们的应用程序中,然后每次将它们相加?