GlideRecord

A GlideRecord is a class of object that represents a table & offers a scriptable API to access records on that table

GlideRecord is comprised of GlideElements as well as other methods and metadata that work together to allow you to query from and write to database tables

GlideElement is a class of object that represents a column on a table

There are two versions of GlideRecord, the client side version, and the server side version. docs

CategoryMethodBrief Description
*getLastErrorMessageRetrieves the last error message
*isValidDetermines whether the table exists or not
*operationRetrieves the current operation being performed, such as insert, update, or delete
*setAbortActionSets a flag to indicate if the next database action (insert, update, delete) is to be aborted
*setWorkflowFlag to run or not run other business rules
AccesscanCreateDetermines if the Access Control Rules which include the user's roles permit inserting new records in this table
AccesscanDeleteDetermines if the Access Control Rules which include the user's roles permit deleting records in this table
AccesscanReadDetermines if the Access Control Rules which include the user's roles permit reading records in this table
AccesscanWriteDetermines if the Access Control Rules which include the user's roles permit editing records in this table
QueryaddEncodedQuerySpecifies one of many querys encoded
QueryaddJoinQueryAdds a filter to return records based on a relationship in a related table
QueryaddNotNullQueryAdd's a ^fielsISNOTNULL condition
QueryaddNullQueryAdd's a ^fieldISNULL condition
QueryaddOrConditionAdd's a ^OR condition
QueryaddQuerySpecifies one of many querys
QuerychooseWindowSets a range of rows to be returned by subsequent queries. If forceCount is true, getRowCount() method will return all possible records
QuerygetGet's a single record
QuerygetEncodedQueryReturns the query in it's encoded form
QuerygetRowCountGets the number of rows, not recomeneded, use GlideAggregate instead
QueryhasNextDetermines if there are any more records in the GlideRecord
QuerynextMoves to the next record in the GlideRecord
QueryorderBySets the order by to A-Z on the specified field
QueryorderByDescSets the order by to Z-A on the specified field
QueryqueryRuns the query against the table based on the specified filters by addQuery and addEncodedQuery
QuerysetLimitSets a limit on the number of results
QuerysetEncodedQuery
ReadaddFunctionRetrieve the specified platform function in addition of the field values
ReadgetAttributeGets the attributes on the field in question from the dictionary
ReadgetCategoryDetermines whether a category is set for a query.
ReadgetClassDisplayValue
ReadgetDisplayNameRetrieves the name of the display field
ReadgetDisplayValueRetrieves the display value for the current record
ReadgetElementRetrieves the GlideElement for a specified field
ReadgetLabelThe label of the field as a String
ReadgetLinkRetrieves a link to the current record
ReadgetRecordClassNameRetrieves the class name for the current record
ReadgetTableNameRetrieves the table name associated with this GlideRecord
ReadgetValueRetrieves the underlying value of a field
WriteautoSysFieldsFlag to update fields starting with sys_
WritedeleteMultipleDeletes all records found to match the query
WritedeleteRecordDeletes a single record
WritegetUniqueValueGets the primary key of the record, which is usually the sys_id unless otherwise specified
WriteinitializeSets up the GlideRecord to ignores default values for columns
WriteinsertInsert a new record using the field values that have been set for the current record
WriteisActionAbortedDetermines whether the current database action is to be aborted. Available in Fuji patch 3
WriteisNewRecordChecks if the current record is a new record that has not yet been inserted into the database
WriteisValidFieldDetermines if the given field is defined in the current table
WriteisValidRecordDetermines if current record is a valid record
WritenewRecordSets up the GlideRecord to follow the default values and assigns a sys_id
WritesetCategorySets the category, which determines how the query is routed to a secondary database pool.
WritesetForceUpdateFlag to allow a save/update when there are no changes
WritesetNewGuidAssigns a sys_id when called
WritesetNewGuidValueSets the sys_id to the value specified
WritesetValueSets the value for the specified field.
WriteupdateUpdates the current GlideRecord with any changes that have been made
WriteupdateMultipleUpdates each GlideRecord in the list with any changes that have been made
WriteupdateLazyPlaces update in a batch, doesn't happen immediately, code continues past it. Undocumented.
OperatorsDifferent Operators for GlideRecord

*

These methods apply to query, read, write operations.

getLastErrorMessage

Retrieves the last error message.

isValid

Determines whether the table exists or not.

operation

Retrieves the current operation being performed, such as insert, update, or delete.

setAbortAction

Sets a flag to indicate if the next database action (insert, update, delete) is to be aborted.

setWorkflow

Enables or disables the running of business rules, script engines, and audit.

This does not stop flows for scoped applications. Source

NOTE: This works on queries too

