您可以將很多添加到帳戶(ID-PK,用戶ID-FK,名稱,描述,...)和Entry(ID-PK)表之間的多對多關係: EntryAccount(ENTRYID & ACCOUNTID-PK,EntryAccountType ) 其中EntryAccountType字段可以具有以下值之一{S =發送者,R =接收者,P =主要接收者,N =次要接收者}。
爲EntryAccount表的INSERT語句將是:
--Basic
INSERT EntryAccount (EntryId,AccountId,EntryAccountType)
VALUES (...,...,'S')
INSERT EntryAccount (EntryId,AccountId,EntryAccountType)
VALUES (...,...,'R')
--Parallel
INSERT EntryAccount (EntryId,AccountId,EntryAccountType)
VALUES (...,...,'S')
INSERT EntryAccount (EntryId,AccountId,EntryAccountType)
VALUES (...,...,'R')
INSERT EntryAccount (EntryId,AccountId,EntryAccountType)
VALUES (...,...,'R')
INSERT EntryAccount (EntryId,AccountId,EntryAccountType)
VALUES (...,...,'R')
--Chained
INSERT EntryAccount (EntryId,AccountId,EntryAccountType)
VALUES (...,...,'S')
INSERT EntryAccount (EntryId,AccountId,EntryAccountType)
VALUES (...,...,'P')
INSERT EntryAccount (EntryId,AccountId,EntryAccountType)
VALUES (...,...,'N')
INSERT EntryAccount (EntryId,AccountId,EntryAccountType)
VALUES (...,...,'N')
INSERT EntryAccount (EntryId,AccountId,EntryAccountType)
VALUES (...,...,'N')
然後,爲了執行一些業務規則(一個發送器S,一個主接收機-P和許多[二次]接收機-R/N)您可以在EntryAccount表上創建唯一的過濾索引(SQL Server 2008):IUF_EntryAccount_EntryId_EntryAccountType(鍵> EntryId & EntryAccountType,filter> EntryAccountType IN('S','P'))。此外,此索引適用於查詢優化。 但是,這個指標是不夠的,因爲你可以有「不一致」輸入業務對象這樣的:
Entry(1001)
EntryAccoount(1001,...,'S') without EntryAccoount(1001,...,'R')
or
EntryAccoount(1001,...,'R') without EntryAccoount(1001,...,'S')
, etc.
要解決此問題,您需要一個AFTER觸發器INSERT,UPDATE,DELETE上EntryAccount表:
CREATE TRIGGER ...
AFTER INSERT, UPDATE, DELETE
...
DECLARE @Results TABLE
(
EntryId INT PRIMARY KEY
,SendersCount INT NOT NULL DEFAULT O
,ReceiversCount INT NOT NULL DEFAULT O
,PrimaryReceiversCount INT NOT NULL DEFAULT O
,SecondaryReceiversCount INT NOT NULL DEFAULT O
);
INSERT @Results(EntryId)
SELECT EntryId
FROM inserted
UNION --no duplicates
SELECT EntryId
FROM deleted;
--Count senders
UPDATE @Results
SET SendersCount = q.Num
FROM @Results r
JOIN
(
SELECT ea.EntryId, COUNT(*) Num
FROM EntryAccount ea
JOIN @Results i ON ea.EntryId = i.EntryId
WHERE ea.EntryAccountType = 'S'
GROUP BY ea.EntryId
) q ON r.EntryId = q.EntryId;
-Count [standard-R] receivers
UPDATE @Results
SET ReceiversCount = q.Num
FROM @Results r
JOIN
(
SELECT ea.EntryId, COUNT(*) Num
FROM EntryAccount ea
JOIN @Results i ON ea.EntryId = i.EntryId
WHERE ea.EntryAccountType = 'R'
GROUP BY ea.EntryId
) q ON r.EntryId = q.EntryId;
--Count primary-P receivers
UPDATE @Results
SET PrimaryReceiversCount = q.Num
FROM @Results r
JOIN
(
SELECT ea.EntryId, COUNT(*) Num
FROM EntryAccount ea
JOIN @Results i ON ea.EntryId = i.EntryId
WHERE ea.EntryAccountType = 'P'
GROUP BY ea.EntryId
) q ON r.EntryId = q.EntryId;
--Count secondary-N receivers
UPDATE @Results
SET SecondaryReceiversCount = q.Num
FROM @Results r
JOIN
(
SELECT ea.EntryId, COUNT(*) Num
FROM EntryAccount ea
JOIN @Results i ON ea.EntryId = i.EntryId
WHERE ea.EntryAccountType = 'N'
GROUP BY ea.EntryId
) q ON r.EntryId = q.EntryId;
--Final validation
IF EXISTS
(
SELECT *
FROM @Results r
WHERE NOT(r.SendersCount=1 AND r.ReceiversCount>=1 AND r.PrimaryReceiver=0 AND r.SecondaryReceiversCount=0
OR r.SenderCount=1 AND r.ReceiversCount=0 AND r.PrimaryReceiver=1 AND r.SecondaryReceiversCount >=1
OR r.SenderCount=0 AND r.ReceiversCount=0 AND r.PrimaryReceiver=0 AND r.SecondaryReceiversCount=0
)
)
ROLLBACK;
如果您沒有SQL Server 2008(R1/R2),則無法創建篩選索引,但只能依靠觸發器。
PS:我還沒有測試過這個解決方案。
這條鏈最多可以有多少「鏈接」? – NullUserException
您好nulluserexception,鏈接,一個發送者只能發送到1個主要接收器,然後這個主要接收器可以發送到最多6個次要接收器。輔助接收器不能發送,因此最多2個鏈。 – 001