ID
仅存在,因为表必须至少有一列(!!),但该列不包含在约束中。虽然有点愚蠢(因此得名),但这是完全合法的语法,类似于添加
WHERE 0 = 1
到
SELECT
查询以确保返回零行。
(标准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
插入
被“给予怀疑的好处”并成功。没问题。
IN
接线员:
CREATE TABLE Test2
(
ID INTEGER NOT NULL,
CONSTRAINT daft_2 CHECK (5 IN (0, 1, NULL))
);
以下
插入
失败,因为约束咬合:
INSERT INTO Test2 (ID) VALUES (1);
5 IN (0, 1, NULL)
再次被评估为
未知的
和
成功的原因与第一个例子相同。
我希望第二个示例中的逻辑与以下第三个示例相同:
CREATE TABLE Test3
(
ID INTEGER NOT NULL,
CONSTRAINT daft_3 CHECK((5 = 0) OR (5 = 1) OR (5 = NULL))
);
以下
插入
成功:
INSERT INTO Test3 (ID) VALUES (1);
我已经在SQL Server上测试了所有这三个示例,并按照我的预期进行了测试,即所有这三个示例
声明成功了。事实上,检查信息模式可以发现,对于第二个示例,SQL Server as“helpfully”(grrr)重写了约束的子句以替换
在里面
接线员
((5)=NULL OR (5)=(1) OR (5)=(0))
那么,对于ACE/Jet来说,这里的“坏”是什么呢
在里面
接线员或
CHECK
限制
下面是一些VBA代码,使用可为空的列来重现问题;还演示了删除约束允许
插入
要成功:
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
编辑:我只是想试试这个:
在(1)中选择空;
在中选择1(空)
--返回零,即FALSE