var incident = new GlideRecord('incident');
incident.newRecord();
incident.setValue('short_description','This is text');
incident.setWorkflow(false);//default is true
incident.insert();//returns the sys_id string of inserted record

Access

canCreate

Determines if the Access Control Rules which include the user's roles permit inserting new records in this table.

canDelete

Determines if the Access Control Rules which include the user's roles permit deleting records in this table.

canRead

Determines if the Access Control Rules which include the user's roles permit reading records in this table

canWrite

Determines if the Access Control Rules which include the user's roles permit editing records in this table.

Query

Generally most of the calls you'll make with this will be queries. See if you find a record, find all the records, find a lack of records, then do something else.

addEncodedQuery

// available for server, if you want to use on client, use addQuery(string)
// expects;
// string e.g. .addEncodedQuery('number=INC12345');
// returns null
var incident = new GlideRecord('incident');
incident.addEncodedQuery('number=INC12345');
incident.query();
if(incident.next()){
gs.info('found record');
gs.info(incident.getValue('sys_created_on'));
} else {
gs.info('no record found');
}

addJoinQuery

Adds a filter to return records based on a relationship in a related table.

addNotNullQuery

I generally ignore any other method that modifies the query. These have documentation, but I have yet to use it and find it's code more verbose. Also this only works on server side.

addNullQuery

I generally ignore any other method that modifies the query. These have documentation, but I have yet to use it and find it's code more verbose. Also this only works on server side.

addOrCondition

I generally ignore any other method that modifies the query. These have documentation, but I have yet to use it and find it's code more verbose. Also this only works on server side. To use this in your encoded query just put ^OR between your query strings.

addQuery

This method is most common when coming across queries. Generally folks with either have many addQuery methods declared, or one addEncodedQuery.

// available for both client and server
// expects;
// string e.g. .addQuery('number=INC12345');
// two strings e.g. .addQuery('number','INC12345');
// three strings e.g. .addQuery('number', '=', 'INC12345');
// returns null
var incident = new GlideRecord('incident');
incident.addQuery('number','INC12345');
incident.query();
if(incident.next()){
gs.info('found record');
gs.info(incident.getValue('sys_created_on'));
} else {
gs.info('no record found');
}

chooseWindow

Sets a range of rows to be returned by subsequent queries. If forceCount is true, getRowCount() method will return all possible records.

get

This method is a shortcut to get the first record found that matches the parameters you pass in this method.

// available for both client and server
// expects one of;
// sys_id e.g. .get('asdf1234asdf1234asfd1234asdf1234');
// column, and value e.g. .get('number','INC12345');
// returns
// boolean and moves object onto the record if boolean is true
var incident = new GlideRecord('incident');
if(incident.get('number','INC12345')){//returns true if found
gs.info('found record');
gs.info(incident.getValue('sys_created_on'));
} else {
gs.info('no record found');
}

getEncodedQuery

This is really helpful if debugging code. If you're not sure why you're getting the records you are, I generally add this to my code before my .query() and try the query in the GUI. This works on client and server side code.

getRowCount

This will return the number of rows in your returned object after your .query(). However, this is frowned on because it has some memory issues. I'm not sure exaclty why but generally if you need to know the quantity of records, you should always use GlideAggregate. getRowCount() is available client and server side. GlideAggregate is only available server side.

hasNext

Determines if there are any more records in the GlideRecord.

next

Moves to the next record in the GlideRecord.

orderBy

This will return your set order ascending (a-z, 1-9) by the column name, and is opposite of orderByDesc.

var incident = new GlideRecord('incident');
incident.addEncodedQuery('active=true');
incident.orderBy('number');
incident.query();
while(incident.next()){
gs.info('found record');
gs.info(incident.getValue('number'));
} else {
gs.info('no record found');
}

orderByDesc

This will return your set order descending (z-a, 9-1) by the columne name, and is opposibe of orderBy.

var incident = new GlideRecord('incident');
incident.addEncodedQuery('active=true');
incident.orderByDesc('number');
incident.query();
while(incident.next()){
gs.info('found record');
gs.info(incident.getValue('number'));
} else {
gs.info('no record found');
}

query

Runs the query against the table based on the specified filters by addQuery and addEncodedQuery.

setEncodedQuery

This isn't documented anywhere and I just came across this. Appears to be a way to set the encoded query on the client. I'd avoid using this as it isn't documented, but you can read the code here on hi.

setLimit

This is really useful if you're running a one time script to update some records. Run a test against one record. This works on client and server side code.

var incident = new GlideRecord('incident');
incident.addEncodedQuery('number=INC12345');
incident.setLimit(1);
incident.query();
while(incident.next()){
gs.info('found record');
gs.info(incident.getValue('sys_created_on'));
} else {
gs.info('no record found');
}

