SERVICENOW

Decision Tables vs Complex If-Else Logic

Build and test maintainable assignment routing with a practical Decision Table implementation.

A routing script may begin with two conditions and grow into a fragile wall of nested if-else statements. This practical build moves category, subcategory and technology routing into a Decision Table, keeps the Business Rule small and gives process owners one readable place to maintain mappings.

Original implementation visualIncident Assignment Decision
01Incident inputs
02Decision rows
03Matched result
CategorySubcategoryTechnologyAssignment group
SoftwareEmailMicrosoft 365Messaging Support
InfrastructureDatabaseOracleDatabase Operations
InfrastructureWeb serverApacheMiddleware Support
Created for Learn Tech with Ravi. Training visual, not a copied product screenshot.
01

Use case and expected result

A support organisation receives incidents for several technologies. The combination of Category, Subcategory and Technology must select the correct Assignment group. The mapping changes regularly, but the logic should not require a code release every time a group changes.

CategorySubcategoryTechnologyExpected group
SoftwareEmailMicrosoft 365Messaging Support
InfrastructureDatabaseOracleDatabase Operations
InfrastructureWeb serverApacheMiddleware Support
Practical note

Decision Tables are a good fit when known combinations of inputs produce a deterministic result. They are not a replacement for procedural processing or complex record manipulation.

02

Why the long if-else approach becomes risky

  • A business mapping is hidden inside code.
  • Every mapping change needs script editing and regression testing.
  • Overlapping branches and spelling differences are difficult to detect.
  • Hard-coded sys_ids make promotion between instances unsafe.
Practical exampleValidate in a non-production instance
if (category == 'software' && subcategory == 'email' && technology == 'm365') {
  current.assignment_group = messagingGroup;
} else if (category == 'infrastructure' && subcategory == 'database' && technology == 'oracle') {
  current.assignment_group = databaseGroup;
} else if (...) {
  // More mappings keep growing here
}
03

Step-by-step implementation

  1. 01Navigate to All > System Definition > Decision Tables and select New.
  2. 02Name the table Incident assignment routing and select Incident as the answer table when a record reference answer is required.
  3. 03Create inputs for Category, Subcategory and Technology. Match their types with the source data. Do not compare a display value with an internal choice value.
  4. 04Create one answer named Assignment group with a reference to User Group [sys_user_group].
  5. 05Add decision rows for the approved mappings. Put the most specific rows above broader fallback rows when first-match behaviour is used.
  6. 06Add an intentional fallback result, such as Service Desk, or let the calling logic handle no answer.
  7. 07Activate the table only after the test combinations have been reviewed.
Practical note

Exact navigation labels can vary by ServiceNow release and installed applications. Search for Decision Tables in the Application Navigator if the module is placed differently.

04

Consume the decision without hard-coded groups

Use the platform-generated API details shown on your Decision Table definition. Input and result names depend on the definition, so copy the generated identifiers from your instance rather than guessing them. The example below shows the safe pattern.

Practical exampleValidate in a non-production instance
(function executeRule(current, previous) {
  var inputs = {
    category: current.getValue('category'),
    subcategory: current.getValue('subcategory'),
    technology: current.getValue('u_technology')
  };

  // Replace the definition id and API call with the generated snippet
  // displayed by your Decision Table in this instance.
  var result = new sn_dt.DecisionTableAPI()
    .getDecision('YOUR_DECISION_DEFINITION_SYS_ID', inputs);

  if (result && result.result_elements &&
      result.result_elements.assignment_group) {
    current.setValue('assignment_group',
      result.result_elements.assignment_group);
  } else {
    gs.warn('No assignment decision matched incident ' + current.getValue('number'));
  }
})(current, previous);
Practical note

Do not paste a random API signature into production. Use the generated code snippet from the Decision Table record because return structure and scoped API usage can differ by configuration and release.

05

Testing checklist

  • Run the Decision Table's own test capability first.
  • Test the consuming Business Rule with a real non-production record.
  • Verify internal values, not only labels visible on the form.
  • Confirm the Assignment group is not overwritten by another Business Rule, Flow or assignment rule.
TestInputExpected evidence
Exact matchSoftware / Email / Microsoft 365Messaging Support returned
Second rowInfrastructure / Database / OracleDatabase Operations returned
No matchUnknown combinationFallback used or warning logged
Missing inputTechnology emptyNo incorrect broad match
Inactive rowMatching row deactivatedRow is not selected
RegressionExisting approved combinationsResults remain unchanged
06

When to use which option

RequirementRecommended option
Many readable input-to-result mappingsDecision Table
Simple record conditions and field updatesBusiness Rule or Flow
Reusable procedural server logicScript Include
Data-driven lookup maintained as recordsLookup table with controlled access
Dynamic orchestration across actionsFlow Designer
Practical note

The maintainable design is usually a small caller plus a visible decision model. Keep data mapping in the table and procedural work in reusable server-side logic.

Continue practical learning.

Explore more implementation-focused ServiceNow and architecture guides.

Explore more articles
Decision Tables vs Complex If-Else Logic | Learn Tech with Ravi