Ich war gerade dabei, ein neues System für das Zurückstellen bestimmter Operationen bis zu außerhalb der Stunden in einer unserer Datenbanken zu prototypieren. Ich habe (was ich denke) ein ziemlich einfaches Schema entwickelt. Ich habe das erste Mal mit SQL Server 2005 Express prototypisiert, habe aber das gleiche Problem für den Entwickler 2008 behoben. Der Fehler Ich erhalte ist:Problem mit der indizierten Sicht in SQL Server, Fehler 8646
Msg 8646, Ebene 21, Status 1, Verfahren abbrechen, Line 6 Kann nicht Index Eintrag in Index-ID 1 der Tabelle 277.576.027, in der Datenbank 'xxxxxx' finden . Der angezeigte Index ist beschädigt oder es gibt ein Problem mit dem aktuellen Update Plan. Führen Sie DBCC CHECKDB oder DBCC CHECKTABLE aus. Wenn das Problem weiterhin besteht, wenden Sie sich an den Produkt-Support.
Das Schema Ich verwende ist:
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
Und der Code, der Fehler provoziert wie folgt:
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
Ich habe zu begegnen solche Probleme ein paar andere gesehen, aber sie scheinen entweder Aggregate in ihren Ansichten zu haben (und eine Nachricht von MS, dass sie die Möglichkeit zum Erstellen solcher indizierten Ansichten in 2005 SP 1 entfernen würden), oder sie lösten sie, indem sie einen Merge-Join in ihrer Join-Klausel anwendeten (aber Ich habe keins).
Anfänglich gab es in der Tabelle Deferrals keine berechnete Spalte, und die WHERE-Klausel in der Ansicht prüfte die Spalten CompletedAt und CanceledAt für NULL separat. Aber ich wechselte zu den oben genannten, nur um zu sehen, ob ich anderes Verhalten provozieren könnte.
Alle meine SET-Optionen sind für die Verwendung indizierter Ansichten geeignet, und wenn nicht, würde ich erwarten, dass ein weniger gewaltsamer Fehler ausgelöst wird.
Irgendwelche Ideen?
Wie ich in meinem Kommentar zu Mladen Prajdic angegeben habe - ich kann die oben genannten Skripte in einer frisch erstellten Datenbank ausführen, und immer noch diesen Fehler erhalten. Wenn ein Index so schnell beschädigt werden könnte (Erstellen auf einer leeren Tabelle, 2 Einfügungen), wäre ich ernsthaft besorgt über die Stabilität von SQL Server. Wie bereits erwähnt, habe ich "andere" Online-Ursachen gefunden, die diese Nachricht hervorbringen, und sie sind nicht wirklich eine Indexbeschädigung. –