Read

addFunction

Retrieve the specified platform function in addition of the field values

getAttribute

Gets the attributes on the field in question from the dictionary

getCategory

The setCategory and getCategory methods are available in GlideRecord for working with query categories when routing to secondary database pools, known as read replicas.

A read replica is a 100% copy of an instance's database (DB) that can be only queried against with the goal to reduce load on the primary database. It's a paid feature and requires an extra plugin that can only be activated by ServiceNow. With setCategory you can route some categories to the read replica, so queries for them will not go to primary database anymore (effectively reducing load on primary database).

Source

getClassDisplayValue

This returns the table class display value, e.g. incident would Return Incident

getDisplayName

Retrieves the name of the display field

getDisplayValue

Retrieves the display value for the current record

getElement

Retrieves the GlideElement for a specified field

getLabel

The label of the field as a String

getLink

Retrieves a link to the current record

getRecordClassName

Retrieves the class name for the current record

getTableName

Retrieves the table name associated with this GlideRecord

getValue

Retrieves the underlying value of a field

Write

autoSysFields

Controls weather or not to set the sys_* fields.

var incident = new GlideRecord('incident');
incident.newRecord();
incident.setValue('short_description','This is text');
incident.autoSysFields(false);//default is true
incident.insert();//returns the sys_id string of inserted record

deleteMultiple

Generally you don't need to delete records, so this is less common to see in use, some places you might see it used are when storing things temporarily. Like the cart's items, those things don't stick around and I've seen it coded to clear it out in some cases. In any case, my point is, this is seen less often.

This is shortcut to delete a lot of records, however it's not necessarily faster. To use this you can just specify your query, and then invoke incident.deleteMultiple();

This is available on server only.

deleteRecord

Generally you don't need to delete records, so this is less common to see in use, some places you might see it used are when storing things temporarily. Like the cart's items, those things don't stick around and I've seen it coded to clear it out in some cases. In any case, my point is, this is seen less often.

If you have a GlideRecord object, you can specify to delete the record like so;

incident.deleteRecord();

This is available on both server, and client, and only in the full gui, not in mobile.

getUniqueValue

Gets the primary key of the record, which is usually the sys_id unless otherwise specified

initialize

var incident = new GlideRecord('incident');
incident.initialize();//ignores default values for columns
incident.setValue('short_description','This is text');
incident.insert();//returns the sys_id string of inserted record

Insert

So to be absolutely clear, to insert or update a record it's nearly the same code, except you use .insert(); or .update();. However you may want to use those with the following methods;

Insert a new record using the field values that have been set for the current record.

isActionAborted

Determines whether the current database action is to be aborted. Available in Fuji patch 3

isNewRecord

Checks if the current record is a new record that has not yet been inserted into the database

isValidField

Determines if the given field is defined in the current table

isValidRecord

Determines if current record is a valid record

newRecord

var incident = new GlideRecord('incident');
incident.newRecord();//Creates a new GlideRecord record, sets the
// default values for the fields, and assigns a unique ID to the record.
incident.setValue('short_description','This is text');
incident.insert();//returns the sys_id string of inserted record

setCategory

The setCategory and getCategory methods are available in GlideRecord for working with query categories when routing to secondary database pools, known as read replicas.

A read replica is a 100% copy of an instance's database (DB) that can be only queried against with the goal to reduce load on the primary database. It's a paid feature and requires an extra plugin that can only be activated by ServiceNow. With setCategory you can route some categories to the read replica, so queries for them will not go to primary database anymore (effectively reducing load on primary database).

Source

setForceUpdate

Normally if no update is detected, Servicenow will ignore the update. With this method, it will apply the update regardless.

var incident = new GlideRecord('incident');
incident.setLimit(1);
incident.query();
if(incident.next()){
incident.setForceUpdate(true);//default is false
incident.update();//returns the sys_id string of inserted record
}

setNewGuid

This sets the guid to a value before the record is saved.

var t = new GlideRecord('task');
var tSysid = t.setNewGuid();
// some fancy script with tSysid

setNewGuidValue

This allows you to manually set your sys_id. I used this to most recently try to fix some broken reference, but I don't know other reasons it may be used.

var a = new GlideRecord('ticket');
a.setNewGuidValue('14018b8cdb69a6403bddf1910f961926');
a.insert();

setValue

Sets the value for the specified field.

Update

So to be absolutely clear, to insert or update a record it's nearly the same code, except you use .insert(); or .update();. However you may want to use those with the following methods;

Updates the current GlideRecord with any changes that have been made.

updateMultiple

So to be absolutely clear, to insert or update a record it's nearly the same code, except you use .insert(); or .update();. However you may want to use those with the following methods;

