在SQL Server 2016数据库中,我有一个包含财务事务的表:
CREATE TABLE Transactions
TxnId int NOT NULL IDENTITY(1,1) PRIMARY KEY,
AccountId int NOT NULL,
DateTime datetime NOT NULL,
Amount money NOT NULL
)
我写了一个VIEW
来显示运行余额信息:
CREATE VIEW TransactionsWithBalance AS
SELECT
*,
SUM( Amount ) OVER ( PARTITION BY AccountId ORDER BY [DateTime], TxnId ) AS Balance
FROM
Transactions
当我查询此视图时,Balance
列包含所有NULL
值:
SELECT
*
FROM
TransactionsWithBalance
TxnId AccountId DateTime Amount Balance
1 1 2017-01-01 100.00 NULL
2 1 2017-01-02 200.00 NULL
3 2 2017-01-01 10.00 NULL
4 1 2017-01-03 300.00 NULL
但是当我在SSMS中直接运行查询(使用SUM( Amount ) OVER ( PARTITION BY... )
)查询时,我会在Balance
列中获得预期值。
TxnId AccountId DateTime Amount Balance
1 1 2017-01-01 100.00 100.00
2 1 2017-01-02 200.00 300.00
3 2 2017-01-01 10.00 10.00
4 1 2017-01-03 300.00 600.00
为什么在NULL
内查询时汇总返回VIEW
值?
答案 0 :(得分:4)
这是元数据不同步时可能发生的事情之一,因为您没有:
只要视图底层的对象发生变化,就调用sp_refreshview
说明
如果未使用模式绑定创建视图,则在对视图下方影响视图定义的对象进行更改时,应运行 sp_refreshview 。否则,查询时视图可能会产生意外结果。
更好的选择可能是使用架构绑定。这也将迫使您不在视图中使用SELECT *
,并为表格使用两部分名称,这两种方法都是最佳做法:
CREATE VIEW dbo.TransactionsWithBalance
WITH SCHEMABINDING
AS
SELECT
TRN.TxnId,
TRN.AccountId,
TRN.[DateTime],
TRN.Amount,
Balance =
SUM(TRN.Amount) OVER (
PARTITION BY TRN.AccountId
ORDER BY TRN.[DateTime], TRN.TxnId)
FROM
dbo.Transactions AS TRN;