Skip to Content

Cascade Update to Child Records

Automatically update related child records when parent record changes, maintaining data consistency across relationships.

Table: incident When: after
#after #update #cascade #parent-child #relationships #data-sync #automation

Script Code

JavaScript
1(function executeRule(current, previous /*null when async*/) {
2
3  // Configuration: Define which fields trigger cascade updates
4  var cascadeFields = {
5    'priority': true,        // Cascade priority changes to tasks
6    'assignment_group': true, // Cascade assignment group to tasks
7    'state': false,          // Don't cascade state (could be handled differently)
8    'category': true         // Cascade category to tasks
9  };
10
11  // Track which fields changed and should cascade
12  var fieldsToUpdate = [];
13
14  // Check which configured fields changed
15  Object.keys(cascadeFields).forEach(function(fieldName) {
16    if (cascadeFields[fieldName] && current[fieldName].changes()) {
17      fieldsToUpdate.push(fieldName);
18    }
19  });
20
21  // Exit if no relevant fields changed
22  if (fieldsToUpdate.length === 0) {
23    return;
24  }
25
26  try {
27    // Find related child records (incident tasks)
28    var grTask = new GlideRecord('incident_task');
29    grTask.addQuery('incident', current.sys_id);
30    grTask.addQuery('active', 'true');  // Only update active tasks
31    grTask.query();
32
33    var updatedCount = 0;
34
35    while (grTask.next()) {
36      var shouldUpdate = false;
37
38      // Update each changed field
39      fieldsToUpdate.forEach(function(fieldName) {
40        var newValue = current.getValue(fieldName);
41
42        // Only update if task value is different
43        if (grTask.getValue(fieldName) !== newValue) {
44          grTask.setValue(fieldName, newValue);
45          shouldUpdate = true;
46        }
47      });
48
49      // Save if any fields were updated
50      if (shouldUpdate) {
51        // Add work note to document cascade update
52        grTask.work_notes = 'Automatically updated from parent incident ' + 
53                           current.number + '. Fields updated: ' + 
54                           fieldsToUpdate.join(', ');
55
56        // Update without triggering business rules to prevent loops
57        grTask.setWorkflow(false);
58        grTask.autoSysFields(false);  // Don't update sys_updated_by/on
59        grTask.update();
60
61        updatedCount++;
62      }
63    }
64
65    if (updatedCount > 0) {
66      gs.info('Cascade update: Updated ' + updatedCount + ' tasks for incident ' + 
67              current.number + '. Fields: ' + fieldsToUpdate.join(', '));
68
69      // Optional: Add work note to parent incident
70      current.work_notes = 'Cascaded updates to ' + updatedCount + ' related tasks';
71      current.setWorkflow(false);
72      current.update();
73    }
74
75    // Example 2: Cascade to related changes
76    // Uncomment if you need to cascade to related change requests
77    /*
78    var grRelChange = new GlideRecord('change_request');
79    grRelChange.addQuery('u_related_incident', current.sys_id);
80    grRelChange.addQuery('state', 'NOT IN', '-5,3,4');  // Not closed/cancelled
81    grRelChange.query();
82
83    while (grRelChange.next()) {
84      if (cascadeFields.priority && current.priority.changes()) {
85        grRelChange.priority = current.priority;
86        grRelChange.work_notes = 'Priority updated from related incident ' + current.number;
87        grRelChange.setWorkflow(false);
88        grRelChange.update();
89      }
90    }
91    */
92
93    // Example 3: Cascade to child incidents (parent-child relationship)
94    /*
95    if (current.getValue('parent_incident')) {
96      var grChild = new GlideRecord('incident');
97      grChild.addQuery('parent_incident', current.sys_id);
98      grChild.addQuery('active', 'true');
99      grChild.query();
100
101      while (grChild.next()) {
102        // Cascade specific fields to child incidents
103        if (cascadeFields.assignment_group && current.assignment_group.changes()) {
104          grChild.assignment_group = current.assignment_group;
105          grChild.work_notes = 'Assignment group inherited from parent ' + current.number;
106          grChild.setWorkflow(false);
107          grChild.update();
108        }
109      }
110    }
111    */
112
113  } catch (e) {
114    gs.error('Cascade update BR error for incident ' + current.number + ': ' + e.message);
115  }
116
117})(current, previous);

How to Use

1. Create an after Business Rule on parent table 2. Check only "Update" checkbox 3. Configure which fields should cascade in cascadeFields object 4. Identify child table(s) and relationship field 5. Test with parent record updates 6. Verify child records are updated correctly 7. Monitor for potential infinite loops 8. Use setWorkflow(false) to prevent triggering child BRs 9. Document cascade behavior for users

Explore More Scripts

Browse our complete library of ServiceNow scripts

View All Scripts