在访问和/或 DAO 中创建检查约束

Posted

技术标签:

【中文标题】在访问和/或 DAO 中创建检查约束【英文标题】:Create a check constraint in access and/or DAO 【发布时间】:2010-12-12 05:50:19 【问题描述】:

我正在尝试在访问(jet?)表上创建检查约束。

所以,我打开具有访问权限的 .mdb 文件,进入查询->在设计视图中创建查询, 输入 esc,然后 menu->view->query,最后输入

创建表 X ( 一个号码, 检查 (a > 20) )

但 access 认为我有“字段定义中的语法错误”。然而,我不这么认为。因此我的问题是:是否可以创建具有访问权限的检查约束。如果是这样:如何。

另外,我想用 dao/vba 创建约束,而不是在 GUI 上。这可能吗?

最后,稍微相关一点:如何将 sql 语句输入到 access 中。我无法想象我必须使用查询->设计视图->查询->查看路线才能做到这一点。我已经习惯了 Oracle 的 SQL*Plus,我非常喜欢它,我希望访问也有类似的东西。

感谢您的任何意见 雷内

【问题讨论】:

【参考方案1】:

这里有一些注释。

您可以为 Oracle 创建 Pass-Through 查询(选择菜单“Query”>“SQL Specific”>“Pass-Through”)

