mcpField
G
glide-api-reference

glide-api-reference

github.com/happy-technologies-llc開発4142 回インストール2 日前に更新
リポジトリ

glide-api-reference について

glide-api-referenceは、サーバーサイドJavaScriptを書くServiceNow開発者向けのAPIリファレンススキルです。レコード、集計、日時、システムコンテキストなどのGlide APIを扱います。

主な機能

  1. 01GlideRecordの検索とレコード操作
  2. 02GlideAggregateの計算とグループ化
  3. 03日付と期間の処理
  4. 04GlideSystemとユーザーコンテキストのメソッド
  5. 05JSONおよびXMLユーティリティ

活用シーン

  1. 01ServiceNowのBusiness Rules作成
  2. 02Script IncludesやScheduled Jobsの構築
  3. 03ServiceNowレコードの検索と更新
  4. 04インシデントデータの集計

MCP 対応

SN-Query-Table MCPツールでServiceNowのテーブルを検索する例が含まれています。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/happy-technologies-llc/happy-platform-skills --skill glide-api-reference

インストール後、Claude Code で/glide-api-referenceを入力して読み込まれたか確認します。

詳細

Glide API リファレンス

概要

このスキルでは、ServiceNow のサーバーサイド Glide API を包括的に解説します。

  • GlideRecord - レコードのクエリ、挿入、更新、削除
  • GlideAggregate - 集計処理(COUNT、SUM、AVG など)の実行
  • GlideDateTime/GlideDuration - 日付と時刻の操作
  • GlideSystem (gs.*) - システムユーティリティとユーザーコンテキスト
  • GlideUser - 現在のユーザー情報
  • GlideSession - セッション管理
  • GlideElement - フィールドレベルのメソッド
  • GlideEncrypter - 暗号化ユーティリティ
  • JSON/XML utilities - データ変換

使用するタイミング: Business Rule、Script Include、Scheduled Job、UI Action、または ServiceNow のサーバーサイドスクリプトを作成する場合。

対象ユーザー: Glide API のクイックリファレンスを必要とする、あらゆるレベルの ServiceNow 開発者。

前提条件

  • ロール: コンテキストによって異なります(バックグラウンドスクリプトでは admin、レコード更新では itil)
  • 知識: JavaScript の基礎、ServiceNow のデータモデル
  • アクセス: アクセス対象のレコードに対する適切なテーブル ACL

手順

以下のセクションでは、包括的な API リファレンスと使用パターンを紹介します。

GlideRecord API

GlideRecord は、ServiceNow でデータベース操作を行うための主要な API です。

基本的なクエリパターン
var gr = new GlideRecord('incident');
gr.addQuery('active', true);
gr.addQuery('priority', 1);
gr.query();

while (gr.next()) {
    gs.info('Incident: ' + gr.number + ' - ' + gr.short_description);
}
クエリメソッド
メソッド説明例
addQuery(field, value)等しい条件gr.addQuery('active', true)
addQuery(field, operator, value)比較条件gr.addQuery('priority', '<=', 2)
addEncodedQuery(query)エンコード済みクエリ文字列gr.addEncodedQuery('active=true^priority=1')
addNotNullQuery(field)フィールドが空ではないgr.addNotNullQuery('assigned_to')
addNullQuery(field)フィールドが空gr.addNullQuery('resolution_notes')
addOrCondition(field, value)OR 条件以下の例を参照
query()クエリを実行gr.query()
クエリ演算子
演算子説明例
=等しい(デフォルト)addQuery('state', 1)
!=等しくないaddQuery('state', '!=', 6)
>より大きいaddQuery('priority', '>', 1)
>=以上addQuery('sys_created_on', '>=', gs.daysAgo(7))
<より小さいaddQuery('priority', '<', 3)
<=以下addQuery('sys_updated_on', '<=', gs.daysAgo(30))
STARTSWITH文字列で始まるaddQuery('number', 'STARTSWITH', 'INC')
ENDSWITH文字列で終わるaddQuery('short_description', 'ENDSWITH', 'error')
CONTAINS文字列を含むaddQuery('description', 'CONTAINS', 'network')
DOES NOT CONTAIN含まないaddQuery('description', 'DOES NOT CONTAIN', 'test')
IN値のリストに含まれるaddQuery('state', 'IN', '1,2,3')
NOT IN値のリストに含まれないaddQuery('priority', 'NOT IN', '4,5')
INSTANCEOFテーブル階層addQuery('sys_class_name', 'INSTANCEOF', 'cmdb_ci')
OR 条件
var gr = new GlideRecord('incident');
var qc = gr.addQuery('priority', 1);
qc.addOrCondition('priority', 2);
gr.query();
// Equivalent to: priority=1^ORpriority=2
複雑なクエリの例
var gr = new GlideRecord('incident');
gr.addQuery('active', true);
gr.addQuery('priority', '<=', 2);
gr.addNotNullQuery('assigned_to');
gr.addQuery('sys_created_on', '>=', gs.daysAgo(30));

