Tro*_*ggy 6 ms-access triggers stored-procedures ms-office
好的,有没有人有关于触发器或存储过程的Access 2007功能的一些很好的资源?甚至可以做它们或类似的东西吗?我在Microsoft的帮助中找到的每个资源都引用了Access 2003以及许多在线帮助手册.一切都在2007年左右移动,因此翻译较旧的帮助手册有点困难.我真的很想使用ms sql,但是被迫在访问中执行这个小项目,所以任何资源都会有所帮助.
很酷,到目前为止所有的答案都很有帮助.只是想确认一下我所拥有的许多分散的访问知识.我想我可以让它适用于这个项目.哦,我不能使用sql,因为很多...繁文缛节.
one*_*hen 16
在ANSI-92查询模式下,Access数据库引擎支持CREATE PROCEDURE(SQL DDL)语法,例如
CREATE PROCEDURE GetCompanies
(
:company_type VARCHAR(30) = NULL
)
AS
SELECT company_registered_number, organisation_name, company_type
FROM Companies
WHERE company_type = IIF(:company_type IS NULL, company_type, :company_type);
Run Code Online (Sandbox Code Playgroud)
因此,生成的对象是a PROCEDURE,并与表一起存储在数据库文件中.这里强调的是"存储"这个词(而不是"过程"),即它"接近数据".使用这些物体可以促进前端(FE)与后端(BE)的良好分离,我的意思是逻辑而非物理; 例如,存储在VBA代码或Access Forms控件属性中的SQL代码不是"接近数据"并将后端"层"与前端"层"混合在一起,使得SQL代码的维护更加困难例如,如果您需要重命名表中的列,则只需查看PROCEDUREs和VIEWs即可完成作业.
使用a的另一个优点PROCEDURE是(或者说更确切地说),当与用户级安全性(ULS)结合使用时,它可以帮助"可用性".为了使用示例,经常会询问如何将created_date列添加到表中并保持其值.添加一个DEFAULT当前时间戳会让你只有这样的方式
CREATE TABLE Entities (
entity_ID CHAR(8) WITH COMPRESSION NOT NULL UNIQUE,
CONSTRAINT entity_ID__pattern
CHECK (entity_ID NOT ALIKE '%[!0-9]%'),
entity_name VARCHAR(20) NOT NULL,
CONSTRAINT entity_name__whitespace
CHECK (
entity_name NOT ALIKE ' %'
AND entity_name NOT ALIKE '% '
AND entity_name NOT ALIKE '% %'
AND LEN(entity_name) > 0
),
created_date DATETIME DEFAULT NOW() NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
但这并不会阻止显式值不是当前时间戳.我们当然可以添加CHECK约束或验证规则来强制执行此操作:
ALTER TABLE Entities ADD
CONSTRAINT entity_created_date__must_be_current_timestamp
CHECK (created_date = NOW());
Run Code Online (Sandbox Code Playgroud)
这里的问题是CHECK在行级别检查约束和验证规则,即如果您曾尝试更改另一列,则约束会咬人.不好,所以:
ALTER TABLE Entities DROP
CONSTRAINT entity_created_date__must_be_current_timestamp;
Run Code Online (Sandbox Code Playgroud)
该怎么办?一种方法是从表中删除权限,以便最终用户(以及此上下文中的应用程序也是用户)不能INSERT或UPDATE直接使用表的数据,然后创建PROCEDUREs以允许更改数据,而是授予适当的权限.PROCEDURE例如
CREATE PROCEDURE AddEntity (
:entity_ID CHAR(8),
:entity_name VARCHAR(20)
)
AS
INSERT INTO Entities (entity_ID, entity_name, created_date)
VALUES (:entity_ID, :entity_name, NOW());
EXECUTE EXECUTE AddEntity '00000001', 'Black';
Run Code Online (Sandbox Code Playgroud)
我正在使用过去时,因为您可能知道,Access团队(或者是SharePoint团队?:))从新的for Access2007 ACE引擎中删除了ULS.我不确定我是否可以推荐使用已弃用的功能.
现在是坏消息.许多(大多数?)人都认为这样的PROCEDURE程序不是一个程序而且他们有一个好点,因为Access数据库引擎的SQL语法不支持流控制,变量声明,甚至执行不止一个的能力SQL语句.换句话说,a PROCEDURE不能包含程序代码.考虑一个引用实体的表:
CREATE TABLE FlyingEntities (
entity_ID CHAR(8) WITH COMPRESSION NOT NULL UNIQUE
REFERENCES Entities (entity_ID)
ON DELETE CASCADE
ON UPDATE CASCADE
);
Run Code Online (Sandbox Code Playgroud)
如果有一个PROCEDURE可以在实体中创建一行并且可选地在FlyingEntities中基于参数值创建一行,那将是很好的,但这在单个SQL语句中是不可能的.因此,Access数据库引擎PROCEDURE的价值有限,尤其是现在ULS已经消失.
没有解决Access数据库引擎没有,也从未有过触发器的事实.但问题是,你需要它们吗?
虽然我仍然喜欢Access数据库引擎的简单性,但事实是多年前我将所有"严肃"的工作转移到更多"工业强度"和更多符合SQL标准的产品,主要是SQL Server.但是,在SQL Server中,我只使用触发器来做两件事,这两件事都可以在Access数据库引擎中没有触发器(在某种程度上)完成.
第一个用法是应对SQL Server CHECK约束不支持子查询的事实; 换句话说,它们可以是列级和行级但不是表级.CHECK在Jet 4.0中引入并仍然存在于ACE(2007)中的访问数据库引擎约束始终是表级的......好吧,它们在理论上.存在一个问题(可疑错误),在行级别检查它们应在SQL语句级别进行逻辑检查.它们不支持SQL-92 DEFERRABLE语法,因此没有解决此问题的方法(顺便提一下,SQL Server在使用a FUNCTION来解决无子查询限制时遇到同样的问题).并非所有CHECK约束都会遇到这个问题,但它的存在让我有点担心.
SQL Server中触发器的第二次也是最后一次使用是由于另一个限制:当尝试为REFERENCE同一个密钥创建两个s 时,可怕的"FOREIGN KEY ...可能导致周期或多个级联路径",例如这在Access中是允许的数据库引擎:
CREATE TABLE Marriages (
entity_ID_1 CHAR(8) WITH COMPRESSION NOT NULL UNIQUE
REFERENCES Entities (entity_ID)
ON DELETE CASCADE
ON UPDATE CASCADE,
entity_ID_2 CHAR(8) WITH COMPRESSION NOT NULL UNIQUE
REFERENCES Entities (entity_ID)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT cannot_marry_yourself
CHECK (entity_ID_1 <> entity_ID_2)
);
Run Code Online (Sandbox Code Playgroud)
但是将其移植到SQL Server(删除WITH COMPRESSION等)并且不允许.在这种情况下,cannot_marry_yourself将阻止循环但SQL Server执行简单计数并确定1 + 1 =太多.我认为原油但有效.使用触发器是令人满意的解决方法; 在CASCADE参照行为符合触发特定的疼痛.
另一方面,在这方面,Access数据库引擎在某种程度上甚至比SQL Server更笨,因为它根本不会尝试检测周期.如果您确实创建了一个循环,则不会收到警告,结果将是最后一次覆盖数据的竞赛以及难以调试的情况.
除了这些用法之外,我避免使用触发器,因为它们是一种维护问题(如果你能在一开始就把它们弄好).我已经失去了同事们向我寻求帮助的次数,我们两个人都对这个问题感到困惑,只是因为他们羞怯地告诉我后来他们忘记了他们创造了一个触发器.
所以,是的,Access数据库引擎缺少触发器,但你可能会发现没有它们可能会更好.
哦,不要让我开始使用Access数据库引擎的文档.它是碎片化的,许多碎片随着时间的推移已经消失,许多碎片一开始就不存在,例如我提到了上述CHECK限制但是从未发布过任何细节,只有几个有缺陷的例子(我所知道的有关CHECK约束的一切)通过反复试验来学习 - 我还没有偶然发现什么?!)存在的碎片包含材料错误和遗漏错误......甚至错误地详述了从未存在过的功能!例如来自Access2007帮助的CREATE TABLE语句提到临时表,命名NOT NULL约束和多列NOT NULL约束,所有这些都不存在,但没有提到DEFAULT或者某些CONSTRAINTs未使用索引实现.但最严重的遗漏IMO是Access数据库引擎表达式的引用,例如IIF()与IIf()VBA中的行为不同,但这似乎是未记录的.Jet 3的SQL帮助有这样一个列表,没有版本,一年或两年前Jet 3帮助从MSDN中消失了.缺乏良好的文档确实损害了Access数据库引擎的可信度.