2016-11-09 66 views
2

我有以下問題:我有一個酒店的數據庫,我必須在預訂房間時處理碰撞。函數在查詢中工作,但不在約束中

所以我們假設Quest1想在2016-11-10和2016-11-15之間預訂房間2,但是這個房間在2016-11-07和2016-11-14之間已經被Quest3預訂了(您可以預訂房間離開人們的那一天),我的功能應該被稱爲約束,以告訴他不能爲這些日期預訂它。

我有一個EMPTY表預訂。問題是,在查詢中使用該函數時,它返回的是room2在2016-11-10和2016-11-15之間預訂了0次(因爲該表爲空,即使它不爲空,它也會返回),但是在使用它作爲約束時,它會在行未更新時出現,插入語句與我的約束衝突。

功能:

ALTER FUNCTION [dbo].[Booked] 
(
    @room int, 
    @from date, 
    @to date 
) 
RETURNS int 
AS 
BEGIN 

return(
    SELECT count(*) 
    FROM BOOKINGS 
    WHERE room = @room AND NOT (@from >= to OR @to < from) 
) 

END 

約束:

ALTER TABLE BOOKINGS ADD 
CONSTRAINT chk_isBooked 
CHECK ([dbo].Booked([room], [from],[to])=(0)) 

提前感謝!

+0

您能指定完整的約束定義嗎? –

+0

是的!對不起,我完全忘了添加那個。 ALTER TABLE BOOKINGS 添加約束chk_isBooked CHECK([dbo]。[Booked]([room], [(from],[to])=(0)) – meph

+0

我真的不這麼認爲,知道如何創建一個函數和一個支票,我的問題是,即使我創建了一個返回正確值的工作函數,這個約束似乎是偏離軌跡的。 對不起,如果我沒有足夠具體的話 – meph

回答

1

以下腳本不起作用。看起來當CHECK約束被觸發時,該行已經在表中並且正在該函數中計數。爲了避免這種情況,我在預訂表中添加了一個縮進。

CREATE TABLE dbo.bookings(
    id int identity(1,1), 
    room int , 
    [from] date, 
    [to] date 
); 
GO 

CREATE FUNCTION dbo.IsBooked(@id int,@room int, @from date, @to date) 
RETURNS BIT 
AS 
BEGIN 
    RETURN CASE WHEN EXISTS(SELECT * FROM bookings WHERE id<>@id AND [email protected] AND NOT(@from>=[to] OR @to<[from])) THEN 1 ELSE 0 END 
END 
GO 

ALTER TABLE dbo.bookings ADD CONSTRAINT chk_isbooked CHECK (dbo.IsBooked(id,room,[from],[to])=0); 
GO 

INSERT INTO dbo.bookings(room,[from],[to])VALUES(1,'20160101','20160107'); -- success 
INSERT INTO dbo.bookings(room,[from],[to])VALUES(1,'20160101','20160107'); -- fail 
+0

現在我覺得我很遲鈍。謝謝你的解釋,我的問題已經解決了。感謝@GordonLidoff,爲了讓我走上一條道路,我在searchi上學到了很多東西通過使用關鍵字'udf'和'constraint'的Stackoverflow。再次感謝你們! – meph

相關問題