我只是原型化一個新系統,用於推遲某些操作,直到某個數據庫超時。我想出了(我認爲)一個非常簡單的模式。我第一次在SQL Server 2005 Express上進行原型設計,但是在2008 Developer上確認了同樣的問題。我得到的錯誤是:SQL Server中的索引視圖有問題,錯誤8646
消息8646,級別21,狀態1,過程 取消,6號線無法找到索引ID 1指數 項,表 277576027的,在數據庫 'XXXXXX' 。 指示索引已損壞或存在 與當前更新 計劃有關的問題。運行DBCC CHECKDB或DBCC CHECKTABLE。如果問題仍然存在,請致電 聯繫產品支持。
我使用的模式是:
create schema Writeback authorization dbo
create table Deferrals (
ClientID uniqueidentifier not null,
RequestedAt datetime not null,
CompletedAt datetime null,
CancelledAt datetime null,
ResolvedAt as ISNULL(CompletedAt,CancelledAt) persisted,
constraint PK_Writeback_Deferrals PRIMARY KEY (ClientID,RequestedAt) on [PRIMARY],
constraint CK_Writeback_Deferrals_NoTimeTravel CHECK ((RequestedAt <= CompletedAt) AND (RequestedAt <= CancelledAt)),
constraint CK_Writeback_Deferrals_NoSchrodinger CHECK ((CompletedAt is null) or (CancelledAt is null))
/* TODO:FOREIGN KEY */
)
create view Pending with schemabinding as
select
ClientID
from
Writeback.Deferrals
where
ResolvedAt is null
go
alter table Writeback.Deferrals add constraint
DF_Writeback_Deferrals_RequestedAt DEFAULT CURRENT_TIMESTAMP for RequestedAt
go
create unique clustered index PK_Writeback_Pending on Writeback.Pending (ClientID)
go
create procedure Writeback.Defer
@ClientID uniqueidentifier
as
set nocount on
insert into Writeback.Deferrals (ClientID)
select @ClientID
where not exists(select * from Writeback.Pending where ClientID = @ClientID)
go
create procedure Writeback.Cancel
@ClientID uniqueidentifier
as
set nocount on
update
Writeback.Deferrals
set
CancelledAt = CURRENT_TIMESTAMP
where
ClientID = @ClientID and
CompletedAt is null and
CancelledAt is null
go
create procedure Writeback.Complete
@ClientID uniqueidentifier
as
set nocount on
update
Writeback.Deferrals
set
CompletedAt = CURRENT_TIMESTAMP
where
ClientID = @ClientID and
CompletedAt is null and
CancelledAt is null
go
這引發了錯誤如下代碼:
declare @ClientA uniqueidentifier
declare @ClientB uniqueidentifier
select @ClientA = newid(),@ClientB = newid()
select * from Writeback.Pending
exec Writeback.Defer @ClientA
select * from Writeback.Pending
exec Writeback.Defer @ClientB
select * from Writeback.Pending
exec Writeback.Cancel @ClientB --<-- Error being raised here
select * from Writeback.Pending
exec Writeback.Complete @ClientA
select * from Writeback.Pending
select * from Writeback.Deferrals
我見過幾個人遇到這樣的問題,但他們似乎在他們的觀點中有彙總(並且MS的消息表示他們將刪除在2005 SP 1中創建此類索引視圖的能力),或者他們通過在其聯接子句中應用合併聯接來解決此問題(但我沒有一個)。
最初在Deferrals表中沒有計算列,而視圖中的where子句分別爲NULL測試了CompletedAt和CancelledAt列。但我改變了上面的看法,只是爲了看看我能否挑起不同的行爲。
我所有的SET選項看起來都適合使用索引視圖,如果它們不是,我希望拋出一個不太暴力的錯誤。
任何想法?
正如我在對Mladen Prajdic的評論中指出的 - 我可以在新創建的數據庫中運行上述腳本,但仍然會出現此錯誤。如果索引可能會快速損壞(在空表上創建2個插入),那麼我會擔心SQL Server的穩定性。另外,如上所述,我發現「其他」原因在網上提出這個消息,而且他們實際上並沒有索引損壞。 – 2009-07-03 10:17:50