Mastering Base Tables in ServiceNow: Your Essential Guide
Ever felt a bit lost navigating the intricate data structures within ServiceNow? You’re not alone. At the heart of every powerful platform lies a well-organized database, and for ServiceNow, that means understanding its base tables. These aren’t just abstract concepts; they are the bedrock upon which all your IT services, workflows, and automations are built.
Whether you’re a seasoned ServiceNow administrator, a budding developer, or even someone just looking to ace that next technical interview, a solid grasp of how to interact with these foundational tables is non-negotiable. This article will take you on a journey through the most crucial base tables, their relationships, and how to manipulate them effectively using practical examples and best practices.
Interview Insight: Questions about base tables, GlideRecord, and table relationships are incredibly common in ServiceNow interviews. Mastering these concepts demonstrates a fundamental understanding of the platform’s architecture.
1. The Foundation: Users, Groups, and Permissions
Let’s kick things off with the very entities that interact with ServiceNow daily: users and groups. Managing who can do what is paramount, and it all starts with these core tables.
1.1 Identifying the Core: User and Group Tables
- User Table Name:
sys_user - Group Member Table Name:
sys_user_group(This is actually the Group table itself, for group members it’ssys_user_grmember)
Indeed, sys_user is where all your individual user accounts reside, holding details like username, first name, last name, email, and more. The sys_user_group table, on the other hand, defines the groups within your organization, like ‘Service Desk’ or ‘Network Team’. The link between users and groups, forming group memberships, is actually managed by the sys_user_grmember table.
1.2 Crafting Accounts: Scripting Users and Groups
While you can certainly create users and groups manually through the UI, scripting becomes your best friend for bulk creation, integrations, or automated provisioning. The key player here is GlideRecord.
Creating a User Account:
Imagine needing to onboard a new batch of employees. Instead of clicking through forms, a simple script can handle it:
var userGr = new GlideRecord('sys_user');
userGr.initialize(); // Prepares a new record for insertion
userGr.username = 'jdoe';
userGr.first_name = 'John'; // Corrected field name
userGr.last_name = 'Doe'; // Corrected field name
userGr.email = 'jdoe@example.com';
userGr.insert(); // Saves the new user record to the database
gs.info("User jdoe created successfully!");Tip: Always use initialize() before setting field values for a new record to ensure all default values are populated correctly. Also, be mindful of exact field names (e.g., first_name, not firstname).
Creating a Group:
Similarly, setting up new teams is a breeze with scripting:
var newGr = new GlideRecord('sys_user_group');
newGr.initialize();
newGr.name = 'Testing Team'; // A more descriptive name is always better
newGr.manager = '62826bf03710200044e0bfc8bcbe5df1'; // Sys_id of the manager user
newGr.email = 'testing@example.com'; // Use your organization's domain
newGr.description = 'A group for testing purposes.';
newGr.insert();
gs.info("Group 'Testing Team' created successfully!");Notice the manager field. For reference fields like this, you typically provide the sys_id of the referenced record (in this case, a user from sys_user).
1.3 Permission Management: Roles and Best Practices
Access control is critical. In ServiceNow, roles define permissions. You can assign roles directly to users or, more commonly and preferably, to groups.
Best Practice: Assign Roles to Groups!
This is a fundamental concept and a frequent interview question. Why groups?
When you assign roles to a group, all members of that group automatically inherit those roles. If an employee leaves, simply removing them from the group revokes all their group-inherited permissions, making offboarding much cleaner and less error-prone. Direct user role assignments should be reserved for very specific, often temporary, cases.
Interview Relevance: Explaining why assigning roles to groups is best practice showcases your understanding of maintainability, scalability, and security in an enterprise environment.
Scripting Role Assignment:
When a role is assigned, a record is created in a linking table. For users, it’s sys_user_has_role. For groups, it’s sys_group_has_role.
Adding a Role to a User (Generally discouraged, but possible):
var userRole = new GlideRecord('sys_user_has_role');
userRole.initialize();
userRole.setValue('user', '62826bf03710200044e0bfc8bcbe5df1'); // Sys_id of the user
userRole.setValue('role', '2831a114c611228501d4ea6c309d626d'); // Sys_id of the role
userRole.insert();
gs.info("Role assigned to user.");Adding a Role to a Group (Recommended!):
var grpRole = new GlideRecord('sys_group_has_role');
grpRole.initialize();
grpRole.setValue('group', '477a05d153013010b846ddeeff7b1225'); // Sys_id of the group
grpRole.setValue('role', '2831a114c611228501d4ea6c309d626d'); // Sys_id of the role
grpRole.insert();
gs.info("Role assigned to group.");Tip: Always retrieve the sys_id of the user, group, or role you intend to use in a script from your ServiceNow instance. Hardcoding these can be brittle if records are deleted or recreated in different environments.
1.4 Managing Group Members Programmatically
Adding or removing users from groups is a common administrative task. The sys_user_grmember table is your friend here.
Adding a Group Member:
var grMem = new GlideRecord('sys_user_grmember');
grMem.initialize();
grMem.user = '62826bf03710200044e0bfc8bcbe5df1'; // Sys_id of the user
grMem.group = '477a05d153013010b846ddeeff7b1225'; // Sys_id of the group
grMem.insert();
gs.info("User added to group.");Removing a Group Member:
To remove someone, you first need to find their specific membership record:
var grMem = new GlideRecord('sys_user_grmember');
grMem.addQuery('user', '62826bf03710200044e0bfc8bcbe5df1'); // Sys_id of the user
grMem.addQuery('group', '477a05d153013010b846ddeeff7b1225'); // Sys_id of the group
grMem.query();
if (grMem.next()) { // If a matching record is found
grMem.deleteRecord();
gs.info("User removed from group.");
} else {
gs.warn("User not found in specified group.");
}Caution: Always add a check (like if(grMem.next())) before performing a deleteRecord() to prevent unintended deletions or errors if the record doesn’t exist.
1.5 User Delegation: Sharing the Load
What if someone goes on vacation but their approvals or tasks can’t wait? That’s where user delegation comes in. It allows one user to act on behalf of another.
Definition: User delegation means granting another user temporary permissions to perform tasks, receive notifications, and access resources normally available to the original user. It’s a lifesaver for business continuity during absences.
Example: A manager is on PTO and needs their team lead to approve pending change requests. The manager can delegate their approval tasks to the team lead for a specific period.
How to Configure (UI Path):
- Navigate to the original user’s profile (e.g., by typing
sys_user.listin the Filter Navigator, then opening their record). - Scroll down to the ‘Related Links’ section.
- Click on ‘Delegates’.
- Click ‘New’ to create a new delegation record.
- Specify the delegate (the person taking over), start date, end date, and select which permissions to delegate (e.g., assignments, notifications, approvals, meetings).
Interview Insight: Delegation is often discussed in scenarios related to workflow continuity and user management. Knowing the ‘why’ and ‘how’ is key.
2. Orchestrating IT: Task Management Tables
ServiceNow’s strength lies in its IT Service Management (ITSM) capabilities. At the core of ITSM are tables like Incident, Problem, and Change, all extending from a powerful base table: task.
2.1 The Mighty task Table
The task table (task) is a fundamental base table in ServiceNow. It doesn’t extend from any other table, but many critical tables, like Incident, Problem, and Change Request, extend from it. This provides a common set of fields and functionalities (e.g., number, short description, description, state, priority, assignment group) that all these derived tables can share, promoting consistency and reducing redundancy.
Interview Relevance: When asked about base tables, task and cmdb_ci are prime examples because they are at the top of their respective hierarchies and extended by many others.
Examples of Tables Extending task:
incidentproblemchange_requestsc_task(Service Catalog Task)approval- …and many more!
2.2 Scripting Core ITIL Records
Just like users and groups, you can programmatically create Incident, Problem, and Change records. This is vital for integrations, automated ticket creation, or service portal submissions.
Creating an Incident Record:
var gr = new GlideRecord('incident');
gr.initialize();
gr.caller_id = '86826bf03710200044e0bfc8bcbe5d94'; // Sys_id of the caller user
gr.category = 'inquiry';
gr.subcategory = 'antivirus';
gr.cmdb_ci = 'affd3c8437201000deeabfc8bcbe5dc3'; // Sys_id of the Configuration Item
gr.short_description = 'Test record created via script';
gr.description = 'This incident was automatically generated by a script for testing purposes.';
gr.assignment_group = 'a715cd759f2002002920bde8132e7018'; // Sys_id of the assignment group
gr.insert();
gs.info("Incident " + gr.number + " created.");Creating a Problem Record:
var gr = new GlideRecord('problem');
gr.initialize();
gr.caller_id = '86826bf03710200044e0bfc8bcbe5d94'; // Could be the user who identified the problem
gr.category = 'inquiry';
gr.subcategory = 'antivirus';
gr.cmdb_ci = 'affd3c8437201000deeabfc8bcbe5dc3';
gr.short_description = 'New problem identified via script';
gr.description = 'This problem record was created programmatically.';
gr.assignment_group = 'a715cd759f2002002920bde8132e7018';
gr.insert();
gs.info("Problem " + gr.number + " created.");Creating a Change Request:
var gr = new GlideRecord('change_request');
gr.initialize();
gr.category = 'inquiry'; // Often tied to specific change types in real scenarios
gr.subcategory = 'antivirus';
gr.cmdb_ci = 'affd3c8437201000deeabfc8bcbe5dc3';
gr.short_description = 'Automated change request for software update';
gr.description = 'This change request was initiated by a script to deploy an antivirus update.';
gr.assignment_group = 'a715cd759f2002002920bde8132e7018';
gr.insert();
gs.info("Change Request " + gr.number + " created.");2.3 Workflow Automation with Business Rules
Business Rules are server-side scripts that run when a record is displayed, inserted, updated, or deleted. They are critical for automating processes and enforcing business logic. Let’s look at some common scenarios.
Scenario 1: Closing Child Incidents when Parent Closes
This is a classic ITIL requirement. If a major incident is resolved, all related child incidents should also be closed.
Logic: An ‘After’ Business Rule on the Incident table, triggered on ‘Update’ when the state changes to ‘Closed’ (assuming state value 7 for Closed). The rule then queries for child incidents and updates their state.
// Business Rule: Close Child Incidents
// Table: incident
// When: After
// Update: true
// Condition: current.state.changesTo(7) && current.parent.nil() // Only run if it's a parent incident closing
if (current.state == 7 && current.parent.nil()) { // current.parent.nil() ensures it's a top-level parent
var grChild = new GlideRecord('incident');
grChild.addQuery('parent_incident', current.sys_id); // Ensure you use the correct field for parent-child relationship, often 'parent_incident' or 'parent'
grChild.query();
while (grChild.next()) {
grChild.state = 7; // Set the state to Closed
grChild.update(); // Update the child incident
gs.info("Child incident " + grChild.number + " closed due to parent " + current.number + " closure.");
}
}Troubleshooting: If child incidents aren’t closing, check the Business Rule condition, the state value (make sure 7 is indeed ‘Closed’), and the field name used for linking parent/child incidents (e.g., `parent_incident` vs. `parent`).
Scenario 2: Preventing Incident Closure with Open Tasks
You wouldn’t want an incident to be marked resolved if there are still tasks associated with it that haven’t been completed. This ensures proper process adherence.
Logic: A ‘Before’ Business Rule on the Incident table, triggered on ‘Update’ when the state changes to ‘Closed’. It queries the incident_task table.
// Business Rule: Prevent Incident Closure with Open Tasks
// Table: incident
// When: Before
// Update: true
// Condition: current.state.changesTo(7) // When trying to close the incident
var grTask = new GlideRecord('incident_task');
grTask.addQuery('incident', current.sys_id); // Link to the current incident
grTask.addQuery('state', '!=', 3); // Assuming 3 is the state value for 'Closed' for incident_task
grTask.query();
if (grTask.hasNext()) { // If any open tasks are found
gs.addErrorMessage('Cannot close this incident because there are open tasks. Please close all associated tasks first.');
current.setAbortAction(true); // Prevents the incident from being saved with the new state
}Critical Function: current.setAbortAction(true) is crucial here. It stops the current database operation (the update to the incident) and prevents the record from being saved.
Extension: This logic can be easily adapted for Problem and Change Requests by changing the table to problem_task or change_task respectively.
Scenario 3: Closing Associated Incidents when Problem Closes
When the root cause (problem) is resolved, all incidents linked to it should ideally be closed as well, signaling that the underlying issue is fixed.
Logic: An ‘After’ Business Rule on the Problem table, triggered on ‘Update’ when the state changes to ‘Closed’. It then finds associated incidents.
// Business Rule: Close Associated Incidents when Problem Closes
// Table: problem
// When: After
// Update: true
// Condition: current.state.changesTo(7) // When the problem is closing
if (current.state == 7) {
var grIncident = new GlideRecord('incident');
grIncident.addQuery('problem_id', current.sys_id); // Link to the current problem
grIncident.addQuery('state', '!=', 7); // Only update incidents that are not already closed
grIncident.query();
while (grIncident.next()) {
grIncident.state = 7; // Set the incident state to Closed
grIncident.update(); // Update the incident
gs.info("Incident " + grIncident.number + " closed due to problem " + current.number + " closure.");
}
}3. The Anatomy of ServiceNow Tables
Beyond specific record types, understanding how tables themselves are structured and behave is foundational.
3.1 Out-of-the-Box vs. Custom Tables
- Out-of-the-Box (OOB) Tables: These are the tables that come with ServiceNow and are part of the core platform. Their names typically do not start with a prefix like
u_orx_(e.g.,incident,sys_user). - Custom Tables:
- Global Scope Custom Tables: Start with
u_(e.g.,u_my_custom_table). These are created in the global application scope. - Scoped Application Custom Tables: Start with
x_followed by the application scope prefix (e.g.,x_myco_myapp_my_table). These are created within a specific custom application scope.
- Global Scope Custom Tables: Start with
Interview Insight: Knowing the naming conventions helps identify the origin and scope of tables at a glance, a useful skill for troubleshooting and development.
3.2 What Happens When You Extend a Table?
Table extension is a powerful feature enabling inheritance. When you extend a table (e.g., incident extends task):
- Field Inheritance: The child table inherits all fields from its parent table. These inherited fields do not get recreated in the child table itself; they are ‘borrowed’ from the parent. This saves database space and promotes data consistency.
sys_id: Every record in ServiceNow has a uniquesys_id, whether it’s a parent or child table record. It’s the primary key for the record.sys_class_nameField: A field calledsys_class_name(often referred to simply asclass) is added to the parent table. This field stores the name of the actual table where the record originated. For example, a record in thetasktable might havesys_class_name = incidentif it’s truly an incident, orproblemif it’s a problem. This allows polymorphic querying. Even if a table extends multiple layers deep (e.g.,incident->task->), there’s only onesys_class_namefield on the ultimate base table.- ACLs & Business Rules: Child tables can also inherit or override ACLs and Business Rules from their parent.
3.3 Creating Custom Number Fields (Auto-numbering)
To have records automatically assigned unique numbers (like INC0001001 for incidents):
When defining your custom table (or modifying an existing one), go to the Controls tab. Here, you can:
- Check the ‘Auto-number’ checkbox.
- Provide a ‘Prefix’ (e.g., ‘MYT’ for “My Table”).
- Specify the number of ‘Digits’ (e.g., 7 for MYT0000001).
This ensures each new record gets a sequential, unique identifier.
3.4 Essential Field Types
Fields are how we store data. ServiceNow offers a rich variety of field types to suit different data needs:
- String: For short text (e.g., ‘Short Description’, ‘Name’).
- Reference: Links to a record in another table (e.g., ‘Caller’ references
sys_user). - List: Links to multiple records in another table (e.g., ‘Watch list’ in Incident).
- Choice: A dropdown list of predefined options (e.g., ‘State’, ‘Category’).
- Email: Stores an email address.
- Date/Time: Stores both a date and a time.
- Date: Stores only a date.
- Boolean: A true/false or yes/no value (checkbox).
- Integer: Whole numbers.
- Journal: For activity streams or comments (e.g., ‘Comments (Customer Visible)’).
- Attachment: Allows files to be attached to the record.
- HTML: For rich text content.
- Currency: Stores monetary values.
- URL: Stores web addresses.
3.5 Temporary vs. Normal Tables
- Normal Tables: Store data permanently in the database. This is the default and most common type of table.
- Temporary Tables: Store data for a limited period, typically 7 days by default. They are often used for intermediate processing, like when importing data (they extend
import_set_row). After the retention period, records are automatically deleted.
Can you increase retention for temporary tables? Yes, you can extend the retention period for temporary tables by configuring Archive Rules. This allows you to define how long records should be kept before being archived or deleted.
3.6 Remote vs. Normal Tables
- Normal Tables: Store data directly within the ServiceNow instance’s database. When you query them, you retrieve the stored data.
- Remote Tables: Don’t store data directly in ServiceNow. Instead, they provide a live, real-time view of data residing in an external system. When you query a remote table, ServiceNow makes a call to the external system to fetch the data. This is useful for integrating with external systems without replicating data.
3.7 Understanding Table Relationships
Data rarely exists in isolation. Tables often relate to each other:
- One-to-Many Relationship: A single record in one table can be associated with multiple records in another, but each record in the second table is linked to only one in the first.
- Example: Users and Incidents. One user (
sys_user) can submit multiple incidents (incident), but each incident has only one ‘Caller’.
- Example: Users and Incidents. One user (
- Many-to-Many Relationship: Records in both tables can be associated with multiple records in the other. This typically requires a “junction” or “many-to-many” table to link them.
- Example: Incidents and Groups. An incident might involve multiple assignment groups (e.g., for collaboration), and a group can be associated with multiple incidents. The
task_cior similar linking tables often facilitate this for tasks and CIs, or custom many-to-many tables are created.
- Example: Incidents and Groups. An incident might involve multiple assignment groups (e.g., for collaboration), and a group can be associated with multiple incidents. The
Interview Relevance: Demonstrating an understanding of relationships and their implementation (e.g., junction tables for many-to-many) is a strong indicator of architectural understanding.
3.8 Where Are All Tables Stored?
Every table defined in your ServiceNow instance, whether OOB or custom, has an entry in the sys_db_object table. This is essentially the meta-table that lists all other tables.
3.9 The “Collection” Field on a Table
When you look at the Dictionary for a table, you’ll notice one entry has a ‘Type’ of “Collection”. This entry doesn’t represent a specific field but rather the table itself. Any attributes or properties set on this “Collection” dictionary entry apply to the entire table, not just a single field.
Example: How to disable attachments using attributes: To disable attachments for an entire form/table, you would go to the dictionary entry for that table where ‘Type’ is ‘Collection’ and add the attribute no_attachment=true.
4. Controlling Data and UI Behavior
ServiceNow offers numerous ways to define how data is entered, displayed, and validated.
4.1 Ways to Create a Record
There’s more than one path to creating a record:
- Form: The most common way, directly through the UI.
- Record Producer: A service catalog item that generates a record (e.g., ‘Report an Incident’ portal form).
- Email: Inbound email actions can parse emails and create records.
- GlideRecord (Script): Programmatically, as we’ve seen.
- Import Set (Excel/CSV): For bulk data imports.
- External Systems: Through APIs (REST, SOAP) or integrations.
4.2 Making Fields Mandatory or Read-Only
You have several tools at your disposal:
- Dictionary Properties: Directly on the field’s dictionary entry (e.g., ‘Mandatory’ checkbox). This applies globally.
- Dictionary Overrides: Allows a field in a child table to behave differently from the parent (e.g., making a field mandatory on Incident but not on Task).
- UI Policies: Client-side logic for dynamic changes based on conditions on the form.
- Data Policies: Enforce data integrity consistently across all data entry points (UI, imports, web services).
- Client Scripts (
g_form): Usingg_form.setMandatory()org_form.setReadOnly()for highly dynamic, client-side control.
Interview Relevance: Expect questions comparing these methods, especially UI Policies vs. Data Policies, and their order of precedence.
4.3 Display Fields: A Unique Identifier
Every table should have exactly one display field. This field is used to represent a record in reference fields, breadcrumbs, and search results. If you set two fields as display, it leads to confusion about which one should be shown in different contexts. ServiceNow will default to the first alphabetically or throw errors.
Example: For the sys_user table, ‘Name’ (name) is the display field. For incident, it’s ‘Number’ (number).
4.4 Setting Default Values
To pre-populate a field when a new form loads, you can set a default value in the field’s dictionary entry. This saves users time and ensures consistency.
4.5 The current Object: Your Server-Side Companion
The current object is a server-side GlideRecord object representing the record being inserted, updated, or queried by a server-side script (like Business Rules or Script Includes). It allows you to get and set field values of that record.
current.setValue('field_name', value): Sets a field’s value. For reference fields,valueshould be thesys_idof the referenced record.current.setDisplayValue('field_name', value): Sets a reference field’s value using its display value (e.g., the user’s name instead of theirsys_id). ServiceNow will automatically resolve thesys_id. This is generally preferred for readability when setting reference fields if you don’t have thesys_idhandy.
4.6 Reference Qualifiers: Filtering Choices
Reference qualifiers are used to restrict the data shown in ‘Reference’ and ‘List’ type fields, helping users find the correct record faster and preventing incorrect selections. There are three main types:
a) Simple Reference Qualifier
- Description: The most straightforward. You specify a fixed query string.
- Example: In an ‘Assigned To’ field (referencing
sys_user), you might only want to show active users. - How to Use: In the reference field’s dictionary entry, under ‘Reference Qualifier’, enter the condition directly.
active=true^roles=itilThis would show only active users with the ‘itil’ role.
b) Dynamic Reference Qualifier
- Description: Uses a pre-configured ‘Dynamic Filter Option’ that can be context-aware. This option wraps a JavaScript function to build the query.
- Example: Displaying only incidents assigned to the same assignment group as the current user.
- How to Use:
- Create a Dynamic Filter Option (System Definition > Dynamic Filter Options).
- Define the conditions/script within that option.
- In your reference field’s dictionary entry, select ‘Dynamic’ for the reference qualifier and choose your created dynamic filter option.
c) Advanced Reference Qualifier (JavaScript)
- Description: Provides maximum flexibility by allowing you to write a custom JavaScript function that returns a query string. This is for complex filtering based on multiple conditions, other form field values, or server-side logic.
- Example: Filter Configuration Items (CIs) based on the selected ‘Category’ field on the form, AND only show CIs that are ‘Operational’.
- How to Use: In the reference field’s dictionary entry, select ‘Advanced’ for the reference qualifier and enter your JavaScript.
javascript:'install_status=1^operational_status=1^category='+current.variables.category; // Example for a variable in a record producer // Or for a field on a form: javascript:'install_status=1^operational_status=1^category='+current.category;Here,
current.categorywould dynamically pull the value of the ‘Category’ field on the current form to filter CIs.
Interview Insight: Be prepared to differentiate between the three types and provide suitable use cases for each. Focus on when to use ‘Advanced’ for true dynamism.
4.7 Dependent Values: Cascading Dropdowns
Dependent values are used to filter the available choices in one ‘Choice’ field based on the selection made in another ‘Choice’ field. Think of it as creating cascaded dropdown menus.
Steps to Configure:
- Identify Parent and Dependent Fields: E.g., ‘Category’ (parent) and ‘Subcategory’ (dependent).
- Configure the Parent Field: Ensure it has its choices defined.
- Configure the Dependent Field:
- Go to the dictionary entry of the dependent field (‘Subcategory’).
- Set the ‘Dependent field’ attribute to the parent field (‘Category’).
- When defining the choices for ‘Subcategory’, you’ll see a ‘Dependent value’ column. Here, you link each subcategory choice to a specific category value.
Example: If ‘Category’ is ‘Hardware’, ‘Subcategory’ choices might be ‘Laptop’, ‘Desktop’, ‘Printer’. If ‘Category’ is ‘Software’, ‘Subcategory’ choices might be ‘Operating System’, ‘Application’, ‘Database’.
4.8 Calculated Values
A calculated field displays a value that is derived from other fields on the same record using a script. The value isn’t stored in the database but calculated on the fly when the record is viewed or accessed.
How to Use: In the dictionary entry for a field, check the ‘Calculated’ checkbox. A ‘Calculation’ script field will appear, where you write a server-side script using the current object to determine the field’s value. The script’s last line should be answer = ...;.
Example: Calculating a ‘Response Time Left’ field based on ‘SLA Due Date’ and the current time.
4.9 Attributes: Modifying Field Behavior
Attributes are key-value pairs added to dictionary entries that change the behavior or appearance of fields. They offer a simple yet powerful way to customize the UI without extensive scripting.
Common Attributes:
no_email=true: Prevents the field’s value from being included in email notifications.no_attachment=true: Disables the attachment icon for that field or table (if applied to the Collection record).tree_picker=true: Displays a hierarchical picker for reference fields (useful for CMDB or groups).no_add_me=true: Hides the “Add me” button on reference fields that populate the current user.max_length=X: Overrides the default string length.
4.10 Dictionary Overrides
A dictionary override is used when you want a field in a child table to have a different behavior or value than the same field inherited from its parent table. It’s about breaking inheritance for specific dictionary properties.
Properties you can override:
- Default value
- Mandatory
- Read-only
- Active (if the field is even available)
- Label (though this is rare and often better handled by translations)
- Reference Qualifiers
- …and many attributes.
Example: The ‘Priority’ field is inherited from the task table. You might want the default priority for Incidents to be 4 (‘Medium’), but for Problems, it should default to 5 (‘Planning’). A dictionary override on the incident table for the ‘Priority’ field allows you to set its default value without affecting other tables that extend task.
4.11 Data Lookup Rules
Data Lookup Rules (often confused with ‘Data Policies’) automatically populate field values on a form based on a set of conditions and matching values from a lookup table. They provide a declarative, non-scripted way to automate data entry.
Example: When a user selects a ‘Category’ and ‘Subcategory’ on an Incident form, a Data Lookup Rule could automatically set the ‘Priority’ and ‘Assignment Group’ based on predefined mappings.
5. UI Policies vs. Data Policies: Client, Server, and Control
These two are often misunderstood, but critical for controlling form behavior and data integrity.
5.1 UI Policies
What they are: Client-side logic that dynamically changes the behavior of fields on a form based on conditions. They run in the user’s browser.
Used to:
- Make fields mandatory, read-only, or visible.
- Show/hide related lists.
- Display messages.
Key UI Policy Checkboxes:
- Global: If checked, the UI Policy applies to all views of the form. If unchecked, you can specify a particular view.
- Reverse if false: If checked, the actions defined in the UI Policy are reversed when the condition becomes false. (e.g., if a field became mandatory when true, it becomes optional again when false).
- On Load: If checked, the UI Policy’s conditions are evaluated and actions applied immediately when the form loads. If unchecked, actions are only triggered when a field value changes after the form has loaded, matching the conditions.
- Inherit: If checked, the UI Policy will also apply to child tables that extend the table where the policy is defined.
- Run scripts: Allows you to execute client-side JavaScript when the UI Policy conditions are met (on ‘Execute if true’ script) or not met (on ‘Execute if false’ script). This gives you powerful dynamic control beyond simple field changes.
Interview Relevance: “When would you use a UI Policy vs. a Client Script?” is a classic. Generally, UI Policies are preferred for simple mandatory/read-only/visible changes as they are declarative and easier to maintain. Use Client Scripts for complex DOM manipulation or AJAX calls.
5.2 Converting UI Policies to Data Policies
You can often convert a UI Policy into a Data Policy directly from the UI Policy record. This is a quick way to enforce similar rules more broadly.
When Conversion IS NOT Possible (Key Limitations):
- When your UI Policy controls data visibility (making fields visible/hidden). Data Policies primarily focus on mandatory/read-only enforcement, not UI visibility.
- When you are controlling form views.
- When you are controlling related lists.
- When your UI Policy involves client-side scripts (the ‘Run scripts’ checkbox is checked). Data Policies are designed to be declarative or run server-side, not client-side JavaScript.
5.3 Data Policies
What they are: Server-side logic that enforces data integrity by making fields mandatory, read-only, or hidden based on conditions. They work consistently across all data sources.
Key Differences from UI Policies:
- Client & Server Side: Data policies can run on both client-side (to provide immediate feedback) and server-side (to enforce integrity regardless of how data is entered).
- All Data Sources: They apply to data entered via forms, import sets, web services, mobile apps, etc. UI Policies only apply to forms.
- Data Integrity: Their primary purpose is to ensure data quality and consistency by enforcing rules before data is saved to the database.
Interview Relevance: A critical distinction! Data Policies are about enforcing data integrity always, while UI Policies are about improving the user experience on a form.
6. Troubleshooting Tips for Base Tables
Even with the best planning, issues can arise. Here are some common troubleshooting areas:
- Script Errors: Check your script syntax, variable names, and field names carefully. Use
gs.info()andgs.log()statements to debug your script execution flow and variable values. Always test in a non-production environment! - `sys_id` Issues: Incorrect or non-existent
sys_idvalues in scripts will lead to records not being found or relationships not being established. Double-check all hardcodedsys_ids. - Permissions (ACLs): If users can’t see, create, or update records, always suspect ACLs. Ensure users have the correct roles for the table and fields in question. Check the ‘Debug Security’ module for a detailed breakdown of ACL evaluations.
- Business Rule Order: If multiple Business Rules affect the same field or record, their ‘Order’ value (lower numbers run first) can determine unexpected behavior.
- UI/Data Policy Conflicts: When a field isn’t behaving as expected (e.g., still editable when it should be read-only), check for conflicting UI Policies, Data Policies, Dictionary Overrides, or Client Scripts. Often, one policy might override another.
- State Values: Ensure you are using the correct numerical value for states (e.g., 7 for ‘Closed’, 3 for ‘Closed Complete’). These can vary slightly between instances or custom configurations.
7. Interview Relevance: What to Emphasize
For any ServiceNow role, a strong understanding of base tables is paramount. Here’s what to highlight:
- GlideRecord Mastery: Show you can create, read, update, and delete records programmatically.
- Best Practices: Emphasize role assignment to groups, using `initialize()` before `insert()`, and understanding the impact of Business Rules.
- Table Relationships: Clearly explain `task` and `cmdb_ci` as base tables and their extension model.
- UI vs. Data Policies: Be able to articulate their differences, use cases, and when to choose one over the other.
- Reference Qualifiers: Demonstrate knowledge of the different types and their application for data accuracy.
- Troubleshooting Skills: Discuss how you would approach debugging script errors or unexpected form behavior.
Conclusion
Working with base tables in ServiceNow is truly at the core of everything you’ll do on the platform. From managing user permissions to automating complex ITIL workflows, the ability to understand and interact with these foundational data structures is what transforms a casual user into a proficient ServiceNow professional.
By mastering GlideRecord, understanding table extensions, and skillfully applying UI and Data Policies, you’re not just learning commands; you’re gaining the power to shape the entire ServiceNow experience. Keep exploring, keep building, and remember that every solution you create rests firmly on the robust foundation of ServiceNow’s base tables.