Fetching Records Using Django’s `get()` Method






Mastering the ‘get’ Method in ServiceNow GlideRecord: Your Guide to Efficient Record Fetching


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), and GlideAjax (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 include GlideSystem (for logging, date/time, and utility functions) and GlideDate/DateTime (for handling dates).

Here’s a quick look at some key players:

Glide API’s
Client SideServer Side
Glide FormGlide Record
Glide UserGlide System
Glide AjaxGlide Date
Glide Dialog WindowGlide Date and Time
Glide ListGlide Aggregation
Glide MenuGlide 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:

  1. Interact with the Database: It provides a structured way to access and manipulate data within any table in your ServiceNow instance.
  2. Handle Rows and Columns: It efficiently manages both individual records (rows) and their specific fields (columns).
  3. 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.
A Crucial Note on Testing: Always, always, always test your GlideRecord scripts on a non-production instance first! An incorrectly constructed query, like a typo in a field name or an invalid condition, can lead to unexpected (and potentially disastrous) results. Using methods like 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()
Where to Run Your Scripts: For practicing these methods, the “Script – Background” module in ServiceNow (accessible via the Filter Navigator) is your best friend. It provides a safe sandbox to execute server-side JavaScript and immediately see the results without impacting your production environment (assuming you’re in a dev instance, of course!). Just type 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:

  1. gr.get(sys_id): Retrieving by System ID

    This is the most common and robust way to use get(). Every record in ServiceNow has a unique 32-character sys_id. If you have this ID, using it with get() 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.
  2. gr.get(fieldName, value): Retrieving by Field-Value Pair

    You can also use get() by providing a field name and its corresponding value. However, be cautious: if multiple records match the fieldName and value, get() will retrieve the first one found. This is why it’s best used with fields known to be unique (like number for Incidents, Problems, Changes, or user_name for 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_id or a unique field like number, 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());

Result → Prints all incident numbers and their short descriptions that have a priority of 1, along with the total count. Here, you’re expecting *multiple* records.

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

Result → Prints a message indicating that the (non-existent) incident was not found. This is critical for robust error handling!

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 (like caller_id), this will be the sys_id of the referenced record. For choice lists (like state or priority), it will be the backend integer or string value (e.g., ‘1’ for “New” state).
  • getDisplayValue(fieldName) (or gr.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 their sys_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.');
}

Result → Prints both the backend value and the user-friendly display value for priority and caller, demonstrating the practical difference.

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

Result → Prints the sys_id of the first incident record found by the query.

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());

Result → Prints the count of active users in the system.

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

Result → Fetches the incident, then fetches the assigned user’s details using their sys_id, and prints their name and email. This demonstrates effective nested 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.');
}

Result → Checks if a CI by a specific name exists and prints a confirmation.

Best Practices for Robust Record Fetching

  • Always Validate: After a get() or query(), use if (gr.isValidRecord()) or if (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: Leverage get(sys_id) or get(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() with addQuery()/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; a GlideRecord inside 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) or getDisplayValue() (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() or query() 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_id or the field name and value you’re passing to get(). 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? Use gr.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 using query().

2. “I’m fetching data, but it’s not the right data!”

  • Field Name Typo: If you’re accessing a field like inc.number or inc.getValue('short_description'), ensure the field name is correct. ServiceNow won’t throw an error for a non-existent field; it’ll just return null or undefined.
  • Value vs. Display Value: Are you using getValue() when you really need getDisplayValue(), or vice versa? For example, fetching a ‘state’ might give you ‘1’, but you want ‘New’.
  • Caching (less common for get()): While rare for direct get() 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 to cache.do in 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 any addQuery() 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 GlideRecord objects or performing query() 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 like addJoinQuery() 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() and gr.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()) or if (gr.next()) after query()).
  • “What’s the difference between getValue() and getDisplayValue(), 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 simply gr.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!


Scroll to Top