Updates each GlideRecord in the list with any changes that have been made.

Tim has a post about this specifically.

Here's an example of the method in use;

var staleState = 10;
var query = 'sys_updated_onRELATIVELT@dayofweek@ago@30^state=2';
var incident = new GlideRecord('incident');
incident.addQuery(query);
incident.setValue('state', staleState);
incident.updateMultiple();

updateLazy

Came up on sndevs slack. According to sources there this does;

puts the update into a batch, which means it might not happen right away. Your code can then continue on, but side-effects like BRs and such might not happen for a short while, because the operation doesn't actually occur yet. It is undocumented. It has consequences and isn't meant for casual use.

Operators

Operator labelEquivalent query operatorExample query
is not!=short_description!=Network storage unavailable
and^active=true^CallerISNOTEMPTY
OR filter (new query)^NQactive=true^NQactive=false
OR condition^ORshort_descriptionISEMPTY^ORdescriptionISEMPTY
before<sla_due<javascript:gs.daysAgoStart(0)
less than<reassignment_count<2
at or before<=sla_due<=javascript:gs.daysAgoEnd(0)
less than or is<=short_description<=s
is=short_description=Network storage unavailable
after>sla_due>javascript:gs.daysAgoEnd(0)
greater than>impact>2
at or after>=sla_due>=javascript:gs.daysAgoStart(0)
greater than or is>=short_description>=s
is anythingANYTHINGshort_descriptionANYTHING
betweenBETWEENshort_descriptionBETWEENq@t
betweenBETWEENimpactBETWEEN1@2
betweenBETWEENsla_dueBETWEENjavascript:gs.daysAgoStart(1)@javascript:gs.daysAgoEnd(0)
betweenBETWEENreassignment_countBETWEEN1@2
changes fromCHANGESFROMstateCHANGESFROM4^EQ
changes toCHANGESTOstateCHANGESTO4^EQ
trend (after)DATEPARTsla_dueDATEPARTMonday@javascript:gs.datePart('dayofweek','monday','GT')
trend (before)DATEPARTsla_dueDATEPARTMonday@javascript:gs.datePart('dayofweek','monday','LT')
trend (on or after)DATEPARTsla_dueDATEPARTMonday@javascript:gs.datePart('dayofweek','monday','GE')
trend (on or before)DATEPARTsla_dueDATEPARTMonday@javascript:gs.datePart('dayofweek','monday','LE')
trend (on)DATEPARTsla_dueDATEPARTMonday@javascript:gs.datePart('dayofweek','monday','EE')
is (dyanmic)DYNAMICcaller_idDYNAMIC54635e965f510100a9ad2572f2b4774c
is empty stringEMPTYSTRINGcaller_idEMPTYSTRING
ends withENDSWITHshort_descriptionENDSWITHoutage
greater than fieldGT_FIELDreassignment_countGT_FIELDreopen_count
greater than or is fieldGT_OR_EQUALS_FIELDreassignment_countGT_OR_EQUALS_FIELDreopen_count
is one ofINimpactIN1,2
is emptyISEMPTYshort_descriptionISEMPTY
is not emptyISNOTEMPTYactiveISNOTEMPTY
is less thanLESSTHANsla_dueLESSTHANactivity_due@day@before@3
containsLIKEsubcategoryLIKEem
less than fieldLT_FIELDreassignment_countLT_FIELDreopen_count
less than or is fieldLT_OR_EQUALS_FIELDreassignment_countLT_OR_EQUALS_FIELDreopen_count
is more thanMORETHANsla_dueMORETHANactivity_due@day@before@1
is not one ofNOT INsubcategoryNOT INdb2,sql server,oracle
does not containNOT LIKEsubcategoryNOT LIKEem
not onNOTONTodaysla_dueNOTONToday@javascript:gs.daysAgoStart(0)@javascript:gs.daysAgoEnd(0)
is differentNSAMEASactiveNSAMEASmade_sla
onONTodaysla_dueONToday@javascript:gs.daysAgoStart(0)@javascript:gs.daysAgoEnd(0)
relative (on)RELATIVEEEsla_dueRELATIVEEE@hour@ago@1
relative (on or after)RELATIVEGEsla_dueRELATIVEGE@hour@ago@1
relative (after)RELATIVEGTsla_dueRELATIVEGT@hour@ago@1
relative (on or before)RELATIVELEsla_dueRELATIVELE@hour@ago@1
relative (before)RELATIVELTsla_dueRELATIVELT@hour@ago@1
is sameSAMEASshort_descriptionSAMEASdescription
starts withSTARTSWITHsubcategorySTARTSWITHem
changesVALCHANGESstateVALCHANGES