Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ms access 是ACE/Jet';运算符中的s或检查约束';破碎的';?_Ms Access_Jet - Fatal编程技术网

Ms access 是ACE/Jet';运算符中的s或检查约束';破碎的';?

Ms access 是ACE/Jet';运算符中的s或检查约束';破碎的';?,ms-access,jet,Ms Access,Jet,考虑下表中的约束,它有点愚蠢,但足够简单,可以证明我的观点。注意,为了使事情非常简单,约束的条件只涉及文字值。列ID之所以存在,是因为表必须至少有一列(!!),但该列不包含在约束中。虽然有点愚蠢(因此得名),但这是完全合法的语法,类似于将WHERE 0=1添加到SELECT查询以确保其返回零行 (标准SQL DDL代码,将在ACE/Jet的ANSI-92查询模式下执行) 以下插入操作成功: INSERT INTO Test1 (ID) VALUES (1); INSERT INTO Test3

考虑下表中的约束,它有点愚蠢,但足够简单,可以证明我的观点。注意,为了使事情非常简单,约束的条件只涉及文字值。列
ID
之所以存在,是因为表必须至少有一列(!!),但该列不包含在约束中。虽然有点愚蠢(因此得名),但这是完全合法的语法,类似于将
WHERE 0=1
添加到
SELECT
查询以确保其返回零行

(标准SQL DDL代码,将在ACE/Jet的ANSI-92查询模式下执行)

以下插入操作成功:

INSERT INTO Test1 (ID) VALUES (1);
INSERT INTO Test3 (ID) VALUES (1);
这是预期的行为。谓词
5=NULL
的计算结果应为
UNKNOWN
插入
是“给予怀疑的好处”并成功。没问题

使用中的
操作符考虑类似的示例:

CREATE TABLE Test2 
(
   ID INTEGER NOT NULL, 
   CONSTRAINT daft_2 CHECK (5 IN (0, 1, NULL))
);
由于约束咬合,以下插入操作失败:

INSERT INTO Test2 (ID) VALUES (1);
至少在我看来,这是出乎意料的。我希望(0,1,NULL)
中的
5再次被评估为
UNKNOWN
,并且
INSERT
成功,原因与第一个示例相同

我希望第二个示例中的逻辑与以下第三个示例相同:

CREATE TABLE Test3
(
   ID INTEGER NOT NULL, 
   CONSTRAINT daft_3 CHECK((5 = 0) OR (5 = 1) OR (5 = NULL))
);
以下插入操作成功:

INSERT INTO Test1 (ID) VALUES (1);
INSERT INTO Test3 (ID) VALUES (1);
这是预期的行为

我已经在SQL Server上测试了所有三个示例,所有的工作都如我所期望的那样,即所有三个
INSERT
语句都成功了。事实上,检查信息模式可以发现,对于第二个示例,SQL Server as“helpfully”(grrr)重写了约束的子句,将
中的
操作符替换为

((5)=NULL OR (5)=(1) OR (5)=(0))
那么,对于ACE/Jet,这里的“坏”是什么:操作符中的
还是
检查约束

下面是一些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
子测试jetincheck()
出错时继续下一步
Kill environo$(“temp”)和“\DropMe.mdb”
错误转到0
昏猫
设置cat=CreateObject(“ADOX.Catalog”)
和猫
.创造_
“Provider=Microsoft.Jet.OLEDB.4.0;”_
“数据源=”&_
环境$(“临时”)和“\DropMe.mdb”
使用.ActiveConnection
将Sql设置为字符串
Sql=_
“创建表测试”&vbCr&_
(“&vbCr&_
“ID整数”&vbCr&_
“约束愚蠢的约束”&vbCr&_
“检查(5英寸(0,1,空))”&vbCr&_
");"
.执行Sql
Sql=“插入测试(ID)值(1);”
出错时继续下一步
.执行Sql
如果错误号为0,则
MsgBox错误说明
其他的
MsgBox“{{无错误}}”
如果结束
错误转到0
.执行“更改表测试跌落约束daft_约束”
出错时继续下一步
.执行Sql
如果错误号为0,则
MsgBox错误说明
其他的
MsgBox“{{无错误}}”
如果结束
错误转到0
以
Set.ActiveConnection=Nothing
以
端接头
编辑:我只是想试试这个:

在(1)中选择空; --返回空值

在中选择1(空)
--返回零,即FALSE

我可以通过创建验证规则来消除
检查
约束(@David W.Fenton:对不起,我发现SQL DDL和ADO比DAO更容易编写,但感谢您的启发):

子测试jetinvalidationrule()
出错时继续下一步
Kill environo$(“temp”)和“\DropMe.mdb”
错误转到0
昏猫
设置cat=CreateObject(“ADOX.Catalog”)
和猫
.创造_
“Provider=Microsoft.Jet.OLEDB.4.0;”_
“数据源=”&_
环境$(“临时”)和“\DropMe.mdb”
使用.ActiveConnection
将Sql设置为字符串
Sql=_
“创建表测试”&vbCr&_
(“&vbCr&_
“ID整数”&vbCr&_
");"
.执行Sql
以
'创建验证规则
丁正
Set jeng=CreateObject(“JRO.JetEngine”)
jeng.RefreshCache.ActiveConnection
.表格(“测试”).列(“ID”)_
.Properties(“Jet OLEDB:列验证规则”)。值=_
5英寸(0,1,空)
jeng.RefreshCache.ActiveConnection
使用.ActiveConnection
Sql=“插入测试(ID)值(1);”
出错时继续下一步
.执行Sql
如果错误号为0,则
MsgBox错误说明
其他的
MsgBox“{{无错误}}”
如果结束
错误转到0
以
Set.ActiveConnection=Nothing
以
端接头

验证规则被咬住并插入失败。因此,我怀疑IN子句的行为出人意料。将来我将使用嵌套或子句

我可以通过创建一个验证规则来消除
检查
约束(@David W.Fenton:对不起,我发现SQL DDL和ADO比DAO更容易编写,但感谢您的启发):

子测试jetinvalidationrule()
出错时继续下一步
Kill environo$(“temp”)和“\DropMe.mdb”
错误转到0
昏猫
设置cat=CreateObject(“ADOX.Catalog”)
和猫
.创造_
“Provider=Microsoft.Jet.OLEDB.4.0;”_
“数据源=”&_
环境$(“临时”)和“\DropMe.mdb”
使用.ActiveConnection
将Sql设置为字符串
Sql=_
“创建表测试”&vbCr&_
(“&vbCr&_
“ID整数”&vbCr&_
");"
.执行Sql
以
'创建验证规则
丁正
Set jeng=CreateObject(“JRO.JetEngine”)
jeng.RefreshCache.ActiveConnection
.表格(“测试”).列(“ID”)_
.Properties(“Jet OLEDB:列验证规则”)。值=_
5英寸(0,1,空)
jeng.RefreshCache.ActiveConnection
使用.ActiveConnection
Sql=“插入到T中”