I
doubt if there’s a single concept in Service-now that is more valuable to understand than how to use GlideRecord methods to query, insert, update, and delete records in your system. These methods have a wide variety of uses and are found at the heart of many of the business rules, UI actions, and scheduled job scripts that are essential to tie together your organization’s processes in your Service-now instance.
While the content of this post isn’t new information (additional examples can be found on the Service-now wiki), my aim is to provide a single page of information containing some common examples of these methods as a reference. This is an excellent page to keep bookmarked!
A standard GlideRecord query follows this format.
//The 'addQuery' line allows you to restrict the query to the field/value pairs specified (optional)
//gr.addQuery('active', true);
gr.query(); //Execute the query
while (gr.next()) { //While the recordset contains records, iterate through them
//Do something with the records returned
if(gr.category == 'software'){
gs.log('Category is ' + gr.category);
}
}
The ‘get’ method is a great way to return a single record when you know the sys_id of that record.
gr.get(sys_id_of_record_here);
//Do something with the record returned
if(gr.category == 'software'){
gs.log('Category is ' + gr.category);
}
You can also query for a specific field/value pair. The ‘get’ method returns the first record in the result set.
var gr = new GlideRecord('incident');
if(gr.get('active', true)){
//Do something with the record returned
gs.log('Category is ' + gr.category);
}
The ‘getRefRecord’ method can be used as a shortcut to query a record populated in a reference field on a record.
caller.email = 'test@test.com';
caller.update();
The standard ‘addQuery’ parameter acts like an ‘and’ condition in your query. This example shows how you can add ‘or’ conditions to your query.
var gr = new GlideRecord('incident');
var grOR = gr.addQuery('priority', 1);
grOR.addOrCondition('priority', 2);
gr.query();
while (gr.next()) {
//Do something with the records returned
if(gr.category == 'software'){
gs.log('Category is ' + gr.category);
}
}
Inserts are performed in the same way as queries except you need to replace the ‘query()’ line with an ‘initialize()’ line as shown here.
var gr = new GlideRecord('incident');
gr.initialize();
gr.short_description = 'Network problem';
gr.category = 'software';
gr.caller_id.setDisplayValue('Joe Employee');
gr.insert();
You can perform updates on one or many records simply by querying the records, setting the appropriate values on those records, and calling ‘update()’ for each record.
var gr = new GlideRecord('incident');
gr.addQuery('active',true);
gr.query();
while (gr.next()) {
gr.active = false;
gr.update();
}
Delete records by performing a glideRecord query and then using the ‘deleteRecord’ method.
var gr = new GlideRecord('incident');
gr.addQuery('active',false);
gr.query();
while (gr.next()) {
//Delete each record in the query result set
gr.deleteRecord();
}
If you are deleting multiple records then the ‘deleteMultiple’ method can be used as a shortcut
var gr = new GlideRecord('incident');
gr.addQuery('active', false);
gr.deleteMultiple(); //Deletes all records in the record set
An alternative to a standard query is to use an encoded query to create your query string instead of using ‘addQuery’ and ‘addOrCondition’ statements. An easy way to identify the encoded query string to use is to create a filter or a module with the query parameters you want to use, and then hover over the link or breadcrumb and look at the URL. The part of the URL after ‘sysparm_query=’ is the encoded query for that link.
So if I had a URL that looked like this…
https://demo.service-now.com/incident_list.do?sysparm_query=active=true^category=software^ORcategory=hardware
My encoded query string would be this…
active=true^category=software^ORcategory=hardware
I could build that encoded query string and use it in a query like this…
var gr = new GlideRecord('incident');
var strQuery = 'active=true';
strQuery = strQuery + '^category=software';
strQuery = strQuery + '^ORcategory=hardware';
gr.addEncodedQuery(strQuery);
gr.query();
GlideAggregate is actually an extension of the GlideRecord object. It allows you to perform the following aggregations on query recordsets…
-COUNT
-SUM
-MIN
-MAX
-AVG
var gr = new GlideAggregate('incident');
gr.addQuery('active', true);
gr.addAggregate('COUNT');
gr.query();
var incidents = 0;
if (gr.next()){
incidents = gr.getAggregate('COUNT');
gs.log('Active incident count: ' + incidents);
}
You can order the results of your recordset by using ‘orderBy’ and/or ‘orderByDesc’ as shown below.
var gr = new GlideRecord('incident');
gr.addQuery('active', true);
gr.orderBy('category');
gr.orderByDesc('sys_created_on');
gr.query();
‘addNullQuery’ and ‘addNotNullQuery’ can be used to search for empty (or not empty) values
var gr = new GlideRecord('incident');
gr.addNullQuery('short_description');
gr.query();
var gr = new GlideRecord('incident');
gr.addNotNullQuery('short_description');
gr.query();
‘getRowCount’ is used to get the number of results returned
var gr = new GlideRecord('incident');
gr.addQuery('category', 'software');
gr.query();
gs.log('Incident count: ' + gr.getRowCount());
var gr = new GlideRecord('incident');
gr.addQuery('category', 'software');
gr.query();
alert('Incident count: ' + gr.rows.length);
‘setLimit’ can be used to limit the number of results returned
var gr = new GlideRecord('incident');
gr.orderByDesc('sys_created_on');
gr.setLimit(10);
gr.query();
‘setWorkflow’ is used to enable/disable the running of any business rules that may be triggered by a particular update.
var gr = new GlideRecord('incident');
gr.addQuery('category', 'software');
gr.query();
while(gr.next()){
gr.category = 'hardware';
gr.setWorkflow(false);
gr.update();
}
‘autoSysFields’ is used to disable the update of ‘sys’ fields (Updated, Created, etc.) for a particular update. This really is only used in special situations. The primary example is when you need to perform a mass update of records to true up some of the data but want to retain the original update timestamps, etc.
var gr = new GlideRecord('incident');
gr.addQuery('category', 'software');
gr.query();
while(gr.next()){
gr.category = 'hardware';
gr.autoSysFields(false);
gr.update();
}
‘setForceUpdate’ is used to update records without having to change a value on that record to get the update to execute. ‘setForceUpdate’ is particularly useful in situations where you need to force the recalculation of a calculated field for all records in a table or when you need to run business rules against all records in a table but don’t want to have to change a value on the records.
This method is often used with ‘setWorkflow’ and ‘autoSysFields’ as shown below.
var gr = new GlideRecord('sys_user');
gr.query();
while (gr.next()) {
gr.setWorkflow(false); //Do not run business rules
gr.autoSysFields(false); //Do not update system fields
gr.setForceUpdate(true); //Force the update
gr.update();
}
The following operators can be used in addition to the standard field/value query searching shown above…
| = | Field value must be equal to the value supplied. | addQuery('priority', '=', 3); |
| > | Field must be greater than the value supplied. | addQuery('priority', '>', 3); |
| < | Field must be less than the value supplied. | addQuery('priority', '<', 3); |
| >= | Field must be equal to or greater than the value supplied. | addQuery('priority', '>=', 3); |
| <= | Field must be equal to or less than the value supplied. | addQuery('priority', '<=', 3); |
| != | Field must not equal the value supplied. | addQuery('priority', '!=', 3); |
| STARTSWITH | Field must start with the value supplied. The example shown on the right will get all records where the short_description field starts with the text 'Error'. | addQuery('short_description', 'STARTSWITH', 'Error'); |
| ENDSWITH | Field must end with the value supplied. The example shown on the right will get all records where the short_description field ends with text 'Error'. | addQuery('short_description', 'ENDSWITH', 'Error'); |
| CONTAINS | Field must contain the value supplied anywhere in the field. The example shown on the right will get all records where the short_description field contains the text 'Error' anywhere in the field. | addQuery('short_description', 'CONTAINS', 'Error'); |
| DOES NOT CONTAIN | Field must not contain the value supplied anywhere in the field. The example shown on the right will get all records where the short_description field does not contain the text 'Error' anywhere in the field. | addQuery('short_description', 'DOES NOT CONTAIN', 'Error'); |
| IN | Field must contain the value supplied anywhere in the string provided. | addQuery('sys_id', 'IN', '0331ddb40a0a3c0e40c83e9f7520f860,032ebb5a0a0a3c0e2e2204a495526dce'); |
| INSTANCEOF | Retrieves only records of a specified class for tables which are extended. For example, to search for configuration items (cmdb_ci table) you many want to retrieve all configuration items that are have are classified as computers. The code uses the INSTANCEOF operator to query for those records. | addQuery('sys_class_name', 'INSTANCEOF', 'cmdb_ci_computer'); |
Comments
Posted On
Feb 23, 2010Posted By
ToddExcellent Cheat Sheet! More more…..
Posted On
Feb 23, 2010Posted By
CesarThanks Mark! this is helpful.
Posted On
Apr 15, 2010Posted By
Ivan MartezGreat Cheat Sheet and an excellent website!!
Posted On
Sep 09, 2010Posted By
ChrisIs there a way to query for a date ? Such as current.addQuery(‘opened_at’, ‘<=’, new Date()-7); Although this does not work is there a way to do something like this to query for a given date range ?
Posted On
Sep 09, 2010Posted By
Mark StangerThere is. I usually use the ‘addEncocdedQuery’ method when dealing with date queries. You can build the query you want in a module or filter definition to see what the encoded query should look like.
Posted On
Nov 04, 2010Posted By
BennyThanks Mark!
I’ve scoured the SN wiki and this is a better summary of their glide record pages. I’m a newbie to SN and I must admit I’ve found the learning curve a bit steep for customising SN, having come from other SaaS systems as Salesforce & Rightnow.
These systems let you use GUI’s to do most things and for more advanced customisation there is a scripting option. SN seems to be all scripting from the get go with limited use of GUIs for configuration. It would be nice if their wiki included a clearer explanation on how Client Scripts, UI Policies, UI Actions, Business Rules & Access Control all fits together…
Posted On
Nov 04, 2010Posted By
Mark StangerThanks for the comment. I think as you become more familiar with Service-now you’ll see that the majority of configurations are GUI-based or require some pretty light scripting. I’m not that familiar with Salesforce & Rightnow so I couldn’t say how Service-now compares. Hopefully some of the content here helps you to get going a little bit faster. I know that the SNC documentation team is really focusing right now on scripting documentation so what you see on the wiki should be getting better by the day.
You might check out these forum links for some more information about SNC scripting basics. It gives some information from presentations I’ve given in the past about how some of this stuff connects. http://community.service-now.com/forum/3480 http://community.service-now.com/forum/3613
Posted On
Feb 11, 2011Posted By
GabeHere’s one for MultipleDelete, should be a good addition to this post.
var md = new Packages.com.glide.db.MultipleDelete('incident');
md.addQuery('active', false);
md.setAllowCascadeDelete(); // optional: Allow cascading to records in other tables related to records being deleted
md.execute();
Posted On
Mar 31, 2011Posted By
bdr529*Fantastic* posting, Mark! Great to have all of these listed together – thanks!
Posted On
Aug 05, 2011Posted By
priscilla.yuenIn reference to the Or query – is there any documentation about what a QueryCondition object is, and what its other functions are?
Posted On
Aug 05, 2011Posted By
Mark Stanger@priscilla, there isn’t any other documentation about QueryCondition, but there’s really not much more to it either. The only real purpose of it is to enable you to add an ‘Or’ condition to a GlideRecord query. There are a couple more examples that I could probably share though. I’ll see if I can get something out next week.
Posted On
Sep 10, 2011Posted By
Jim CoyneA nice tip for the “addEncodedQuery” section: you can now right-click a Breadcrumb and select “Copy query” to get a copy of the encoded query.
Posted On
Oct 10, 2011Posted By
MikeIs there a way to get the display value from a SYS ID returned in a query?
example: I would like the below code to result in the display name for the requested_by and not the sys_id used to reference the user table.
var gr = new GlideRecord("change_request");
gr.addQuery('number', current.sysapproval);
gr.query();
while(gr.next()) {
Req = gr.requested_by;
}
Posted On
Oct 10, 2011Posted By
Mark StangerSince you’re dealing with a reference field you should be able to do something like this inside your while loop…
You can also just dot-walk to the field that contains the display value
Posted On
Oct 11, 2011Posted By
MikeThanks for the suggestions,
I’ve tried both and have listed the results of each below.
Returned the value “undefined”
Resulted in a script error “Object doesn’t support this property or method”
Posted On
Oct 12, 2011Posted By
Mark StangerYou’ve got another problem in your code…
should be...
gr.addQuery('sys_id', current.sysapproval);
Posted On
Oct 12, 2011Posted By
MikeAh, you are correct. I have corrected the query. Still, very odd when I use the following:
I get the sys_id that is in that reference field
When using
I still get “undefined”.
I will keep working at it. Thanks for your time and help.