Apex Triggers - триггеры в Salesforce
Триггеры в Salesforce (apex triggers) - замечательный и парой коварный инструмент разработчика. А по научному это apex код который выполняется ДО или ПОСЛЕ следующих DML операций:
insert
update
delete
merge
upsert
undelete
Замечательность данного инструмента заключается в том, что можно добавлять свою логику на обработку объектов при их создании, изменении или удалении. Не надо искать все места в коде, где производятся эти манипуляции. Пишите триггер и он всегда срабатывает. Особенно это полезно если надо добавить свою логику к стороннему пакету, к исходникам которого вы никогда доступа не получите.
Коварность же заключается в том, что в триггер работает не с одной записью, а с набором. Т.е. на вход триггера может попасть как набор из одной записи, так и 200 записей. И если обработка каждой записи требует значительных ресурсов, то ваш триггер вполне вероятно вывалится по лимитам. Важно понимать что apex class, из которого вызывается DML операция , как и триггер работают как единый набор логики с общим лимитом.
Триггеры можно разделить на два типа:
- до (before) - используются в основном для проверки (изменения) данных перед вставкой их в базу данных
- после (after) - используются, когда необходимо получить и обработать данные записи установленные самой базой данных (значение ID, значения системных полей, например LastUpdated и др.). Это тип триггера отрабатывает только если запись проходит стандартную валидацию базы данных salesforce и успешно сохраняется.
Перейдем к самому интересному - написанию первого триггера.
Задача: создать триггер для объекта Contact, который проверяет что поле Email заполнено. Если email не указан, заполняет его значением по-умолчанию, скажем some_email@email.com
checkEmail.trigger
Если надо проверить значение поля и вывести ошибку, то можно сделать так:
Получится следующее:
В общем хитростей в триггерах хватает. Ищите другие рецепты в следующих статьях.
insert
update
delete
merge
upsert
undelete
Замечательность данного инструмента заключается в том, что можно добавлять свою логику на обработку объектов при их создании, изменении или удалении. Не надо искать все места в коде, где производятся эти манипуляции. Пишите триггер и он всегда срабатывает. Особенно это полезно если надо добавить свою логику к стороннему пакету, к исходникам которого вы никогда доступа не получите.
Коварность же заключается в том, что в триггер работает не с одной записью, а с набором. Т.е. на вход триггера может попасть как набор из одной записи, так и 200 записей. И если обработка каждой записи требует значительных ресурсов, то ваш триггер вполне вероятно вывалится по лимитам. Важно понимать что apex class, из которого вызывается DML операция , как и триггер работают как единый набор логики с общим лимитом.
Триггеры можно разделить на два типа:
- до (before) - используются в основном для проверки (изменения) данных перед вставкой их в базу данных
- после (after) - используются, когда необходимо получить и обработать данные записи установленные самой базой данных (значение ID, значения системных полей, например LastUpdated и др.). Это тип триггера отрабатывает только если запись проходит стандартную валидацию базы данных salesforce и успешно сохраняется.
Перейдем к самому интересному - написанию первого триггера.
Задача: создать триггер для объекта Contact, который проверяет что поле Email заполнено. Если email не указан, заполняет его значением по-умолчанию, скажем some_email@email.com
checkEmail.trigger
trigger checkEmail on Contact (before insert) {
for (Contact c : Trigger.new) {
if (c.Email == null) {
c.Email = 'some_email@email.com';
}
}
}
Если надо проверить значение поля и вывести ошибку, то можно сделать так:
trigger checkEmail on Contact (before insert) {
for (Contact c : Trigger.new) {
if (c.Email == null) {
c.Email.addError('Please enter email');
}
}
}
Получится следующее:
В общем хитростей в триггерах хватает. Ищите другие рецепты в следующих статьях.
Этот комментарий был удален автором.
ОтветитьУдалитьTrigger.new, как я понимаю, возвращает коллекцию всех существующих объектов Contact.
ОтветитьУдалитьВ связи с чем, я не понимаю как поступить, если например встанет задача: "нельзя добавить email, если он совпадает с каким-нибудь email-ом у другого пользователя созданного ранее".
Ответ на вопрос дал на странице форума http://salesforce-developer.ru/forum/viewtopic.php?f=1&t=12#p16
УдалитьДобрый день Дмитрий. У меня задача после выполнения обновления оппортунити в SF дернуть внешний url передав ему id. Это должно произойти в фоне. Это возможно сделать?
ОтветитьУдалитьДа, очень даже возможно.
ОтветитьУдалитьчтобы "дернуть" воспользуйтесь http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_restful_http_httprequest.htm
Чтобы "в фоне" можно это сделать во @future методе.
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_annotation_future.htm
Спасибо. Буду читать. Еще вопрос мне нужно изначально с помощью апи достать все данные по оппортунити(около 50к записей) Но при выборке получаю только 1000 записей(почитал что это ограничение) Подумалось получить поочередно через LIMIT 1000,2000 Но LIMIT не работает как в mysql. Подскажите что делать
ОтветитьУдалитьЕсли нужно выбирать записи пачками то нужно использовать LIMIT в сочетании с OFFSET
ОтветитьУдалитьhttp://www.salesforce.com/us/developer/docs/soql_sosl/Content/sforce_api_calls_soql_select_offset.htm
Покажите плиз ссылку на информацию о лимите в 1000 записей при запросе через API.
http://salesforce-developer.ru/paginatsiya-na-visualforce-stranitse-pagination-using-standardsetcontroller/
ОтветитьУдалитьhttps://url.odesk.com/uvlinc
Это немного не то. Тут написано про лимит при выводе List объектов на Visualforce странице. На получение данных через API это отношение не имеет.
ОтветитьУдалитьвозможно у моего пользователя недостаточно прав
ОтветитьУдалитьДмитрий еще вопросик.
ОтветитьУдалитьнашел такую строку в инете
trigger Opportunity_AfterUpdate on Opportunity (after update) {}
- Это то что мне нужно?
- Как внутри тригера получить id opportunity?
- Тригер сработает сам или его нужно както повесить на события?
trigger Opportunity_AfterUpdate on Opportunity (after update) {}
ОтветитьУдалитьХорошая строка. Trigger название_триггера on объект {когда событие}
Тоже самое что у меня в примере выше для Contact.
- да, это триггер для Opportunity;
- в триггер приходит List объектов (почитайте внимательнее мои статьи). В большинстве случаем в листе содержится 1 записть. Но все равно чтобы получить список Id нужно либо в цикле перебрать Trigger.new или можно получить Set так Trigger.newMap.keySet()
- триггер начинает работать сразу после создания. (в параметрах вы должны указать список событий)
Если вы хотите продолжить с вопросами, приглашаю зарегистрироваться на форуме http://salesforce-developer.ru/forum/ Там есть больше шансов получить ответы от разных людей, не только от меня.
ОтветитьУдалитьhttp://salesforce-developer.ru/forum/viewtopic.php?f=1&t=17
ОтветитьУдалить