Alternative zur Überprüfung von Einschränkungen in viewen

Also habe ich zwei tische:

Requests -------- Id RequestSchemeId ReceivedByUserId ForwardedRequests ----------------- Id RequestId (FK to Id column of Requests Table) ForwardedToUserId 

und eine view

 ForwardedRequestsInRequestSchemes --------------------------------- Requests.RequestSchemeId Requests.ReceivedByUserId ForwardedRequests.ForwardedToUserId 

Was ist der Standard / empfohlene Methode, eine Einschränkung hinzuzufügen, die äquivalent zu Requests.ReceivedByUserId != ForwardedRequests.ForwardedToUserId in der view ist?

Ich weiß, Check-Einschränkungen sind nicht erlaubt in viewen. Verwenden von SQL server 2008.

BEARBEITEN:

Dies ist eine Folgefrage zu dieser Frage .

Geschäftsregeln:

  1. Die gleiche Anfrage kann an mehrere Benutzer weitergeleitet werden. Daher die ID-Spalte in der Tabelle ForwardedRequests.

  2. Ein Benutzer kann nur eine Anfrage für einen bestimmten RequestScheme erhalten. So habe ich eine UniqueKey-Einschränkung für RequestSchemeId + ReceivedByUserId in der Requests-Tabelle erstellt.

  3. Die Anforderung kann an einen anderen Benutzer weitergeleitet werden, wenn der weitergeleitete Benutzer nicht bereits eine weitergeleitete Anfrage unter demselben Schema von einem anderen Benutzer hat. So wie Martin in der verknüpften Frage vorgeschlagen hat , habe ich eine view aus den beiden Tabellen erstellt und eine eindeutige Einschränkung auf Requests.RequestSchemeId + ForwardedRequests.ForwardedToUserId hinzugefügt.

  4. Die Geschäftsregel, die diese Frage betrifft, ist, dass der Empfänger der Anfrage es nicht an sich selbst weiterleiten kann.

Ich kann an ein paar Möglichkeiten denken, SQL server zu erzwingen, um dies für Sie zu erzwingen. Beide hübsch aber so interessiert, andere Ansätze zu sehen.

1) Sie können der indizierten view hinzufügen ForwardedRequestsInRequestSchemes eine zusätzliche Spalte 1/(ForwardedToUserId - ReceivedByUserId) AS FailIfSame die eine Divide by zero error erhöhen würde, wenn die beiden Werte gleich sind. Dies bedeutet, dass Sie am Ende speichern eine redundante Spalte in der indizierten view though.

2) Du könntest eine neue view erstellen, die solche Zeilen zurückgibt, die auf eine zweireihige Tabelle verknüpft sind, dann definieren sie eine eindeutige Einschränkung für diese view. Diese view ist immer leer.

 CREATE TABLE dbo.TwoRows(C INT) INSERT INTO dbo.TwoRows VALUES(1),(1) GO CREATE VIEW dbo.FailIfForwardedUserEqualToReceivedByUser WITH SCHEMABINDING AS SELECT 1 AS C FROM dbo.ForwardedRequests FR INNER JOIN dbo.Requests R ON R.Id = FR.RequestId AND R.ReceivedByUserId = FR.ForwardedToUserId CROSS JOIN dbo.TwoRows GO CREATE UNIQUE CLUSTERED INDEX ix ON dbo.FailIfForwardedUserEqualToReceivedByUser(C) 

Eine Möglichkeit besteht darin, das update, insert, delete zuzulassen update, insert, delete Rechte auf den Tabellen zu update, insert, delete und die Geschäftsanforderung mit einer gespeicherten Prozedur zu erzwingen. Beispielsweise,

 create procedure dbo.AddRequestForward( @requestId int , @forwardedToUserId int) as insert ForwardedRequests (ForwardedRequests, ForwardedRequests) select @requestId , @forwardedToUserId where not exists ( select * from Requests where Id = @requestId and @forwardedToUserId = @forwardedToUserId ) if @@rowcount = 0 return -1 -- Forwarded and Received identical user return 1 -- Success go