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
 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');  
     }  
   }  
 }  

Получится следующее:


В общем хитростей в триггерах хватает. Ищите другие рецепты в следующих статьях.

Комментарии

  1. Этот комментарий был удален автором.

    ОтветитьУдалить
  2. Trigger.new, как я понимаю, возвращает коллекцию всех существующих объектов Contact.
    В связи с чем, я не понимаю как поступить, если например встанет задача: "нельзя добавить email, если он совпадает с каким-нибудь email-ом у другого пользователя созданного ранее".

    ОтветитьУдалить
    Ответы
    1. Ответ на вопрос дал на странице форума http://salesforce-developer.ru/forum/viewtopic.php?f=1&t=12#p16

      Удалить
  3. Добрый день Дмитрий. У меня задача после выполнения обновления оппортунити в SF дернуть внешний url передав ему id. Это должно произойти в фоне. Это возможно сделать?

    ОтветитьУдалить
  4. Да, очень даже возможно.

    чтобы "дернуть" воспользуйтесь 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

    ОтветитьУдалить
  5. Спасибо. Буду читать. Еще вопрос мне нужно изначально с помощью апи достать все данные по оппортунити(около 50к записей) Но при выборке получаю только 1000 записей(почитал что это ограничение) Подумалось получить поочередно через LIMIT 1000,2000 Но LIMIT не работает как в mysql. Подскажите что делать

    ОтветитьУдалить
  6. Если нужно выбирать записи пачками то нужно использовать LIMIT в сочетании с OFFSET

    http://www.salesforce.com/us/developer/docs/soql_sosl/Content/sforce_api_calls_soql_select_offset.htm

    Покажите плиз ссылку на информацию о лимите в 1000 записей при запросе через API.

    ОтветитьУдалить
  7. http://salesforce-developer.ru/paginatsiya-na-visualforce-stranitse-pagination-using-standardsetcontroller/

    https://url.odesk.com/uvlinc

    ОтветитьУдалить
  8. Это немного не то. Тут написано про лимит при выводе List объектов на Visualforce странице. На получение данных через API это отношение не имеет.

    ОтветитьУдалить
  9. возможно у моего пользователя недостаточно прав

    ОтветитьУдалить
  10. Дмитрий еще вопросик.
    нашел такую строку в инете
    trigger Opportunity_AfterUpdate on Opportunity (after update) {}

    - Это то что мне нужно?
    - Как внутри тригера получить id opportunity?
    - Тригер сработает сам или его нужно както повесить на события?

    ОтветитьУдалить
  11. trigger Opportunity_AfterUpdate on Opportunity (after update) {}
    Хорошая строка. Trigger название_триггера on объект {когда событие}
    Тоже самое что у меня в примере выше для Contact.

    - да, это триггер для Opportunity;
    - в триггер приходит List объектов (почитайте внимательнее мои статьи). В большинстве случаем в листе содержится 1 записть. Но все равно чтобы получить список Id нужно либо в цикле перебрать Trigger.new или можно получить Set так Trigger.newMap.keySet()
    - триггер начинает работать сразу после создания. (в параметрах вы должны указать список событий)

    ОтветитьУдалить
  12. Если вы хотите продолжить с вопросами, приглашаю зарегистрироваться на форуме http://salesforce-developer.ru/forum/ Там есть больше шансов получить ответы от разных людей, не только от меня.

    ОтветитьУдалить
  13. http://salesforce-developer.ru/forum/viewtopic.php?f=1&t=17

    ОтветитьУдалить

Отправить комментарий

Популярные сообщения из этого блога

Начало работы, первые шаги, hello world в Salesforce