data-policies
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseData Policies & Dictionary for ServiceNow
ServiceNow 数据策略与字典
Data Policies enforce data integrity rules. Dictionary controls schema and field behavior.
数据策略用于强制执行数据完整性规则,字典用于控制表结构与字段行为。
Architecture
架构
Dictionary (sys_dictionary)
├── Field Definition
│ ├── Type, Length, Default
│ └── Dependent Field
└── Dictionary Overrides (sys_dictionary_override)
Data Policy (sys_data_policy2)
└── Data Policy Rules (sys_data_policy_rule)
└── Condition-based field behaviorsDictionary (sys_dictionary)
├── Field Definition
│ ├── Type, Length, Default
│ └── Dependent Field
└── Dictionary Overrides (sys_dictionary_override)
Data Policy (sys_data_policy2)
└── Data Policy Rules (sys_data_policy_rule)
└── Condition-based field behaviorsKey Tables
核心表
| Table | Purpose |
|---|---|
| Field definitions |
| Scoped overrides |
| Data policies |
| Policy rules |
| Table definitions |
| 表名 | 用途 |
|---|---|
| 字段定义 |
| 作用域覆盖配置 |
| 数据策略 |
| 策略规则 |
| 表定义 |
Dictionary Management (ES5)
字典管理(仅支持ES5)
Create Table
创建表
javascript
// Create custom table (ES5 ONLY!)
var table = new GlideRecord('sys_db_object');
table.initialize();
table.setValue('name', 'u_custom_table');
table.setValue('label', 'Custom Table');
table.setValue('super_class', 'task'); // Extends task
table.setValue('is_extendable', true);
table.setValue('create_access_controls', true);
table.setValue('live_feed_enabled', false);
table.insert();javascript
// Create custom table (ES5 ONLY!)
var table = new GlideRecord('sys_db_object');
table.initialize();
table.setValue('name', 'u_custom_table');
table.setValue('label', 'Custom Table');
table.setValue('super_class', 'task'); // Extends task
table.setValue('is_extendable', true);
table.setValue('create_access_controls', true);
table.setValue('live_feed_enabled', false);
table.insert();Create Field
创建字段
javascript
// Create field on table (ES5 ONLY!)
var field = new GlideRecord('sys_dictionary');
field.initialize();
// Table and element
field.setValue('name', 'u_custom_table');
field.setValue('element', 'u_customer_name');
// Field properties
field.setValue('column_label', 'Customer Name');
field.setValue('internal_type', 'string');
field.setValue('max_length', 100);
field.setValue('mandatory', false);
field.setValue('read_only', false);
field.setValue('display', false);
field.setValue('active', true);
// Default value
field.setValue('default_value', '');
// Reference field specific
// field.setValue('reference', 'customer_account');
// field.setValue('reference_qual', 'active=true');
field.insert();javascript
// Create field on table (ES5 ONLY!)
var field = new GlideRecord('sys_dictionary');
field.initialize();
// Table and element
field.setValue('name', 'u_custom_table');
field.setValue('element', 'u_customer_name');
// Field properties
field.setValue('column_label', 'Customer Name');
field.setValue('internal_type', 'string');
field.setValue('max_length', 100);
field.setValue('mandatory', false);
field.setValue('read_only', false);
field.setValue('display', false);
field.setValue('active', true);
// Default value
field.setValue('default_value', '');
// Reference field specific
// field.setValue('reference', 'customer_account');
// field.setValue('reference_qual', 'active=true');
field.insert();Field Types
字段类型
javascript
// Common field types
var FIELD_TYPES = {
STRING: 'string',
INTEGER: 'integer',
DECIMAL: 'decimal',
BOOLEAN: 'boolean',
GLIDE_DATE: 'glide_date',
GLIDE_DATE_TIME: 'glide_date_time',
REFERENCE: 'reference',
CHOICE: 'choice',
JOURNAL: 'journal',
JOURNAL_INPUT: 'journal_input',
HTML: 'html',
URL: 'url',
EMAIL: 'email',
SCRIPT: 'script',
CONDITIONS: 'conditions'
};
// Create different field types (ES5 ONLY!)
function createField(tableName, fieldDef) {
var field = new GlideRecord('sys_dictionary');
field.initialize();
field.setValue('name', tableName);
field.setValue('element', fieldDef.name);
field.setValue('column_label', fieldDef.label);
field.setValue('internal_type', fieldDef.type);
if (fieldDef.maxLength) {
field.setValue('max_length', fieldDef.maxLength);
}
if (fieldDef.reference) {
field.setValue('reference', fieldDef.reference);
}
if (fieldDef.choices) {
field.setValue('choice', 1); // Has choices
}
return field.insert();
}javascript
// Common field types
var FIELD_TYPES = {
STRING: 'string',
INTEGER: 'integer',
DECIMAL: 'decimal',
BOOLEAN: 'boolean',
GLIDE_DATE: 'glide_date',
GLIDE_DATE_TIME: 'glide_date_time',
REFERENCE: 'reference',
CHOICE: 'choice',
JOURNAL: 'journal',
JOURNAL_INPUT: 'journal_input',
HTML: 'html',
URL: 'url',
EMAIL: 'email',
SCRIPT: 'script',
CONDITIONS: 'conditions'
};
// Create different field types (ES5 ONLY!)
function createField(tableName, fieldDef) {
var field = new GlideRecord('sys_dictionary');
field.initialize();
field.setValue('name', tableName);
field.setValue('element', fieldDef.name);
field.setValue('column_label', fieldDef.label);
field.setValue('internal_type', fieldDef.type);
if (fieldDef.maxLength) {
field.setValue('max_length', fieldDef.maxLength);
}
if (fieldDef.reference) {
field.setValue('reference', fieldDef.reference);
}
if (fieldDef.choices) {
field.setValue('choice', 1); // Has choices
}
return field.insert();
}Create Choices
创建选项列表
javascript
// Create choice list values (ES5 ONLY!)
function createChoices(tableName, fieldName, choices) {
for (var i = 0; i < choices.length; i++) {
var choice = new GlideRecord('sys_choice');
choice.initialize();
choice.setValue('name', tableName);
choice.setValue('element', fieldName);
choice.setValue('value', choices[i].value);
choice.setValue('label', choices[i].label);
choice.setValue('sequence', (i + 1) * 10);
choice.setValue('inactive', false);
choice.insert();
}
}
// Usage
createChoices('incident', 'u_custom_status', [
{ value: 'pending', label: 'Pending Review' },
{ value: 'approved', label: 'Approved' },
{ value: 'rejected', label: 'Rejected' }
]);javascript
// Create choice list values (ES5 ONLY!)
function createChoices(tableName, fieldName, choices) {
for (var i = 0; i < choices.length; i++) {
var choice = new GlideRecord('sys_choice');
choice.initialize();
choice.setValue('name', tableName);
choice.setValue('element', fieldName);
choice.setValue('value', choices[i].value);
choice.setValue('label', choices[i].label);
choice.setValue('sequence', (i + 1) * 10);
choice.setValue('inactive', false);
choice.insert();
}
}
// Usage
createChoices('incident', 'u_custom_status', [
{ value: 'pending', label: 'Pending Review' },
{ value: 'approved', label: 'Approved' },
{ value: 'rejected', label: 'Rejected' }
]);Dictionary Overrides (ES5)
字典覆盖配置(仅支持ES5)
Create Override
创建覆盖规则
javascript
// Create dictionary override for scoped app (ES5 ONLY!)
var override = new GlideRecord('sys_dictionary_override');
override.initialize();
// Reference the base field
override.setValue('base_table', 'task');
override.setValue('base_element', 'short_description');
// Target table
override.setValue('name', 'u_custom_table');
// Override properties
override.setValue('column_label', 'Request Summary');
override.setValue('mandatory', true);
override.setValue('read_only', false);
override.setValue('max_length', 200);
// Default value override
override.setValue('default_value', '');
override.insert();javascript
// Create dictionary override for scoped app (ES5 ONLY!)
var override = new GlideRecord('sys_dictionary_override');
override.initialize();
// Reference the base field
override.setValue('base_table', 'task');
override.setValue('base_element', 'short_description');
// Target table
override.setValue('name', 'u_custom_table');
// Override properties
override.setValue('column_label', 'Request Summary');
override.setValue('mandatory', true);
override.setValue('read_only', false);
override.setValue('max_length', 200);
// Default value override
override.setValue('default_value', '');
override.insert();Data Policies (ES5)
数据策略(仅支持ES5)
Create Data Policy
创建数据策略
javascript
// Create data policy (ES5 ONLY!)
var policy = new GlideRecord('sys_data_policy2');
policy.initialize();
policy.setValue('model_table', 'incident');
policy.setValue('short_description', 'Resolution Fields Required on Resolve');
policy.setValue('active', true);
// Conditions - when policy applies
policy.setValue('conditions', 'state=6'); // Resolved state
// Apply to forms
policy.setValue('apply_to_client', true);
policy.setValue('apply_to_import_sets', true);
policy.setValue('apply_to_soap', true);
// Reverse
policy.setValue('reverse_if_false', true);
var policySysId = policy.insert();
// Add policy rules
addDataPolicyRule(policySysId, 'resolution_code', true, false, false);
addDataPolicyRule(policySysId, 'close_notes', true, false, false);javascript
// Create data policy (ES5 ONLY!)
var policy = new GlideRecord('sys_data_policy2');
policy.initialize();
policy.setValue('model_table', 'incident');
policy.setValue('short_description', 'Resolution Fields Required on Resolve');
policy.setValue('active', true);
// Conditions - when policy applies
policy.setValue('conditions', 'state=6'); // Resolved state
// Apply to forms
policy.setValue('apply_to_client', true);
policy.setValue('apply_to_import_sets', true);
policy.setValue('apply_to_soap', true);
// Reverse
policy.setValue('reverse_if_false', true);
var policySysId = policy.insert();
// Add policy rules
addDataPolicyRule(policySysId, 'resolution_code', true, false, false);
addDataPolicyRule(policySysId, 'close_notes', true, false, false);Add Policy Rules
添加策略规则
javascript
// Add data policy rule (ES5 ONLY!)
function addDataPolicyRule(policySysId, fieldName, mandatory, readOnly, hidden) {
var rule = new GlideRecord('sys_data_policy_rule');
rule.initialize();
rule.setValue('sys_data_policy', policySysId);
rule.setValue('field', fieldName);
rule.setValue('mandatory', mandatory);
rule.setValue('read_only', readOnly);
rule.setValue('visible', !hidden);
return rule.insert();
}javascript
// Add data policy rule (ES5 ONLY!)
function addDataPolicyRule(policySysId, fieldName, mandatory, readOnly, hidden) {
var rule = new GlideRecord('sys_data_policy_rule');
rule.initialize();
rule.setValue('sys_data_policy', policySysId);
rule.setValue('field', fieldName);
rule.setValue('mandatory', mandatory);
rule.setValue('read_only', readOnly);
rule.setValue('visible', !hidden);
return rule.insert();
}Complex Data Policy
复杂数据策略
javascript
// Data policy with scripted condition (ES5 ONLY!)
var policy = new GlideRecord('sys_data_policy2');
policy.initialize();
policy.setValue('model_table', 'change_request');
policy.setValue('short_description', 'High Risk Change Requirements');
policy.setValue('active', true);
// Use scripted condition for complex logic
policy.setValue('use_as_condition', true);
policy.setValue('script',
'(function checkCondition(current) {\n' +
' // High risk changes require additional fields\n' +
' if (current.risk == "high") {\n' +
' return true;\n' +
' }\n' +
' \n' +
' // Also apply to changes affecting critical CIs\n' +
' if (current.cmdb_ci) {\n' +
' var ci = current.cmdb_ci.getRefRecord();\n' +
' if (ci.business_criticality == "1 - most critical") {\n' +
' return true;\n' +
' }\n' +
' }\n' +
' \n' +
' return false;\n' +
'})(current);'
);
var policySysId = policy.insert();
// Require additional documentation for high risk
addDataPolicyRule(policySysId, 'implementation_plan', true, false, false);
addDataPolicyRule(policySysId, 'backout_plan', true, false, false);
addDataPolicyRule(policySysId, 'test_plan', true, false, false);
addDataPolicyRule(policySysId, 'justification', true, false, false);javascript
// Data policy with scripted condition (ES5 ONLY!)
var policy = new GlideRecord('sys_data_policy2');
policy.initialize();
policy.setValue('model_table', 'change_request');
policy.setValue('short_description', 'High Risk Change Requirements');
policy.setValue('active', true);
// Use scripted condition for complex logic
policy.setValue('use_as_condition', true);
policy.setValue('script',
'(function checkCondition(current) {\n' +
' // High risk changes require additional fields\n' +
' if (current.risk == "high") {\n' +
' return true;\n' +
' }\n' +
' \n' +
' // Also apply to changes affecting critical CIs\n' +
' if (current.cmdb_ci) {\n' +
' var ci = current.cmdb_ci.getRefRecord();\n' +
' if (ci.business_criticality == "1 - most critical") {\n' +
' return true;\n' +
' }\n' +
' }\n' +
' \n' +
' return false;\n' +
'})(current);'
);
var policySysId = policy.insert();
// Require additional documentation for high risk
addDataPolicyRule(policySysId, 'implementation_plan', true, false, false);
addDataPolicyRule(policySysId, 'backout_plan', true, false, false);
addDataPolicyRule(policySysId, 'test_plan', true, false, false);
addDataPolicyRule(policySysId, 'justification', true, false, false);Field Validation (ES5)
字段验证(仅支持ES5)
Dictionary Attribute Validation
字典属性验证
javascript
// Add validation to dictionary field (ES5 ONLY!)
var field = new GlideRecord('sys_dictionary');
if (field.get('name', 'incident').get('element', 'u_email')) {
// Add regex validation
field.setValue('attributes', 'validate=email');
field.update();
}
// Common validation attributes
var VALIDATION_ATTRIBUTES = {
EMAIL: 'validate=email',
PHONE: 'validate=phone_number',
URL: 'validate=url',
CUSTOM: 'validate=script' // Uses script in Calculated Value
};javascript
// Add validation to dictionary field (ES5 ONLY!)
var field = new GlideRecord('sys_dictionary');
if (field.get('name', 'incident').get('element', 'u_email')) {
// Add regex validation
field.setValue('attributes', 'validate=email');
field.update();
}
// Common validation attributes
var VALIDATION_ATTRIBUTES = {
EMAIL: 'validate=email',
PHONE: 'validate=phone_number',
URL: 'validate=url',
CUSTOM: 'validate=script' // Uses script in Calculated Value
};Script Validation
脚本验证
javascript
// Calculated field with validation (ES5 ONLY!)
// Set in Dictionary > Calculated Value
// Check phone format
(function calculate() {
var phone = current.getValue('u_phone');
if (!phone) return '';
// Format validation
var phonePattern = /^\+?[1-9]\d{1,14}$/;
if (!phonePattern.test(phone.replace(/[\s\-\(\)]/g, ''))) {
gs.addErrorMessage('Invalid phone number format');
return '';
}
return phone;
})();javascript
// Calculated field with validation (ES5 ONLY!)
// Set in Dictionary > Calculated Value
// Check phone format
(function calculate() {
var phone = current.getValue('u_phone');
if (!phone) return '';
// Format validation
var phonePattern = /^\+?[1-9]\d{1,14}$/;
if (!phonePattern.test(phone.replace(/[\s\-\(\)]/g, ''))) {
gs.addErrorMessage('Invalid phone number format');
return '';
}
return phone;
})();Schema Queries (ES5)
结构查询(仅支持ES5)
Get Table Fields
获取表字段
javascript
// Get all fields for a table (ES5 ONLY!)
function getTableFields(tableName) {
var fields = [];
var dict = new GlideRecord('sys_dictionary');
dict.addQuery('name', tableName);
dict.addQuery('internal_type', '!=', 'collection');
dict.addQuery('active', true);
dict.orderBy('element');
dict.query();
while (dict.next()) {
fields.push({
name: dict.getValue('element'),
label: dict.getValue('column_label'),
type: dict.getValue('internal_type'),
mandatory: dict.getValue('mandatory') === 'true',
reference: dict.getValue('reference'),
maxLength: dict.getValue('max_length')
});
}
return fields;
}javascript
// Get all fields for a table (ES5 ONLY!)
function getTableFields(tableName) {
var fields = [];
var dict = new GlideRecord('sys_dictionary');
dict.addQuery('name', tableName);
dict.addQuery('internal_type', '!=', 'collection');
dict.addQuery('active', true);
dict.orderBy('element');
dict.query();
while (dict.next()) {
fields.push({
name: dict.getValue('element'),
label: dict.getValue('column_label'),
type: dict.getValue('internal_type'),
mandatory: dict.getValue('mandatory') === 'true',
reference: dict.getValue('reference'),
maxLength: dict.getValue('max_length')
});
}
return fields;
}Check Field Exists
检查字段是否存在
javascript
// Check if field exists on table (ES5 ONLY!)
function fieldExists(tableName, fieldName) {
var dict = new GlideRecord('sys_dictionary');
dict.addQuery('name', tableName);
dict.addQuery('element', fieldName);
dict.query();
return dict.hasNext();
}javascript
// Check if field exists on table (ES5 ONLY!)
function fieldExists(tableName, fieldName) {
var dict = new GlideRecord('sys_dictionary');
dict.addQuery('name', tableName);
dict.addQuery('element', fieldName);
dict.query();
return dict.hasNext();
}MCP Tool Integration
MCP 工具集成
Available Tools
可用工具
| Tool | Purpose |
|---|---|
| Query dictionary |
| Get field definitions |
| Test dictionary scripts |
| Find data policies |
| 工具 | 用途 |
|---|---|
| 查询字典 |
| 获取字段定义 |
| 测试字典脚本 |
| 查找数据策略 |
Example Workflow
示例工作流
javascript
// 1. Get table fields
await snow_discover_table_fields({
table_name: 'incident'
});
// 2. Query data policies
await snow_query_table({
table: 'sys_data_policy2',
query: 'model_table=incident^active=true',
fields: 'short_description,conditions,apply_to_client'
});
// 3. Check dictionary overrides
await snow_query_table({
table: 'sys_dictionary_override',
query: 'name=u_custom_table',
fields: 'base_element,column_label,mandatory,read_only'
});javascript
// 1. Get table fields
await snow_discover_table_fields({
table_name: 'incident'
});
// 2. Query data policies
await snow_query_table({
table: 'sys_data_policy2',
query: 'model_table=incident^active=true',
fields: 'short_description,conditions,apply_to_client'
});
// 3. Check dictionary overrides
await snow_query_table({
table: 'sys_dictionary_override',
query: 'name=u_custom_table',
fields: 'base_element,column_label,mandatory,read_only'
});Best Practices
最佳实践
- Schema Planning - Design before implementation
- Field Naming - u_ prefix for custom fields
- Data Types - Use appropriate types
- Mandatory Fields - Only when truly required
- Data Policies - Enforce business rules
- Performance - Avoid complex calculated fields
- Documentation - Document custom schema
- ES5 Only - No modern JavaScript syntax
- 表结构规划 - 先设计再实现
- 字段命名 - 自定义字段使用u_前缀
- 数据类型 - 使用合适的类型
- 必填字段 - 仅在真正需要时设置
- 数据策略 - 强制执行业务规则
- 性能优化 - 避免复杂的计算字段
- 文档记录 - 记录自定义表结构
- 仅支持ES5 - 禁止使用现代JavaScript语法