Mastering the ‘get’ Method in ServiceNow GlideRecord: Your Guide to Efficient Record Fetching
Hey there, fellow ServiceNow enthusiast! Ever found yourself needing to grab just one specific record from your instance’s massive database? Maybe you’ve got a sys_id from a log, or an incident number from an email, and you need to pull up all its details in a script. If so, you’re in the right place! Today, we’re going to demystify one of the most powerful and frequently used methods in ServiceNow’s server-side scripting arsenal: the GlideRecord.get() method.
While GlideRecord offers a plethora of ways to interact with your data, get() stands out for its precision and efficiency when you know exactly what you’re looking for. It’s like having a direct, express lane to a single piece of information, rather than sifting through an entire library.
Let’s embark on this journey to understand not just what get() does, but also why it’s a critical tool in your development kit, how it compares to other fetching methods, and how to wield it like a pro to build robust and performant ServiceNow solutions.
The Heartbeat of ServiceNow Scripting: GlideRecord Overview
Before we zero in on get(), let’s set the stage with a quick refresher on GlideRecord itself. If you’ve been working with ServiceNow for any amount of time, you’ve undoubtedly encountered the Glide API. It’s the developer’s bread and butter for bending the platform to our will, allowing us to customize default behaviors and extend existing functionalities.
Think of Glide APIs as your specialized toolset for interacting with the ServiceNow application through scripting. Instead of writing complex SQL queries (which, let’s be honest, can be a pain and are generally discouraged in ServiceNow), Glide APIs provide high-level, JavaScript-friendly methods to perform database operations. Each API is packed with methods designed to perform distinct operations, making your life as a developer much easier and your code more readable.
Types of Glide APIs: Client-Side vs. Server-Side
ServiceNow APIs broadly fall into two categories:
- Client-Side APIs: These run in the user’s browser, typically interacting with the UI. Examples include
GlideForm(for manipulating forms),GlideUser(for user information), andGlideAjax(for asynchronous communication with the server). - Server-Side APIs: These execute on the ServiceNow server, interacting directly with the database or performing heavier logic. This is where our star,
GlideRecord, shines brightest. Other notable server-side APIs includeGlideSystem(for logging, date/time, and utility functions) andGlideDate/DateTime(for handling dates).
Here’s a quick look at some key players:
| Glide API’s | |
|---|---|
| Client Side | Server Side |
| Glide Form | Glide Record |
| Glide User | Glide System |
| Glide Ajax | Glide Date |
| Glide Dialog Window | Glide Date and Time |
| Glide List | Glide Aggregation |
| Glide Menu | Glide Element |
What is GlideRecord and Why is it so Important?
GlideRecord is arguably the most common and vital API you’ll encounter in ServiceNow development. It’s a special Java class that runs exclusively on the server side, acting as a native JavaScript object within the platform. Its primary purpose? To perform CRUD (Create, Read, Update, Delete) operations on your ServiceNow database without you ever having to write a line of SQL!
Imagine it as a sophisticated translator that takes your simple JavaScript commands and turns them into efficient database queries. This abstraction is a huge advantage, making data interaction safer, faster, and more standardized. It allows you to:
- Interact with the Database: It provides a structured way to access and manipulate data within any table in your ServiceNow instance.
- Handle Rows and Columns: It efficiently manages both individual records (rows) and their specific fields (columns).
- Abstract SQL: You define what you want to do in JavaScript, and GlideRecord handles the underlying SQL generation, ensuring adherence to platform best practices and security models.
insert(), update(), or deleteRecord() with a bad query could even result in data loss. Play it safe!The architecture of GlideRecord is quite elegant: you write JavaScript, and the platform transparently maps it to the appropriate SQL queries, executing them against the underlying database. This abstraction layer is what makes server-side scripting in ServiceNow so powerful yet approachable.
Diving Deep into GlideRecord Methods
The GlideRecord object comes packed with a comprehensive set of methods to handle almost any data interaction scenario. From fetching a single record to updating thousands, there’s a method for it. While we can’t cover all 50+ methods in detail right now (you can see a glimpse of their variety in the table below), we’re here to focus on one of the most fundamental for data retrieval: get().
| Glide Record Methods (Selection) | ||
|---|---|---|
| Query() | Insert() | getDisplayValue() |
| addQuery() | deleteRecord() | getValue() |
| addActiveQuery() | update () | isValidRecord() |
| addEncodedQuery() | initialize () | getLink() |
| addInactiveQuery() | deleteMultiple () | setLimit() |
| next() | updateMultiple() | orderBy() |
| get() | addNullQuery() | orderByDesc() |
| getRowCount() | addNotNullQuery() | canRead() |
| getUniqueValue() | setWorkflow() | setAbortAction() |
gs.print() or gs.info() to see your output.Fetching with Precision: Understanding the get() Method
Alright, let’s get to the star of our show: the GlideRecord.get() method. If you know exactly which record you want and you have a unique identifier for it – usually its sys_id or another unique field like a record number – get() is your fastest and most straightforward path to retrieve it.
What Does get() Do?
The get() method attempts to retrieve a single record from the database based on the provided identifier. It’s designed for direct, pinpoint retrieval, making it incredibly efficient when you’re sure about the record’s existence and its unique key. It’s not for finding “all incidents with priority 1”; it’s for finding “the incident with this specific sys_id.”
How to Use get(): Syntax and Parameters
The get() method has two primary signatures:
gr.get(sys_id): Retrieving by System IDThis is the most common and robust way to use
get(). Every record in ServiceNow has a unique 32-charactersys_id. If you have this ID, using it withget()guarantees you’ll retrieve that specific record (if it exists and you have access).var inc = new GlideRecord('incident'); var targetSysId = '44e116e02f1a60100a7351172799b61d'; // Replace with a real sys_id from your instance if (inc.get(targetSysId)) { // Attempt to fetch the record gs.print('Incident Number: ' + inc.number); gs.print('Short Description: ' + inc.short_description); gs.print('State: ' + inc.state.getDisplayValue()); } else { gs.print('Incident with sys_id ' + targetSysId + ' not found or inaccessible.'); }Result → Prints the Incident number, Short Description, and State for the record matching the provided sys_id, or a ‘not found’ message.gr.get(fieldName, value): Retrieving by Field-Value PairYou can also use
get()by providing a field name and its corresponding value. However, be cautious: if multiple records match thefieldNameandvalue,get()will retrieve the first one found. This is why it’s best used with fields known to be unique (likenumberfor Incidents, Problems, Changes, oruser_namefor users).var inc = new GlideRecord('incident'); var targetIncidentNumber = 'INC0009005'; // Replace with a real incident number from your instance if (inc.get('number', targetIncidentNumber)) { // Fetching by Incident Number gs.print('Sys ID for ' + targetIncidentNumber + ': ' + inc.sys_id); gs.print('Assigned To: ' + inc.assigned_to.getDisplayValue()); gs.print('Opened By: ' + inc.caller_id.getDisplayValue()); } else { gs.print('Incident ' + targetIncidentNumber + ' not found or inaccessible.'); }Result → Prints the sys_id, Assigned To, and Opened By (display values) for the specified incident number.And another common use case for fetching a user record:
var user = new GlideRecord('sys_user'); var targetUserName = 'admin'; // Or any other user_name if (user.get('user_name', targetUserName)) { // Fetching a user by their user_name gs.print('User Name: ' + user.user_name); gs.print('Full Name: ' + user.name); gs.print('Email: ' + user.email); } else { gs.print('User with user_name "' + targetUserName + '" not found!'); }Result → Prints the user’s name, full name, and email if the ‘admin’ user is found.
get() vs. query() + next(): Choosing the Right Tool
This is a common point of confusion for new developers. While both methods retrieve records, their use cases are distinct and knowing when to use which is key to efficient scripting:
-
Use
get()when:- You need a single, specific record.
- You have a unique identifier (
sys_idor a unique field likenumber,user_name). - You prioritize direct and efficient retrieval of that one record. It’s often faster for single lookups because it doesn’t need to set up an iterator.
-
Use
query()+next()when:- You need to retrieve multiple records that meet certain conditions.
- You need to iterate through a set of records to process each one.
- You need to apply complex filtering (using
addQuery(),addEncodedQuery(), etc.), sorting (orderBy()), or limit the results (setLimit()).
Let’s revisit an example from our reference using query() to highlight the difference:
var inc = new GlideRecord('incident');
inc.addQuery('priority', 1); // Add a filter for Priority 1 tickets
inc.query(); // Execute the query to find all matching records
gs.print('--- Priority 1 Incidents ---');
while(inc.next()){ // Loop through ALL matching records
gs.print('Incident: ' + inc.number + ' | Short Description: ' + inc.short_description);
}
gs.print('Total Priority 1 Incidents: ' + inc.getRowCount());See the difference? get() is like asking, “Show me the book with ISBN 12345,” while query() is like asking, “Show me all books by author ‘John Doe’ that were published this year.” Both are valid, but for different purposes. Using the right tool for the job is a hallmark of good development.
Essential Companion Methods for Record Fetching
While get() is powerful on its own, it often works in tandem with other GlideRecord methods to ensure you’re getting the right data and handling it correctly. Let’s look at a few that are highly relevant to record fetching and data extraction:
isValidRecord(): Did We Actually Find Anything?
After a get() or query() operation, it’s crucial to confirm whether a record was successfully retrieved. This method returns true if a record was found and false otherwise. It’s an indispensable guard against null pointer exceptions and ensures your script behaves predictably.
var inc = new GlideRecord('incident');
var nonExistentIncident = 'INC9999999';
inc.get('number', nonExistentIncident); // An incident number that likely doesn't exist
if (inc.isValidRecord()) { // Check if a record was returned
gs.print('Incident ' + inc.number + ' found!');
} else {
gs.print('Incident ' + nonExistentIncident + ' not found. Check your number, table name, or ACLs.');
}getValue() vs. getDisplayValue(): Raw Data vs. User-Friendly Data
These methods are vital for extracting data from the fields of your fetched record, and understanding their difference is fundamental:
getValue(fieldName): Retrieves the actual, raw value stored in the database for a field. For reference fields (likecaller_id), this will be thesys_idof the referenced record. For choice lists (likestateorpriority), it will be the backend integer or string value (e.g., ‘1’ for “New” state).getDisplayValue(fieldName)(orgr.fieldName.getDisplayValue()): Retrieves the user-friendly, displayed value of a field, as it would appear on a form. This is incredibly useful for reference fields (to get the name of the caller instead of theirsys_id) or choice lists (to get “New” instead of “1”).
var inc = new GlideRecord('incident');
var targetIncident = 'INC0000007'; // Replace with an actual incident number
if (inc.get('number', targetIncident)) {
gs.print('Priority (Raw Value): ' + inc.getValue('priority'));
gs.print('Priority (Display Value): ' + inc.priority.getDisplayValue());
gs.print('Caller (Raw Value - Sys_ID): ' + inc.getValue('caller_id'));
gs.print('Caller (Display Value - Name): ' + inc.caller_id.getDisplayValue());
} else {
gs.print('Incident ' + targetIncident + ' not found.');
}getUniqueValue(): Getting the Current Record’s Sys_ID
This method returns the sys_id of the current record in your GlideRecord object. It’s a clean and reliable way to get the unique identifier after you’ve fetched or created a record.
var inc = new GlideRecord('incident');
inc.query(); // Fetch some records (e.g., all incidents)
if (inc.next()) { // Move to the first one if available
var uniqueId = inc.getUniqueValue();
gs.print('Sys_ID of the first incident: ' + uniqueId);
} else {
gs.print('No incidents found to get unique value from.');
}getRowCount(): How Many Did We Find?
Used after a query() (not typically get(), as get() aims for one), this method returns the total number of records that matched your query conditions. It’s great for summaries or checking if any records matched your criteria.
var users = new GlideRecord('sys_user');
users.addActiveQuery(); // Only active users
users.query();
gs.print('Total active users: ' + users.getRowCount());Real-World Scenarios and Best Practices for Record Fetching
Now that we’ve covered the mechanics, let’s look at how get() and its companions fit into practical ServiceNow development, along with some tips to keep your scripts lean, mean, and functional.
Scenario 1: Fetching a User’s Details from a Reference Field
Imagine you have an incident record, and you need to fetch the email address of the person assigned to it. The assigned_to field is a reference field, storing the sys_id of the user, not their name or email.
var incidentNumber = 'INC0000007'; // Replace with a real incident number
var grInc = new GlideRecord('incident');
if (grInc.get('number', incidentNumber)) { // Use get() to fetch the incident first
var assignedToSysId = grInc.getValue('assigned_to'); // Get the sys_id of the assigned_to user
if (assignedToSysId) { // Check if an assigned user exists
var grUser = new GlideRecord('sys_user');
if (grUser.get(assignedToSysId)) { // Use get() again to fetch the assigned_to user's full record
gs.print('Incident ' + incidentNumber + ' is assigned to: ' + grUser.name);
gs.print('Assigned To Email: ' + grUser.email);
} else {
gs.print('Assigned user record not found for sys_id: ' + assignedToSysId);
}
} else {
gs.print('Incident ' + incidentNumber + ' has no assigned user.');
}
} else {
gs.print('Incident ' + incidentNumber + ' not found or inaccessible.');
}get() usage for related records.Scenario 2: Validating a Configuration Item (CI) Exists Before Linking
Before associating a new change request or incident with a Configuration Item, you might want to ensure that CI actually exists in your CMDB. This prevents creating records with broken references.
var ciName = 'My Test Server 01'; // The name of a CI we want to link
var grCI = new GlideRecord('cmdb_ci');
if (grCI.get('name', ciName)) { // Fetch CI by name (assuming CI names are unique enough for your purpose)
gs.print('Configuration Item "' + ciName + '" (Sys ID: ' + grCI.sys_id + ') exists!');
// Now you can safely proceed to link this CI to a new change request or incident.
// Example: var newChange = new GlideRecord('change_request'); newChange.cmdb_ci = grCI.sys_id; newChange.insert();
} else {
gs.print('Configuration Item "' + ciName + '" not found. Cannot proceed with linking.');
}Best Practices for Robust Record Fetching
- Always Validate: After a
get()orquery(), useif (gr.isValidRecord())orif (gr.next())to confirm a record was found before attempting to access its fields. This prevents runtime errors if the record doesn’t exist. - Use
get()for Uniqueness: Leverageget(sys_id)orget(unique_field_name, value)for single, precise record lookups. This is usually the most performant way to retrieve a known record. query()for Collections: When you need to find multiple records or apply complex filters,query()withaddQuery()/addEncodedQuery()is the way to go.- Performance Matters: Avoid querying large tables without sufficient filters. Use
setLimit()if you only need a few records. Be mindful of GlideRecord operations inside loops; aGlideRecordinside a loop that queries the same table repeatedly can be a performance killer. - Understand Field Types: Always know whether you need the
getValue()(raw data) orgetDisplayValue()(user-friendly text) for a given field. - Security through ACLs: Remember that GlideRecord operations are subject to Access Control Lists (ACLs). If your script runs as a user without the necessary permissions,
get()orquery()might return no records or incomplete data, even if the records technically exist.
Troubleshooting Common Issues with Record Fetching
Even seasoned developers hit snags. Here are some common issues you might encounter when fetching records and how to troubleshoot them:
1. “My get() method isn’t finding the record!”
- Check for Typos: This is the most frequent culprit. Double-check the
sys_idor the field name and value you’re passing toget(). Even a single character off will result in no match. - Table Name Correctness: Is the table name in
new GlideRecord('table_name')spelled correctly and does it actually exist? Usegr.isValid()to confirm the table itself is valid. - ACL Restrictions: The user context in which your script runs might not have read access to that specific record or table. Test by running the script as an admin or with a user role that has broader access to rule this out.
- Non-Unique Field Value (for
get(fieldName, value)): If you’re using a field that isn’t strictly unique (e.g.,short_description),get()will only return the *first* matching record. If you expect multiple, you should be usingquery().
2. “I’m fetching data, but it’s not the right data!”
- Field Name Typo: If you’re accessing a field like
inc.numberorinc.getValue('short_description'), ensure the field name is correct. ServiceNow won’t throw an error for a non-existent field; it’ll just returnnullorundefined. - Value vs. Display Value: Are you using
getValue()when you really needgetDisplayValue(), or vice versa? For example, fetching a ‘state’ might give you ‘1’, but you want ‘New’. - Caching (less common for
get()): While rare for directget()operations, in very specific scenarios, especially when dealing with recently modified records and server-side cache, stale data might appear. Clearing instance cache (by navigating tocache.doin your instance) can sometimes resolve erratic behavior, but this is a last resort and should be used with caution in shared environments.
3. “My script is slow when fetching records.”
- Too Broad a Query: If you’re using
query()without anyaddQuery()filters, you’re fetching *all* records in a table, which can be incredibly slow for large tables. Always narrow down your results as much as possible. - GlideRecord in a Loop: Avoid creating new
GlideRecordobjects or performingquery()operations repeatedly inside a loop. If you need to fetch related records for each item in a query result, try to optimize (e.g., fetch all related records first and store them in an array/object, then process, or use advanced methods likeaddJoinQuery()for complex relationships). - Excessive Data Retrieval: Only retrieve the fields you actually need. While GlideRecord is generally efficient, fetching an entire record with dozens of fields when you only need one or two can add unnecessary overhead.
Interview Relevance: A Developer’s Perspective
Mastering GlideRecord is non-negotiable for any aspiring or current ServiceNow developer. It’s a fundamental skill, and interviewers *will* test your knowledge. Being able to articulate these concepts clearly, perhaps with a small code snippet, will significantly boost your credibility. Here are common questions related to record fetching:
- “Explain the difference between
gr.get()andgr.query(). When would you use each?” (The core topic of this article!) - “How do you retrieve a specific incident record if you only know its number?” (Answer:
gr.get('number', 'INCXXXXX')). - “After fetching a record, how do you ensure it actually exists before you try to access its fields?” (Answer:
if (gr.isValidRecord())orif (gr.next())afterquery()). - “What’s the difference between
getValue()andgetDisplayValue(), and when would you use each?” (Crucial for handling reference and choice fields correctly). - “How would you retrieve the sys_id of the currently active record in a GlideRecord object?” (Answer:
gr.getUniqueValue()or simplygr.sys_id). - “What are some best practices for writing performant GlideRecord queries?” (Answer: Focus on filtering, limiting results, avoiding nested queries, and checking for record existence).
Concluding Thoughts
The GlideRecord.get() method is a fundamental building block in your ServiceNow scripting toolkit. Its ability to efficiently and precisely fetch single records by sys_id or unique field values makes it indispensable for countless server-side operations, from validating inputs to retrieving details for complex business logic. While it’s powerful on its own, remember that it truly shines when used thoughtfully alongside other GlideRecord methods like isValidRecord(), getValue(), and in appropriate contexts alongside query().
By understanding when and how to use get(), practicing with real-world scenarios, and applying best practices, you’re not just fetching data – you’re building more robust, efficient, and maintainable ServiceNow applications. Keep experimenting, keep learning, and happy scripting!