// OR condition group
var qc = gr.addQuery('category', 'network');
qc.addOrCondition('category', 'hardware');

gr.orderByDesc('priority');
gr.orderBy('sys_created_on');
gr.setLimit(100);
gr.query();
挿入操作
// Basic insert
var gr = new GlideRecord('incident');
gr.initialize();
gr.short_description = 'New incident from script';
gr.description = 'Detailed description here';
gr.caller_id = gs.getUserID();
gr.priority = 3;
gr.category = 'inquiry';
var sysId = gr.insert();

gs.info('Created incident: ' + gr.number + ' (sys_id: ' + sysId + ')');
フィールド検証を伴う挿入
var gr = new GlideRecord('incident');
gr.initialize();

// Check if field is valid before setting
if (gr.isValidField('custom_field')) {
    gr.custom_field = 'value';
}

// Use setValue for reference fields (safer)
gr.setValue('assignment_group', 'a715cd759f2002002920bde8132e7018');
gr.setValue('assigned_to', gs.getUserID());

var sysId = gr.insert();
更新操作
// Update single record by sys_id
var gr = new GlideRecord('incident');
if (gr.get('a1b2c3d4e5f6...')) {
    gr.state = 2;  // In Progress
    gr.work_notes = 'Automated update via script';
    gr.update();
    gs.info('Updated: ' + gr.number);
}
一括更新パターン
// Update multiple records matching query
var gr = new GlideRecord('incident');
gr.addQuery('active', true);
gr.addQuery('priority', 1);
gr.addNullQuery('assigned_to');
gr.query();

var count = 0;
while (gr.next()) {
    gr.assignment_group = 'Critical Incidents Team';
    gr.work_notes = 'Auto-assigned to critical team';
    gr.update();
    count++;
}

gs.info('Updated ' + count + ' incidents');
削除操作
// Delete single record
var gr = new GlideRecord('sys_user_preference');
if (gr.get('sys_id_here')) {
    gr.deleteRecord();
}

// Delete multiple records (USE WITH CAUTION!)
var gr = new GlideRecord('temp_import_table');
gr.addQuery('sys_created_on', '<', gs.daysAgo(30));
gr.deleteMultiple();  // Deletes ALL matching records
ナビゲーションメソッド
メソッド説明
next()次のレコードに移動し、存在する場合は true を返します
hasNext()さらにレコードがあるか確認します(位置は進みません)
get(sysId)sys_id でレコードを取得します
get(field, value)フィールド値でレコードを取得します
getRowCount()クエリ結果のレコード総数
件数制限とウィンドウ処理
// Limit results
gr.setLimit(10);

// Pagination with chooseWindow
gr.chooseWindow(0, 100);    // First 100 records
gr.chooseWindow(100, 200);  // Records 101-200

// Order results
gr.orderBy('priority');       // Ascending
gr.orderByDesc('sys_created_on');  // Descending
レコード状態メソッド
メソッド説明
isNewRecord()レコードがまだ挿入されていない場合は True
isValidRecord()現在のレコードが有効な場合は True
isValidField(field)フィールドがテーブルに存在する場合は True
canRead()ユーザーがレコードを読み取れる場合は True
canWrite()ユーザーがレコードに書き込める場合は True
canCreate()ユーザーがレコードを作成できる場合は True
canDelete()ユーザーがレコードを削除できる場合は True
changes()いずれかのフィールドが変更されている場合は True
MCP ツールの使用
Tool: SN-Query-Table
Parameters:
  table_name: incident
  query: active=true^priority=1
  fields: sys_id,number,short_description,state,priority
  limit: 10

GlideAggregate API

GlideAggregate は、データベースレベルで集計処理を効率的に実行します。

