关于 gliderecord-patterns
面向 ServiceNow 开发者的 GlideRecord 数据库操作实践指南,介绍查询、CRUD 和性能优化模式。还涵盖查询运算符及访问控制等安全注意事项。
主要功能
- 01展示单条及多条记录查询
- 02介绍编码查询和查询运算符
- 03涵盖插入、更新与删除操作
- 04提供限制查询开销的建议
- 05说明 ACL 与输入验证注意事项
适用场景
- 01查询 ServiceNow 表中的记录
- 02执行记录的增删改操作
- 03优化批量查询与计数
- 04检查脚本中的权限和输入处理
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ serac-labs/ serac --skill gliderecord-patterns安装后在 Claude Code 中输入/gliderecord-patterns确认已加载。
详细介绍
ServiceNow 的 GlideRecord 最佳实践
GlideRecord 是 ServiceNow 中用于数据库操作的主要 API。遵循这些模式可确保查询高效且安全。
基本查询模式
按 sys_id 获取单条记录
var gr = new GlideRecord("incident")
if (gr.get("sys_id_here")) {
gs.info("Found: " + gr.getValue("number"))
}
按字段获取单条记录
var gr = new GlideRecord("sys_user")
if (gr.get("user_name", "admin")) {
gs.info("Found user: " + gr.getValue("name"))
}
查询多条记录
var gr = new GlideRecord("incident")
gr.addQuery("active", true)
gr.addQuery("priority", "1")
gr.orderByDesc("sys_created_on")
gr.setLimit(100)
gr.query()
while (gr.next()) {
gs.info(gr.getValue("number"))
}
编码查询(更快)
对于复杂条件,请使用编码查询——它们比多次调用 addQuery 更高效:
var gr = new GlideRecord("incident")
// Encoded query from list view URL or Query Builder
gr.addEncodedQuery("active=true^priority=1^assigned_toISEMPTY")
gr.query()
while (gr.next()) {
// Process records
}
性能提示
1. 始终使用 setLimit()
// When you only need X records
var gr = new GlideRecord("incident")
gr.addQuery("active", true)
gr.setLimit(10) // Don't fetch more than needed
gr.query()
2. 对字符串使用 getValue()
// CORRECT - Returns string value
var number = gr.getValue("number")
// ALSO WORKS but returns GlideElement
var element = gr.number
var numberStr = gr.number.toString()
3. 对引用字段使用 getDisplayValue()
// Get the display value of a reference field
var assignedToName = gr.getDisplayValue("assigned_to")
// Get the sys_id of a reference field
var assignedToId = gr.getValue("assigned_to")
4. 避免在循环中查询
// BAD - Query inside loop
for (var i = 0; i < userIds.length; i++) {
var gr = new GlideRecord("sys_user")
gr.get(userIds[i]) // N queries!
}
// GOOD - Single query with IN clause
var gr = new GlideRecord("sys_user")
gr.addQuery("sys_id", "IN", userIds.join(","))
gr.query()
while (gr.next()) {
// Process all users at once
}
5. 使用 GlideAggregate 统计数量
// BAD - Counting with GlideRecord
var count = 0
var gr = new GlideRecord("incident")
gr.addQuery("active", true)
gr.query()
while (gr.next()) {
count++
}
// GOOD - Use GlideAggregate
var ga = new GlideAggregate("incident")
ga.addQuery("active", true)
ga.addAggregate("COUNT")
ga.query()
if (ga.next()) {
var count = ga.getAggregate("COUNT")
}
CRUD 操作
插入
var gr = new GlideRecord("incident")
gr.initialize()
gr.setValue("short_description", "New incident")
gr.setValue("caller_id", gs.getUserID())
gr.setValue("priority", "3")
var sysId = gr.insert()
更新
var gr = new GlideRecord("incident")
if (gr.get("sys_id_here")) {
gr.setValue("state", "6") // Resolved
gr.setValue("close_notes", "Issue fixed")
gr.update()
}
删除(谨慎使用!)
var gr = new GlideRecord("incident")
if (gr.get("sys_id_here")) {
gr.deleteRecord()
}
批量更新
var gr = new GlideRecord("incident")
gr.addQuery("state", "6") // Resolved
gr.addQuery("resolved_at", "<", gs.daysAgoStart(30))
gr.query()
while (gr.next()) {
gr.setValue("state", "7") // Closed
gr.update()
}
查询运算符
| 运算符 | 示例 | 说明 |
|---|---|---|
= | addQuery('active', true) | 等于 |
!= | addQuery('active', '!=', true) | 不等于 |
>, < | addQuery('priority', '<', '3') | 大于/小于 |
>=, <= | addQuery('sys_created_on', '>=', gs.daysAgoStart(7)) | 大于/小于或等于 |
CONTAINS | addQuery('short_description', 'CONTAINS', 'error') | 包含字符串 |
STARTSWITH | addQuery('number', 'STARTSWITH', 'INC') | 以……开头 |
ENDSWITH | addQuery('email', 'ENDSWITH', '@company.com') | 以……结尾 |
IN | addQuery('state', 'IN', '1,2,3') | 在列表中 |
NOT IN | addQuery('state', 'NOT IN', '6,7') | 不在列表中 |
ISEMPTY | addQuery('assigned_to', 'ISEMPTY', '') | 字段为空 |
ISNOTEMPTY | addQuery('assigned_to', 'ISNOTEMPTY', '') | 字段不为空 |
安全注意事项
- setWorkflow(false) - 批量操作时跳过业务规则
- setLimit() - 防止查询失控
- 检查 canRead()/canWrite() - 验证 ACL 权限
- 切勿信任用户输入 - 在查询中使用前先进行验证
评论
支持 Markdown