小喵今天原本想写一篇关于递归触发器的问题,结果一不小心遇见了另一个 问题 ┭┮﹏┭┮
因此,只能先解决眼前的问题 :
案例 如下:
小喵原本想写的 一个触发器功能是 :用来记录最近一次更新时间.当一条book记录被修改时,将最近一次修改时间赋值给这个自定义字段(newUpdateDateTime__c )
trigger BookTrigger on Book__c(after update) {
Map<Id, Book__c> newMap = (Map<Id, Book__c>) Trigger.newMap;
Map<Id, Book__c> oldMap = (Map<Id, Book__c>) Trigger.oldMap;
List<Book__c> newList = (List<Book__c>) Trigger.new;
List<Book__c> oldList = (List<Book__c>) Trigger.old;
//后置
if(Trigger.isAfter){
//更新
if(Trigger.isUpdate){
List<Book__c> bookList = new List<Book__c>();
for(Book__c book : newList){
//如果上次修改时间不等于现在时间,则把最新时间赋值
if(book.newUpdateDateTime__c != DateTime.now()){
book.newUpdateDateTime__c = DateTime.now();
booklist.add(book);
}
}
if(bookList.size()>0){
update bookList;
}
}
}
}
想法是很快就出现了,代码敲的也很快,就是效果不尽人意┭┮﹏┭┮
小喵第一眼看过去的时候,发现错误信息说的是 记录是只读的,小喵以为没有设置写的权限,然后把权限那一块看了看发现用户是有权限进行读写的,所以小喵去网上查了查, 原因 好像是说 记录仅在该上下文中被读取,因为它们已写入但未提交到数据库
当处于后触发器中时,无法更新触发记录上的字段
想象一下,已经更新了机会,由于更新发生,我们的记录将再次调用触发器,并且我们的案例将发生无限递归循环。
当然,这不代表我们不能创建字段,自己完成这样的功能,
Salesforce告诉我们 : 字段更新属于before 触发器,不需要额外的 DML 操作。
您可以为支持触发器的顶级标准对象(例如联系人或客户)、某些标准子对象(例如 CaseComment)和自定义对象定义触发器。要定义触发器,请从要访问其触发器的对象的对象管理设置中,转到触发器。
有两种类型的触发器:
* 在将记录值保存到数据库之前,触发器用于更新或验证记录值之前。
* After 触发器用于访问系统设置的字段值(例如记录的 Id 或 LastModifiedDate 字段),并影响其他记录中的更改,例如登录审计表或使用队列触发异步事件。触发 after 触发器的记录是只读的。
因此小喵把代码修改了一下,
修改后:
trigger BookTrigger on Book__c(bofore update) {
Map<Id, Book__c> newMap = (Map<Id, Book__c>) Trigger.newMap;
Map<Id, Book__c> oldMap = (Map<Id, Book__c>) Trigger.oldMap;
List<Book__c> newList = (List<Book__c>) Trigger.new;
List<Book__c> oldList = (List<Book__c>) Trigger.old;
//前置
if(Trigger.isBefore){
//修改
if(Trigger.isUpdate){
List<Book__c> bookList = new List<Book__c>();
for(Book__c book : newList){
//修改时间不同
if(book.newUpdateDateTime__c != DateTime.now()){
book.newUpdateDateTime__c = DateTime.now();
}
}
}
}
}
效果 :
小喵建议小伙伴们有时间的话可以读一读 Apex_Trigger
今天分享就到这里了
(^_^)~喵~!!