基本的な COUNT
var ga = new GlideAggregate('incident');
ga.addQuery('active', true);
ga.addAggregate('COUNT');
ga.query();

if (ga.next()) {
    var count = ga.getAggregate('COUNT');
    gs.info('Active incidents: ' + count);
}
集計関数
関数説明例
COUNTレコード数を数えるga.addAggregate('COUNT')
SUM数値フィールドの合計ga.addAggregate('SUM', 'actual_hours')
AVGフィールドの平均ga.addAggregate('AVG', 'priority')
MIN最小値ga.addAggregate('MIN', 'sys_created_on')
MAX最大値ga.addAggregate('MAX', 'priority')
GROUP BY 操作
// Count incidents by priority
var ga = new GlideAggregate('incident');
ga.addQuery('active', true);
ga.addAggregate('COUNT');
ga.groupBy('priority');
ga.query();

while (ga.next()) {
    var priority = ga.priority;
    var count = ga.getAggregate('COUNT');
    gs.info('Priority ' + priority + ': ' + count + ' incidents');
}
複数の集計
// Get count and average time per category
var ga = new GlideAggregate('incident');
ga.addQuery('active', true);
ga.addAggregate('COUNT');
ga.addAggregate('AVG', 'reassignment_count');
ga.groupBy('category');
ga.orderByAggregate('COUNT');  // Order by count
ga.query();

while (ga.next()) {
    gs.info(ga.category + ': ' +
            ga.getAggregate('COUNT') + ' incidents, ' +
            'avg reassignments: ' + ga.getAggregate('AVG', 'reassignment_count'));
}
Having 句(集計結果のフィルタリング)
// Categories with more than 10 incidents
var ga = new GlideAggregate('incident');
ga.addQuery('active', true);
ga.addAggregate('COUNT');
ga.groupBy('category');
ga.addHaving('COUNT', '>', 10);
ga.query();
傾向分析パターン
// Incidents created per day over last 7 days
var ga = new GlideAggregate('incident');
ga.addQuery('sys_created_on', '>=', gs.daysAgo(7));
ga.addAggregate('COUNT');
ga.addTrend('sys_created_on', 'Day');
ga.query();

while (ga.next()) {
    var date = ga.getValue('timeref');
    var count = ga.getAggregate('COUNT');
    gs.info(date + ': ' + count + ' incidents created');
}

GlideDateTime API

GlideDateTime は、タイムゾーンを考慮した日付と時刻の操作を処理します。

GlideDateTime オブジェクトの作成
// Current date/time
var gdt = new GlideDateTime();

// From string (UTC format)
var gdt = new GlideDateTime('2026-02-06 12:00:00');

// Copy existing
var gdt2 = new GlideDateTime(gdt);
値の取得
メソッド説明出力例
getValue()内部値(UTC)2026-02-06 12:00:00
getDisplayValue()ユーザーのタイムゾーン2026-02-06 04:00:00
getDate()日付部分2026-02-06
getTime()時刻部分12:00:00
getNumericValue()エポックからのミリ秒数1770465600000
getDayOfWeek()曜日番号(1=月曜)5(金曜)
getDayOfMonth()月内の日6
getMonthUTC()月(1~12)2
getYearUTC()年2026
値の設定
var gdt = new GlideDateTime();

// Set from string
gdt.setValue('2026-12-25 00:00:00');

// Set display value (user timezone)
gdt.setDisplayValue('2026-12-25 00:00:00');

// Set components
gdt.setYearUTC(2026);
gdt.setMonthUTC(12);
gdt.setDayOfMonthUTC(25);
日付の算術演算
var gdt = new GlideDateTime();

// Add time
gdt.addSeconds(60);
gdt.addMinutes(30);
gdt.addHours(2);
gdt.addDays(7);
gdt.addMonths(1);
gdt.addYears(1);

// Add GlideDuration
var duration = new GlideDuration('1 12:30:00');  // 1 day, 12 hours, 30 minutes
gdt.add(duration);

// Subtract
gdt.addDays(-7);  // 7 days ago
日付の比較
var gdt1 = new GlideDateTime('2026-02-06 12:00:00');
var gdt2 = new GlideDateTime('2026-02-07 12:00:00');

// Compare
if (gdt1.before(gdt2)) {
    gs.info('gdt1 is earlier');
}

if (gdt2.after(gdt1)) {
    gs.info('gdt2 is later');
}

