2016-11-25 176 views
0

我新的SQL,我有點掙扎 -瞭解違反約束SQL

考慮下一個代碼片段:

CREATE TABLE Trip 
(
    tnum INTEGER PRIMARY KEY, 
    location TEXT NOT NULL, 
    duration INTEGER DEFAULT(5), 
    difficulty INTEGER CHECK(difficulty > 0 AND difficulty < 7), 
    CHECK (difficulty <= 6 AND difficulty >= 3) 
); 

CREATE TABLE Company 
(
    cid INTEGER PRIMARY KEY, 
    diffiname TEXT NOT NULL, 
    estYear Integer NOT NULL 
); 

CREATE TABLE Offer 
(
    cid INTEGER, 
    tnum INTEGER, 
    FOREIGN KEY(cid) REFERENCES Company(cid), 
    FOREIGN KEY(tnum) REFERENCES Trip(tnum) 
); 

我遇到2個約束違規,第一個是,我能夠與difficulty 0,或旅行用difficulty 7添加Tripsduration 2(期望約束 - 持續時間的旅程超過6具有至少3個難度) -

enter image description here

而第二次違規行爲是我能夠添加Offer s,其中包含tnumcid甚至不存在。

+1

「(難度<= 6或持續時間> = 3)」 - 您能否想到一個數字無法通過此測試? –

+1

@DavidAldridge是你可能想要的'(持續時間<= 6 AND難度> = 3)' –

+0

你們是對的,但仍然如你所說修正後,約束仍然違反 –

回答

1

如果我們修改你的約束爲邏輯上等同,

difficulty INTEGER not NULL 
    CHECK(difficulty between 1 and 6), 
    CHECK(difficulty between 3 and 6) 

很清楚,第二個約束控制,因爲任何3 & 6之間也是1 & 之間6.

我'能夠添加難度的旅行0

這是不可能的波夫。不過,使用andor,很容易混淆並描述一個約束,而不是你想要的。

關於外鍵約束,SQL現在看起來是正確的,但是@Gordon Linoff的回答表明您的文章的原始版本包含的錯誤不會正確約束Offer

1

我覺得你的外鍵引用trip是錯上offer

CREATE TABLE Offer 
(
    cid INTEGER, 
    tnum INTEGER, 
    FOREIGN KEY(cid) REFERENCES Company(cid), 
    FOREIGN KEY(tnum) REFERENCES Trip(cid) 
--------------------------------------^ tnum 
); 

對於檢查約束,我不明白這樣做的意圖:

CHECK (difficulty <= 6 OR duration >= 3) 

你打算AND?你打算用AND difficulty >= 3而不是duration