由於這裏唯一相關的選項是「行不存在」和「行已存在」,因此不需要COUNT。 IF EXISTS效率更高,因爲它會在查找一行時停止執行,而不是掃描整個表(或索引)而僅查找不到更多條目,因爲無論如何只有1條可能存在。
因此:
IF (EXISTS(
SELECT *
FROM Events
WHERE [eventstart] = @EventStart
AND [StartDate] = @StartDate
AND [Room] = @Room
))
BEGIN
RAISERROR('Row already exits!', 16, 1);
RETURN;
END;
ELSE
BEGIN
INSERT INTO Events
([Text], [eventStart], [EventEnd], [Repeat], [Days], [Room], [StartDate])
VALUES (@Text, @EventStart, @EventEnd, @Repeat, @Days, @Room, @StartDate);
END;
上面可以在存儲過程中或經由SqlCommand
C#中的參數化查詢(或一些其它語言)來完成。
OR
取決於你如何想陷阱的條件,它是可能通過一個唯一約束處理這個,然後它會檢查在被插入,而不需要額外的代碼(即IF EXISTS SELECT構造)。這樣做的好處是:a)代碼少,b)規則始終執行,而不僅僅是在這一個實例中。缺點是a)「規則」有些隱藏,可能會被人遺忘,直到有人愚蠢地寫出不尊重規則的代碼,並且b)它放棄了INSERT的事務,如果可能,我會盡量避免。最後,如果這是系統的嚴格規則,那麼最好通過UNIQUE CONSTRAINT來執行,這確保了沒有人能夠繞過規則。
CREATE UNIQUE NONCLUSTERED INDEX [UIX_Events_fields]
ON dbo.[Events] ([EventStart] ASC, [Room] ASC, [StartDate] ASC);
更好YET
一舉兩得。 UNIQUE INDEX
(現在不是約束,這是原因)不僅會強制執行規則,還會幫助加快查詢的速度。這將允許您輕鬆管理「錯誤」狀態和消息(而不是陷入SqlException
並檢查ErrorCode)。
爲什麼不首先做一個'SELECT'?也許有一個'COUNT',所以你不會不必要地帶回一堆記錄。 – 2014-10-28 16:44:17
在插入前如何使用'If Exists(...)'? – 2014-10-28 16:53:54