if (gdt1.equals(gdt2)) {
    gs.info('Same date/time');
}

// Get difference
var diff = GlideDateTime.subtract(gdt1, gdt2);
gs.info('Difference: ' + diff.getDisplayValue());  // Duration
よく使われる日付パターン
// Start of today
var startOfDay = new GlideDateTime();
startOfDay.setDisplayValue(startOfDay.getDate() + ' 00:00:00');

// End of today
var endOfDay = new GlideDateTime();
endOfDay.setDisplayValue(endOfDay.getDate() + ' 23:59:59');

// Beginning of month
var startOfMonth = new GlideDateTime();
startOfMonth.setDayOfMonthUTC(1);
startOfMonth.setDisplayValue(startOfMonth.getDate() + ' 00:00:00');

// Check if date is in future
function isFuture(dateField) {
    var now = new GlideDateTime();
    var target = new GlideDateTime(dateField);
    return target.after(now);
}

GlideDuration API

GlideDuration は、時間の長さを表します。

期間の作成
// From string (days hours:minutes:seconds)
var dur = new GlideDuration('1 12:30:00');  // 1 day, 12 hours, 30 minutes

// From milliseconds
var dur = new GlideDuration(86400000);  // 1 day in ms

// From two GlideDateTimes
var start = new GlideDateTime('2026-02-06 00:00:00');
var end = new GlideDateTime('2026-02-07 12:00:00');
var dur = GlideDateTime.subtract(start, end);
期間メソッド
メソッド説明
getValue()内部値
getDisplayValue()人が読みやすい形式
getNumericValue()ミリ秒
getDayPart()日の部分
getRoundedDayPart()四捨五入した日数
getDurationValue()期間文字列
期間の算術演算
var dur1 = new GlideDuration('1 00:00:00');  // 1 day
var dur2 = new GlideDuration('0 12:00:00');  // 12 hours

// Add
var total = dur1.add(dur2);  // 1 day 12 hours

// Subtract
var diff = dur1.subtract(dur2);  // 12 hours

// Compare
dur1.compareTo(dur2);  // -1, 0, or 1
営業時間を計算する
// Calculate business hours between two dates using schedule
var schedule = new GlideSchedule('08fcd0830a0a0b2600079f56b1adb9ae');  // 8-5 M-F
var startDate = new GlideDateTime('2026-02-06 09:00:00');
var endDate = new GlideDateTime('2026-02-07 17:00:00');

var duration = schedule.duration(startDate, endDate);
gs.info('Business duration: ' + duration.getDisplayValue());

GlideSystem(gs.*)メソッド

GlideSystem は、ユーティリティ関数とシステムコンテキストへのアクセスを提供します。

ユーザーコンテキスト
メソッド説明
gs.getUserID()現在のユーザーの sys_id
gs.getUserName()ユーザー名
gs.getUserDisplayName()氏名
gs.getUser()GlideUser オブジェクト
gs.hasRole(role)ユーザーのロールを確認
gs.hasRoleInGroup(role, group)グループ内のロールを確認
日付/時刻のショートカット
// Relative dates (return strings for queries)
gs.now();           // Current timestamp
gs.nowDateTime();   // Current date/time
gs.daysAgo(7);      // 7 days ago
gs.daysAgoStart(7); // Start of day 7 days ago
gs.daysAgoEnd(7);   // End of day 7 days ago
gs.hoursAgo(2);     // 2 hours ago
gs.minutesAgo(30);  // 30 minutes ago
gs.monthsAgo(1);    // 1 month ago
gs.yearsAgo(1);     // 1 year ago
gs.beginningOfLastMonth();
gs.endOfLastMonth();
gs.beginningOfThisMonth();
gs.beginningOfThisYear();
クエリの日付の例
// Incidents created in last 7 days
var gr = new GlideRecord('incident');
gr.addQuery('sys_created_on', '>=', gs.daysAgo(7));
gr.query();

// Using encoded query
gr.addEncodedQuery('sys_created_onONLast 7 days@javascript:gs.daysAgoStart(7)@javascript:gs.daysAgoEnd(0)');
ロギング
gs.info('Informational message');
gs.warn('Warning message');
gs.error('Error message');
gs.debug('Debug message');  // Only logged if debug enabled

// Include data in logs
gs.info('Processing incident: ' + current.number + ', State: ' + current.state);