自 Access 2003 起,您可以选择 SQL Server Compatible Syntax (ANSI 92) (http://office.microsoft.com/en-us/access/HA010345621033.aspx)

使用 VBA / DAO 的验证规则

''Reference: Microsoft DAO x.x Object Library

Dim tdf As TableDef
Dim db As Database

Set db = CurrentDb

Set tdf = db.TableDefs("Table1")

tdf.Fields("aDouble").ValidationRule = "<10"
tdf.Fields("aDouble").ValidationText = "Must be less than 10"

ADO / VBA 的约束。请参阅[用于 Access 2000 的中级 Microsoft Jet SQL](http://msdn.microsoft.com/en-us/library/aa140015(office.10).aspx)

''Reference: Microsoft ADO Ext. x.x for DDL and Security

Dim cn As ADODB.Connection 'For action queries
Dim rs As ADODB.Recordset  'For select queries
Dim s As String
Dim RecordsAffected As Long

Set cn = CurrentProject.Connection

''You can store sql in a table
s = DLookup("SQLText", "sysSQL", "ObjectName='q1'")
''Result: CREATE TABLE tblCreditLimit (LIMIT DOUBLE)
cn.Execute s, RecordsAffected
Debug.Print RecordsAffected

''You can run queries from VBA
s = "INSERT INTO tblCreditLimit VALUES (100)"
cn.Execute s, RecordsAffected
Debug.Print RecordsAffected

s = "CREATE TABLE tblCustomers (CustomerID COUNTER, CustomerName Text(50))"
cn.Execute s, RecordsAffected
Debug.Print RecordsAffected

s = "INSERT INTO tblCustomers VALUES (1, 'ABC Co')"
cn.Execute s, RecordsAffected
Debug.Print RecordsAffected

s = "ALTER TABLE tblCustomers " _
   & "ADD COLUMN CustomerLimit DOUBLE"
cn.Execute s, RecordsAffected
Debug.Print RecordsAffected

''You can add contraints using ADO like so:
s = "ALTER TABLE tblCustomers " _
   & "ADD CONSTRAINT LimitRule " _
   & "CHECK (CustomerLimit <= (SELECT LIMIT " _
   & "FROM tblCreditLimit))"
cn.Execute s, RecordsAffected
Debug.Print RecordsAffected

s = "UPDATE tblCustomers " _
   & "SET CustomerLimit = 200 " _
   & "WHERE CustomerID = 1"
''Error occurs here
cn.Execute s, RecordsAffected

s = "UPDATE tblCustomers " _
   & "SET CustomerLimit = 90 " _
   & "WHERE CustomerID = 1"
cn.Execute s, RecordsAffected
Debug.Print RecordsAffected

''Clean up
''You cannot do this through the database window,
''because of the constraint.
s = "ALTER TABLE tblCustomers DROP CONSTRAINT LimitRule "
cn.Execute s, RecordsAffected
Debug.Print RecordsAffected

s = "DROP TABLE tblCustomers "
cn.Execute s, RecordsAffected
Debug.Print RecordsAffected

s = "DROP TABLE tblCreditLimit "
cn.Execute s, RecordsAffected
Debug.Print RecordsAffected

【讨论】:

您需要对表 'tblCreditLimit' 使用 CHECK 约束以确保不会超过一行,否则在测试 CHECK 约束 'LimitRule' 时会出错。 ...并且由于 CHECK 约束的语义,最好避免在同一个 CHECK 约束中引用多个表。您使用的规则更适合 Access 数据库引擎不支持的 ASSERTION ;)【参考方案2】:

列上有验证规则。 您可以使用 VB 进行访问。这里没有 SQL*Plus... 您始终可以将 SQL Express 用作数据源 - 具有真正 sql 服务器的所有优点,并且仅将访问用作前端。

【讨论】:

ms-access->表格->设计视图->验证规则。设置为 >20。不要认为你可以通过数据定义语言来做到这一点,例如创建表 @heferav:是的,可以使用 SQL DDL 完成。您需要处于 ANSI-92 查询模式,使用 Access UI 或 OLE DB 代码(例如 VBA 中的 ADO 经典)。 接受@onedaywhen 在 ADO 方面的卓越知识(我倾向于避免像驳船杆一样)。【参考方案3】:

要在 Access 中执行此操作,您需要先将界面打开到ANSI-92 Query Mode。我已经测试了您的 SQL DDL 代码:它工作正常并创建了一个类型为 FLOAT(双)的列。

使用 DAO 无法做到这一点,但您可以使用 ADO。长话短说:CHECK 约束在 Jet 4.0 时代被引入引擎,当时 Access 团队偏爱 ADO。从 Access2007 开始,Access 团队重新支持 DAO,但尚未填补 DAO 中的 Jet 4.0“漏洞”。因此,对于大多数仅限 Jet 4.0 的功能(可压缩数据类型、固定长度文本数据类型、快速外键等),您需要使用 ADO。

【讨论】:

实际上,我想知道“在 Jet 4 中引入了检查约束”这句话——表级和字段级验证规则一直存在于 Access 中(至少从喷气机 2)。现在,是否有用于创建/更改它们的 DDL 是一个不同的问题,可能随着 Jet 4 的发布而发生的所有事情都是添加了与其他数据库一致的 DDL 支持。您当然可以使用 DAO 对象模型在 DAO 中创建它们(不执行 DDL 语句)。 @David W. Fenton:“Jet 4 的发布可能只是增加了对 DDL 的支持”——并非如此。 “表验证规则”这个名称具有误导性; “行验证规则”会更好,因为它仅适用于当前行。然而,一个 CHECK 约束可以引用同一个表中其他行甚至其他表中的值... 考虑经常使用的“时态数据库”模式,即行上的 start_date 和 end_date DATETIME 列对来模拟一个时期。 Alethic 业务规则要求您确保 end_date 不会出现在 start_date 之前,这确实可以使用表验证规则进行归档。但是,对于您的“排序”键,您需要确保相同非排序键的周期不重叠,如果不使用 CHECK 约束就无法实现……通过引用“日历”辅助表最容易实现。跨度> 关于检查与验证规则的另一点:您只能为每个列/表定义一个验证规则,因此您必须将所有规则组合成一个超级规则。 CHECK 约束没有限制,可为您提供更大的规则粒度,这意味着您可以就如何修复数据向用户提供更好的反馈,即测试咬人的约束名称:start_date__before_1990、start_date__after_2030、start_date__time_must_be_midnight 等。【参考方案4】:

您不能在查询生成器中使用标准 ANSI,除非您将数据库设置为与 sql ansi 兼容。如果您确实更改了此设置,那么您可以像以前一样使用查询生成器中的 sql。但是,我不建议为现有数据库更改此设置。

如果你这样做,你可以输入:

CREATE TABLE z1 
       (id int IDENTITY , FirstName CHAR, LastName CHAR, SSN INTEGER ,
check (id < 20),  
constraint Mypk primary key (id) )

在查询生成器中不需要保存sql,只需要输入sql,然后直接敲ctrl-g即可访问命令行提示符,然后输入:

currentproject.Connection.Execute "CREATE TABLE
    z1(id int IDENTITY , FirstName CHAR, LastName CHAR, SSN INTEGER ,
    check (id < 20),
    constraint Mypk primary key (id) )"

以上内容将在一行上输入。因此,您可以根据需要使用命令行提示符..

【讨论】:

以上是关于在访问和/或 DAO 中创建检查约束的主要内容,如果未能解决你的问题,请参考以下文章

在 PHP 中创建 DAO 的正确方法

在目录中创建文件之前检查目录中的写访问权限

如何在 mariaDB 中创建检查约束以检查 char 类型的多个值?

如何在 Firebase 中创建基于角色的访问控制或自定义声明

如何在 yii 中创建访问(查看页面)角色?

如何在maria DB中创建检查约束以检查char类型的多个值?