考慮下面的表格,它的約束有點笨拙,但足以證明我的觀點。請注意,爲了使事情變得非常簡單,約束條件只涉及文字值。列ID
僅存在,因爲表必須至少有一列(!!),但該列未包含在約束中。雖然有點愚蠢(因此名稱),這是完全合法的語法,類似於將WHERE 0 = 1
添加到SELECT
查詢以確保它返回零行。ACE/Jet的IN運算符或CHECK約束是否「損壞」?
(標準SQL DDL代碼,將在ACE/Jet的ANSI-92查詢模式執行)
CREATE TABLE Test1
(
ID INTEGER NOT NULL,
CONSTRAINT daft_1 CHECK (5 = NULL)
);
以下INSERT
成功:
INSERT INTO Test1 (ID) VALUES (1);
這是正常現象。謂詞5 = NULL
應評估爲UNKNOWN
。 INSERT
是'給予懷疑的好處'並且成功。那裏沒問題。
使用IN
運營商考慮這個類似的例子:
CREATE TABLE Test2
(
ID INTEGER NOT NULL,
CONSTRAINT daft_2 CHECK (5 IN (0, 1, NULL))
);
以下INSERT
因爲約束咬傷失敗:
INSERT INTO Test2 (ID) VALUES (1);
這是出乎意料的behviour,通過我至少。我希望5 IN (0, 1, NULL)
再次被評估爲UNKNOWN
和INSERT
成功的原因與第一個例子相同。
我期望在第二示例中的邏輯是相同的如下面的第三示例:
CREATE TABLE Test3
(
ID INTEGER NOT NULL,
CONSTRAINT daft_3 CHECK((5 = 0) OR (5 = 1) OR (5 = NULL))
);
以下INSERT
成功:
INSERT INTO Test3 (ID) VALUES (1);
這是預期行爲。
我已經測試了SQL Server上的所有三個示例,並且所有工作都如我所料,即所有三個INSERT
語句都成功。事實上,檢查信息模式顯示,在第二個例子中的SQL Server作爲「有益」(哎呀)改寫約束的條款與
((5)=NULL OR (5)=(1) OR (5)=(0))
所以更換IN
運營商,爲ACE /噴氣,什麼是「破'這裏:IN
運營商或CHECK
約束?
下面是一些使用NULLable列重現問題的VBA代碼;也證明了下降的約束使得INSERT
成功:
Sub TestJetInCheck()
On Error Resume Next
Kill Environ$("temp") & "\DropMe.mdb"
On Error GoTo 0
Dim cat
Set cat = CreateObject("ADOX.Catalog")
With cat
.Create _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & _
Environ$("temp") & "\DropMe.mdb"
With .ActiveConnection
Dim Sql As String
Sql = _
"CREATE TABLE Test" & vbCr & _
"(" & vbCr & _
" ID INTEGER, " & vbCr & _
" CONSTRAINT daft_constraint " & vbCr & _
" CHECK (5 IN (0, 1, NULL))" & vbCr & _
");"
.Execute Sql
Sql = "INSERT INTO Test (ID) VALUES (1);"
On Error Resume Next
.Execute Sql
If Err.Number <> 0 Then
MsgBox Err.Description
Else
MsgBox "{{no error}}"
End If
On Error GoTo 0
.Execute "ALTER TABLE Test DROP CONSTRAINT daft_constraint;"
On Error Resume Next
.Execute Sql
If Err.Number <> 0 Then
MsgBox Err.Description
Else
MsgBox "{{no error}}"
End If
On Error GoTo 0
End With
Set .ActiveConnection = Nothing
End With
End Sub
編輯:我只是想試試這個:
SELECT NULL(1); - 返回NULL
SELECT 1 IN(NULL) - 返回零即FALSE
爲什麼不嘗試使用DAO而不是DDL? – 2009-06-06 04:21:51