// Log to specific source
gs.log('Custom log entry', 'MyScriptName');
システムプロパティ
// Get property
var value = gs.getProperty('glide.ui.session_timeout');
var valueWithDefault = gs.getProperty('custom.setting', 'default_value');

// Set property (requires admin)
gs.setProperty('custom.setting', 'new_value');
セッションとリクエスト
// Session data
gs.getSession().putClientData('key', 'value');
var data = gs.getSession().getClientData('key');

// URL parameters (in UI scripts)
gs.getUrlParameter('sysparm_record');

// Language
gs.getLanguage();  // e.g., 'en'
その他
// Generate GUID
var guid = gs.generateGUID();

// Nil/empty check
gs.nil('');     // true
gs.nil(null);   // true
gs.nil(false);  // false (has value)

// Get table label
gs.getTableLabel('incident');  // 'Incident'

// Check table exists
gs.tableExists('incident');  // true

// Get current scope
gs.getCurrentScopeName();  // 'global' or scope name

// Print (deprecated, use gs.info)
gs.print('message');  // Logs to system log

GlideUser API

GlideUser は、現在のユーザー情報を提供します。

var user = gs.getUser();

// User identification
user.getID();               // sys_id
user.getName();             // username
user.getDisplayName();      // full name
user.getEmail();            // email address
user.getFirstName();        // first name
user.getLastName();         // last name
user.getLocation();         // location sys_id
user.getDepartmentID();     // department sys_id
user.getCompanyID();        // company sys_id
user.getManagerID();        // manager sys_id

// Role checking
user.hasRole('admin');                    // true/false
user.hasRoleInGroup('itil', groupId);     // true/false
user.hasRoleExactly('admin');             // exact match, not elevated
user.getRoles();                          // array of roles

// Preference
user.getPreference('timezone');
user.savePreference('custom.pref', 'value');

// Delegation (impersonation)
user.isMemberOf(groupId);                 // check group membership

GlideSession API

GlideSession は、ユーザーセッションデータを管理します。

var session = gs.getSession();

// Session identification
session.getSessionToken();     // session token
session.getClientIP();         // client IP address
session.getCurrentApplicationId();  // current app scope

// Client data (persists during session)
session.putClientData('key', 'value');
var value = session.getClientData('key');

// Language
session.getLanguage();         // 'en', 'de', etc.

// Timezone
session.getTimeZoneName();     // e.g., 'America/Los_Angeles'

// Check if logged in
session.isLoggedIn();          // true/false

// Impersonation
session.isImpersonating();     // true if impersonating
session.getImpersonatingUserName();  // original user

GlideElement メソッド

GlideElement は、GlideRecord フィールドへのフィールドレベルのアクセスとメソッドを提供します。

値の取得
var gr = new GlideRecord('incident');
gr.get('sys_id_here');

// Different value methods
gr.short_description.toString();      // String value
gr.priority.getValue();               // Internal value
gr.priority.getDisplayValue();        // Display value
gr.assigned_to.getRefRecord();        // Get referenced record (GlideRecord)
gr.getDisplayValue();                 // Current record display value
gr.assigned_to.getReferenceTable();   // Referenced table name
参照フィールド
// Get reference value
var assignedTo = gr.assigned_to.getDisplayValue();  // User's name

// Get referenced record
var userGr = gr.assigned_to.getRefRecord();
if (userGr.isValidRecord()) {
    gs.info('Assigned to: ' + userGr.email);
}

// Check if reference is empty
if (gr.assigned_to.nil()) {
    gs.info('Not assigned');
}
フィールド状態メソッド
// Check if field changed (in business rules)
if (gr.state.changes()) {
    gs.info('State changed from ' + gr.state.getOldValue() + ' to ' + gr.state.getValue());
}

// Check for changes to specific value
if (gr.state.changesFrom('1')) {
    gs.info('State changed from New');
}

if (gr.state.changesTo('6')) {
    gs.info('State changed to Resolved');
}

// Get old value
var previousState = gr.state.getOldValue();
フィールド属性
// Get field metadata
var element = gr.getElement('short_description');
element.getLabel();           // Field label
element.getTableName();       // Table name
element.getED();              // Element descriptor

// Check field properties
element.canRead();            // User can read
element.canWrite();           // User can write
element.hasValue();           // Has non-null value
element.nil();                // Is null/empty
ジャーナルフィールド
// Work notes / comments
gr.work_notes = 'Adding a work note';
gr.comments = 'Adding a customer-visible comment';

// Get journal entries
var journal = gr.work_notes.getJournalEntry(1);  // Most recent
var allJournal = gr.work_notes.getJournalEntry(-1);  // All entries

GlideEncrypter API

GlideEncrypter は、暗号化およびハッシュ化のユーティリティを提供します。

var encrypter = new GlideEncrypter();

// One-way hash (MD5)
var hash = encrypter.encrypt('sensitive_data');

// Two-way encryption (for password fields)
var encrypted = new GlideEncrypter().encrypt('password123');

// Decrypt (if two-way)
var decrypted = new GlideEncrypter().decrypt(encrypted);
パスワードのハッシュ化
// Hash password (one-way)
var hashedPassword = GlideStringUtil.getStringFromStream(
    new GlideDigest().md5(password)
);

JSON および XML ユーティリティ

JSON 操作
// Parse JSON
var jsonString = '{"name":"John","age":30}';
var obj = JSON.parse(jsonString);
gs.info(obj.name);  // 'John'

// Stringify object
var data = { name: 'John', age: 30 };
var jsonStr = JSON.stringify(data);
var prettyJson = JSON.stringify(data, null, 2);

// Global JSON utility
var parser = new global.JSON();
var obj = parser.decode(jsonString);
var str = parser.encode(obj);

// In scoped apps
var obj = global.JSON.parse(jsonString);
var str = global.JSON.stringify(data);
GlideRecord での JSON
// Store JSON in field
gr.u_json_data = JSON.stringify({ key: 'value' });
gr.update();

// Retrieve JSON
var data = JSON.parse(gr.u_json_data);
XML ユーティリティ
// Create XML document
var xmlDoc = new XMLDocument('<root></root>');
var root = xmlDoc.getDocumentElement();
var child = xmlDoc.createElement('child');
child.setAttribute('attr', 'value');
root.appendChild(child);
var xmlString = xmlDoc.toString();

// Parse XML
var parser = new XMLDocument(xmlString);
var elements = parser.getElementByTagName('child');
XMLHelper
// Convert GlideRecord to XML
var gr = new GlideRecord('incident');
gr.get('sys_id_here');
var xml = new GlideRecordXMLSerializer(gr).serialize();

// Pretty print XML
var prettyXml = new global.XMLPrettyPrint().prettyPrint(xmlString);

よく使われるクエリパターン

パターン 1:単一レコードを効率的に検索する
// GOOD: Direct lookup
var gr = new GlideRecord('sys_user');
if (gr.get('user_name', 'admin')) {
    gs.info('Found: ' + gr.name);
}

// AVOID: Query with single result
var gr = new GlideRecord('sys_user');
gr.addQuery('user_name', 'admin');
gr.setLimit(1);
gr.query();
if (gr.next()) {
    gs.info('Found: ' + gr.name);
}
パターン 2:レコードの存在を確認する
// Efficient existence check
function recordExists(table, field, value) {
    var gr = new GlideRecord(table);
    gr.addQuery(field, value);
    gr.setLimit(1);
    gr.query();
    return gr.hasNext();
}

// Usage
if (recordExists('sys_user', 'user_name', 'admin')) {
    gs.info('User exists');
}
パターン 3:参照フィールドから値を取得する
// Get value from referenced record
var gr = new GlideRecord('incident');
gr.get('sys_id_here');

// Direct dot-walk (generates extra query)
var callerEmail = gr.caller_id.email;

// More efficient for multiple fields
var callerGr = gr.caller_id.getRefRecord();
if (callerGr.isValidRecord()) {
    var email = callerGr.email;
    var phone = callerGr.phone;
    var dept = callerGr.department.getDisplayValue();
}
パターン 4:バッチ処理
// Process records in batches to avoid memory issues
function processInBatches(table, query, batchSize, callback) {
    var offset = 0;
    var hasMore = true;

    while (hasMore) {
        var gr = new GlideRecord(table);
        gr.addEncodedQuery(query);
        gr.chooseWindow(offset, offset + batchSize);
        gr.query();

        var count = 0;
        while (gr.next()) {
            callback(gr);
            count++;
        }

        hasMore = (count === batchSize);
        offset += batchSize;

        gs.info('Processed batch: ' + offset);
    }
}

// Usage
processInBatches('incident', 'active=true', 1000, function(gr) {
    // Process each record
    gr.work_notes = 'Batch processed';
    gr.update();
});
パターン 5:参照を安全に設定する
// Resolve reference by name
function getUserSysId(username) {
    var gr = new GlideRecord('sys_user');
    if (gr.get('user_name', username)) {
        return gr.sys_id.toString();
    }
    return null;
}

// Usage
var gr = new GlideRecord('incident');
gr.initialize();
var userId = getUserSysId('admin');
if (userId) {
    gr.setValue('assigned_to', userId);
} else {
    gs.warn('User not found: admin');
}
gr.insert();
パターン 6:条件付き更新(変更がある場合のみ)
var gr = new GlideRecord('incident');
gr.get('sys_id_here');

var changed = false;

// Only update if different
if (gr.priority != 2) {
    gr.priority = 2;
    changed = true;
}

if (gr.state != 2) {
    gr.state = 2;
    changed = true;
}

if (changed) {
    gr.update();
    gs.info('Record updated');
} else {
    gs.info('No changes needed');
}

MCP ツールを使用した Glide の操作

MCP でクエリを実行する
Tool: SN-Query-Table
Parameters:
  table_name: incident
  query: active=true^priority<=2
  fields: sys_id,number,short_description,state,priority,assigned_to
  limit: 50
MCP でスクリプトを実行する
Tool: SN-Execute-Background-Script
Parameters:
  script: |
    // Count incidents by priority
    var results = {};

    var ga = new GlideAggregate('incident');
    ga.addQuery('active', true);
    ga.addAggregate('COUNT');
    ga.groupBy('priority');
    ga.query();

    while (ga.next()) {
      results['P' + ga.priority] = ga.getAggregate('COUNT');
    }

    gs.info('Incident counts: ' + JSON.stringify(results));
  description: Count active incidents by priority
MCP でレコードを作成する
Tool: SN-Create-Record
Parameters:
  table_name: incident
  data:
    short_description: Created via MCP
    description: Detailed description
    caller_id: [user_sys_id]
    priority: 3
    category: inquiry

ベストプラクティス

  • 件数の集計には GlideAggregate を使用します - レコード数を数えるだけの目的で、GlideRecord を使ってレコードを反復処理しないでください
  • 上限を設定します - クエリの暴走を防ぐため、必ず setLimit() を使用してください
  • エンコードクエリを使用します - 複数の addQuery() 呼び出しより効率的です
  • ループ内でのドットウォーキングを避けます - 参照の検索結果をループの外でキャッシュしてください
  • 権限を確認します - 操作の前に canRead()、canWrite() を使用してください
  • 参照には setValue を使用します - 直接代入するより安全です
  • null の参照を処理します - アクセスする前に gr.field.nil() を確認してください
  • 操作をログに記録します - デバッグできるよう、ログに識別可能な情報を含めてください
  • まずクエリをテストします - MCP の SN-Query-Table を使用して、クエリのロジックを確認してください

トラブルシューティング

クエリで結果が返されない

症状: GlideRecord クエリが何も返しません
原因:

  • クエリ構文が正しくありません
  • ACL によってアクセスがブロックされています
  • データが条件に一致していません 解決方法:
// Debug query
gs.info('Query: ' + gr.getEncodedQuery());
gs.info('Row count: ' + gr.getRowCount());
参照フィールドに sys_id が表示される

症状: 参照フィールドに名前ではなく sys_id が表示されます
原因: getDisplayValue() ではなく getValue() を使用しています
解決方法:

// WRONG
var name = gr.assigned_to.getValue();  // Returns sys_id

// RIGHT
var name = gr.assigned_to.getDisplayValue();  // Returns name
ビジネスルールで変更が検出されない

症状: gr.field.changes() が予期せず false を返します
原因: 確認するフィールド、または比較する値が間違っています
解決方法:

// Debug changes
gs.info('Field changes: ' + gr.state.changes());
gs.info('Old value: ' + gr.state.getOldValue());
gs.info('New value: ' + gr.state.getValue());

関連スキル

  • admin/script-execution - バックグラウンドスクリプトの実行パターン
  • admin/batch-operations - レコードの一括操作
  • development/business-rules - ビジネスルールの開発(近日公開)
  • development/script-includes - 再利用可能なスクリプトのパターン(近日公開)

参考資料

コメント