Glide 서버 API
ServiceNow 는 Glide 서버용 API를 제공합니다.
GlideAggregate
GlideAggregate 클래스는 GlideRecord의 확장이며 데이터베이스 집계(COUNT, SUM, MIN, MAX, AVG) 쿼리를 수행할 수 있습니다. 이는 사용자 지정 보고서를 생성하거나 계산된 필드를 계산하는 데 유용할 수 있습니다.
자세한 내용은 GlideAggregate API를 참조하십시오.
GlideAggregate 예시
GlideAggregate 는 GlideRecord 의 확장이며 그 사용법은 일련의 예를 통해 가장 잘 알 수 있습니다.
다음은 단순히 테이블의 기록 수를 계산하는 예입니다.
var count = new GlideAggregate('incident');
count.addAggregate('COUNT');
count.query();
var incidents = 0;
if(count.next())
incidents = count.getAggregate('COUNT');앞의 예와 관련된 쿼리가 없습니다. 오픈 상태였던 인시던트의 수를 확인하려면 GlideRecord에서와 같이 쿼리를 추가하기만 하면 됩니다. 다음은 활성 인시던트 수를 계산하는 예입니다.
var count = new GlideAggregate('incident');
count.addQuery('active','true');
count.addAggregate('COUNT');
count.query();
var incidents = 0;
if(count.next())
incidents = count.getAggregate('COUNT');범주별로 모든 오픈 인시던트 수를 가져오려면 코드는 다음과 같습니다.
var count = new GlideAggregate('incident');
count.addQuery('active','true');
count.addAggregate('COUNT','category');
count.query();
while(count.next()){
var category = count.category;
var categoryCount = count.getAggregate('COUNT','category');
gs.log("The are currently "+ categoryCount +" incidents with a category of "+ category);}출력은 다음과 같습니다.
*** Script: The are currently 1.0 incidents with a category of Data
*** Script: The are currently 11.0 incidents with a category of Enhancement
*** Script: The are currently 1.0 incidents with a category of Implementation
*** Script: The are currently 197.0 incidents with a category of inquiry
*** Script: The are currently 13.0 incidents with a category of Issue
*** Script: The are currently 1.0 incidents with a category of
*** Script: The are currently 47.0 incidents with a category of request다음은 여러 집계를 사용하여 MIN, MAX 및 AVG 값을 사용하여 기록이 수정된 횟수를 확인하는 예입니다.
var count = new GlideAggregate('incident');
count.addAggregate('MIN','sys_mod_count');
count.addAggregate('MAX','sys_mod_count');
count.addAggregate('AVG','sys_mod_count');
count.groupBy('category');
count.query();
while(count.next()){
var min = count.getAggregate('MIN','sys_mod_count');
var max = count.getAggregate('MAX','sys_mod_count');
var avg = count.getAggregate('AVG','sys_mod_count');
var category = count.category.getDisplayValue();
gs.log(category +" Update counts: MIN = "+ min +" MAX = "+ max +" AVG = "+ avg);}출력은 다음과 같습니다.
*** Script: Data Import Update counts: MIN = 4.0 MAX = 21.0 AVG = 9.3333
*** Script: Enhancement Update counts: MIN = 1.0 MAX = 44.0 AVG = 9.6711
*** Script: Implementation Update counts: MIN = 4.0 MAX = 8.0 AVG = 6.0
*** Script: inquiry Update counts: MIN = 0.0 MAX = 60.0 AVG = 5.9715
*** Script: Inquiry / Help Update counts: MIN = 1.0 MAX = 3.0 AVG = 2.0
*** Script: Issue Update counts: MIN = 0.0 MAX = 63.0 AVG = 14.9459
*** Script: Monitor Update counts: MIN = 0.0 MAX = 63.0 AVG = 3.6561
*** Script: request Update counts: MIN = 0.0 MAX = 53.0 AVG = 5.0987다음은 한 달과 다음 달의 활동을 비교하는 방법을 보여주는 보다 복잡한 예입니다.
var agg = new GlideAggregate('incident');
agg.addAggregate('count','category');
agg.orderByAggregate('count','category');
agg.orderBy('category');
agg.addQuery('opened_at','>=','javascript:gs.monthsAgoStart(2)');
agg.addQuery('opened_at','<=','javascript:gs.monthsAgoEnd(2)');
agg.query();
while(agg.next()){
var category = agg.category;
var count = agg.getAggregate('count','category');
var query = agg.getQuery();
var agg2 = new GlideAggregate('incident');
agg2.addAggregate('count','category');
agg2.orderByAggregate('count','category');
agg2.orderBy('category');
agg2.addQuery('opened_at','>=','javascript:gs.monthsAgoStart(3)');
agg2.addQuery('opened_at','<=','javascript:gs.monthsAgoEnd(3)');
agg2.addEncodedQuery(query);
agg2.query();
var last ="";
while(agg2.next()){
last = agg2.getAggregate('count','category');}
gs.log(category +": Last month:"+ count +" Previous Month:"+ last);
}출력은 다음과 같습니다.
*** Script: Monitor: Last month:6866.0 Previous Month:4468.0
*** Script: inquiry: Last month:142.0 Previous Month:177.0
*** Script: request: Last month:105.0 Previous Month:26.0
*** Script: Issue: Last month:8.0 Previous Month:7.0
*** Script: Enhancement: Last month:5.0 Previous Month:5.0
*** Script: Implementation: Last month:1.0 Previous Month:0다음은 그룹 쿼리에서 필드의 고유 개수를 가져오는 예입니다.
var agg = new GlideAggregate('incident');
agg.addAggregate('count');
agg.addAggregate('count(distinct','category');
agg.addQuery('opened_at', '>=', 'javascript:gs.monthsAgoStart(2)');
agg.addQuery('opened_at', '<=', 'javascript:gs.monthsAgoEnd(2)');
//
agg.groupBy('priority');
agg.query();
while (agg.next()) {
// Expected count of incidents and count of categories within each priority value (group)
gs.info('Incidents in priority ' + agg.priority + ' = ' + agg.getAggregate('count') +
' (' + agg.getAggregate('count(distinct','category') + ' categories)');
}출력은 다음과 같습니다.
*** Script: Incidents in priority 1 = 13 (3 categories)
*** Script: Incidents in priority 2 = 10 (5 categories)
*** Script: Incidents in priority 3 = 5 (3 categories)
*** Script: Incidents in priority 4 = 22 (6 categories)- total_cost가 $12인 레코드 3개
- total_cost가 $10인 기록 4개
- total_cost가 $5인 레코드 5개
다음 코드는 groupBy() 메서드를 사용하지 않고 SUM 집계를 구현하는 방법을 보여줍니다.
var totalCostSum = new GlideAggregate('fixed_asset');
totalCostSum.addAggregate('SUM', 'total_cost');
totalCostSum.query();
while (totalCostSum.next()) {
var allTotalCost = 0;
allTotalCost = totalCostSum.getAggregate('SUM', 'total_cost');
aTotalCost = totalCostSum.getValue('total_cost');
gs.print('Unique field value: ' + aTotalCost + ', SUM = ' + allTotalCost + ', ' + allTotalCost/aTotalCost + ' records');
}이 예시의 출력은 다음과 같습니다.
*** Script: Unique field value: 12, SUM = 36, 3 records
*** Script: Unique field value: 10, SUM = 40, 4 records
*** Script: Unique field value: 5, SUM = 25, 5 records이전 예제와 동일한 데이터 요소를 사용하여 groupBy() 메서드를 사용하는 경우 SUM 집계는 지정된 필드에 대한 모든 값의 합계를 반환합니다.
다음 예제에서는 groupBy() 메서드를 사용하여 SUM 집계를 구현하는 방법을 보여줍니다.
var totalCostSum = new GlideAggregate('fixed_asset');
totalCostSum.addAggregate('SUM', 'total_cost');
totalCostSum.groupBy('total_cost');
totalCostSum.query();
if(totalCostSum.next()){ // in case there is no result
var allTotalCost = 0;
allTotalCost = totalCostSum.getAggregate('SUM', 'total_cost');
gs.print('SUM of total_cost: = ' + allTotalCost);
}이 예시의 출력은 다음과 같습니다.
*** Script: SUM of total_cost: 101GlideRecord
GlideRecord 는 JavaScript에서 네이티브 JavaScript 클래스인 것처럼 정확하게 사용할 수 있는 특수 Java 클래스(GlideRecord.java)입니다.
- 는 SQL 쿼리를 작성하는 대신 데이터베이스 작업에 사용됩니다.
- 는 한 테이블에서 0개 이상의 기록을 포함하는 객체입니다. 이것을 말하는 또 다른 방법은 GlideRecord가 순서가 지정된 목록이라는 것입니다.
GlideRecord에는 기록(행)과 필드(열)가 모두 포함됩니다. 필드 이름은 기본 데이터베이스 열 이름과 같습니다. 자세한 내용은 GlideRecord - 범위 지정을 참조하십시오.
에서 gs.sql()) 스크립팅 구문의 사용이 중단되었습니다.Geneva 해당 위치에 표준 GlideRecord 구문을 사용합니다.GlideRecordSecure 사용
GlideRecordSecure는 GlideRecord와 동일한 기능을 수행하고 ACL을 적용하는 GlideRecord에서 상속된 클래스입니다.
기본적으로 GlideRecordSecure 는 쿼리 ACL을 적용하지 않습니다. 표준 읽기-쓰기 ACL을 자동으로 적용하지만 쿼리 ACL은 개발자의 명시적 옵트인이 필요합니다. 자세한 내용은 쿼리 ACL 적용 문서를 참조하십시오.
쓸 수 없는 필드
GlideRecordSecure를 사용하는 경우 데이터베이스에 쓰려고 할 때 쓸 수 없는 필드가 NULL로 설정됩니다. 기본적으로 열의 canCreate() 메서드는 열의 canWrite() 로 대체됩니다. canWrite() 메서드가 false를 반환하면 열 값이 NULL로 설정됩니다.
객체 유형 가져오기
toString() 메서드를 호출하여 객체 유형이 ScopedGlideRecordSecure인지 확인할 수 있습니다.
- 반환된 GlideRecord 실수 유형 확인 중
-
현재 객체는 ScopedGlideRecordSecure로 전달할 수 있습니다. 대부분의 경우 current.toString()을 호출하여 현재 객체 유형을 반환할 수 있습니다.
다음 줄은 ScopedGlideRecordSecure 객체에 대해 [object ScopedGlideRecordSecure]를 반환합니다.
gs.info(current.toString()); - 반환된 객체 유형이 예상과 다른 경우
-
GlideRecord 개체를 해당 형식으로 반환하는 범위가 지정된 함수를 호출하면 호출된 범위에 따라 다른 결과가 반환됩니다.
- 애플리케이션 범위 내에서 범위가 지정된 함수를 호출하면
GlideRecord또는GlideRecordSecure의 예상 객체 유형이 반환됩니다. - 전역 범위 내에서 범위가 지정된 함수를 호출하면 반환되는 객체 유형은
ScopedGlideRecord또는ScopedGlideRecordSecure입니다.
- 애플리케이션 범위 내에서 범위가 지정된 함수를 호출하면
NULL 값 확인 중
if 문이 필요합니다.if (!now_GRScanRead())
continue;var count = 0;
var now_GR = new GlideRecord('mytable');
now_GR.query();
while (now_GR.next()) {
if (!now_GR.canRead()) continue;
if (!now_GR.canWrite()) continue;
if (!now_GR.val.canRead() || !now_GR.val.canWrite())
now_GR.val = null;
else
now_GR.val = "val-" + now_GR.id;
if (now_GR.update())
count ++;
}
var count = 0;
var now_GRS = new GlideRecordSecure('mytable');
now_GRS.query();
while (now_GRS.next()) {
now_GRS.val = "val-" + now_GRS.id;
if (now_GRS.update())
count ++;
}쿼리 ACL 적용
기본적으로 GlideRecordSecure 는 쿼리 ACL을 적용하지 않습니다. 쿼리 ACL 적용을 위해서는 명시적 옵트인이 필요합니다.
쿼리 ACL 적용은 사용자가 액세스 권한이 있는 필드와 기록만 쿼리할 수 있도록 하는 보안 접근 방식입니다. 이 전략은 데이터 검색 수준뿐만 아니라 쿼리 수준에서 접근 제어를 적용하여 심층 방어를 제공합니다. 명시적 쿼리 ACL 적용은 사용자 입력을 처리하는 애플리케이션에 대한 보다 안전한 설계 패턴을 나타냅니다.
쿼리 ACL 적용 동작을 명시적으로 지정하려면 GlideRecordSecure.addEncodedQuery()를 사용합니다. 명시적 ACL 사양 없이 기본적인 addEncodedQuery(query) 사용을 업데이트합니다. 다음 보안 옵션 중 하나를 사용합니다.
- 옵션 1: 편리한 방법(권장)
- 다음 사용 사례에 대해 addUserEncodedQuery() 메서드를 사용합니다.
- 쿼리 ACL이 적용되는 사용자 입력에서 작성된 쿼리
- 사용자 선택에 기반한 동적 필터 빌드
- 신뢰할 수 없는 데이터 처리
다음 사용 사례에 대해 addSystemEncodedQuery() 메서드를 사용합니다.- 하드 코딩된 쿼리 조건
- 사용자 입력이 없는 백엔드 또는 시스템 전용 로직
- 안전하고 사전 정의된 쿼리 조건
필요에 따라 두 방법을 모두 혼합합니다. 쿼리의 여러 부분은 소스에 따라 다른 적용 수준을 사용할 수 있습니다.
// Queries built from user input nowGRS_ACL.addUserEncodedQuery(userInput); // Hard-coded system queries nowGRS.addSystemEncodedQuery("active=true"); - 옵션 2: 부울 매개변수
-
다음 예제에서는 ACL 적용을 위해 addEncodedQuery() 메서드를 사용하는 방법을 보여줍니다.
// Explicitly enforce query ACLs var now_GRS_true = new GlideRecordSecure(<table_name>); nowGRS_true.addEncodedQuery(query, true); // Explicitly skip query ACL enforcement (use cautiously) var nowGRS_false = new GlideRecordSecure(<table_name>); nowGRS_false.addEncodedQuery(query, false);
예제
다음은 GlideRecordSecure를 사용하는 두 가지 간단한 예입니다.
var att = new GlideRecordSecure('sys_attachment');
att.get('$[sys_attachment.sys_id]');
var sm = GlideSecurityManager.get();
var checkMe = 'record/sys_attachment/delete';
var canDelete = sm.hasRightsTo(checkMe, att);
gs.log('canDelete: ' + canDelete);
canDelete;
var now_GRS = new GlideRecordSecure('task_ci');
now_GRS.addSystemQuery();
now_GRS.query();
var count = now_GRS.getRowCount();
if (count > 0 ) {
var allocation = parseInt(10000/count) / 100;
while (now_GRS.next()) {
now_GRS.u_allocation = allocation;
now_GRS.update();
}
}
글라이드시스템
GlideSystem API는 정보를 검색하기 위한 메서드를 제공합니다.
GlideSystem(비즈니스 규칙에서 변수 이름 'gs'로 참조됨)은 시스템, 현재 로그인한 사용자 등에 대한 정보를 얻을 수 있는 여러 가지 편리한 방법을 제공합니다. 예를 들어 addInfoMessage() 메서드는 사용자와의 통신을 허용합니다.
gs.addInfoMessage('Email address added for notification');
많은 GlideSystem 메서드를 사용하면 쿼리 범위에 날짜를 쉽게 포함할 수 있으며 필터 및 보고에 가장 자주 사용됩니다.
자세한 내용은 GlideSystem 문서를 참조하십시오.
GlideDateTime
GlideDateTime 클래스는 GlideDateTime 객체 인스턴스화 또는 glide_date_time 필드 작업 등 GlideDateTime 객체에 대한 작업을 수행하는 메서드를 제공합니다.
아래에 설명된 인스턴스화 메서드 외에도 getGlideObject() 메서드(예: var gdt = gr.my_datetime_field.getGlideObject();))를 사용하여 glide_date_time 필드에서 GlideDateTime 객체를 인스턴스화할 수 있습니다.
일부 메서드는 날짜 및 시간 값을 검색하거나 수정할 때 Java Virtual Machine 시간대를 사용합니다. 이러한 방법을 사용하면 예기치 않은 동작이 발생할 수 있습니다. 가능하면 동등한 현지 시간과 UTC 방법을 사용합니다.
GlideDate 및 GlideDateTime 예시
GlideDate 및 GlideDateTime API는 날짜 및 시간 값을 조작하는 데 사용됩니다.
자세한 내용은 GlideDate API 및 GlideDateTime API를 참조하십시오.
var gDate = new GlideDate();
gDate.setValue('2015-01-01');
gs.info(gDate);
var gDT = new GlideDateTime(gDate);
gs.info(gDT); 출력: 2015-01-01
2015-01-01 00:00:00GlideDateTime 필드 값 수정 또한 참조하십시오.
스크립트에서 기간 필드 값 설정
기간 필드의 값을 설정하는 데 사용할 수 있는 JavaScript 예시입니다.
GlideDateTime.subtract() 메서드 사용
var duration = GlideDateTime.subtract(start, end);var time = GlideDateTime.subtract(start,end).getNumericValue();
<duration_field> = GlideDateTime.subtract(new GlideDateTime(<start_time>.getValue()),gs.nowDateTime());GlideDateTime.subtract에 표시되는 시간 값은 사용자의 시간대와 사용자 형식으로 되어 있어야 합니다.
기간 필드의 기본값 설정
기간 필드의 기본값 설정은 이전 주제에서 사용한 방법과 유사합니다.
클라이언트 스크립트에서 기간 필드 값 설정
g_form.setValue('<duration_field>','11 01:02:03');클라이언트 스크립트를 사용하여 기간 계산 및 설정
다음은 값을 반환하고 클라이언트 스크립트를 사용하여 채우는 방법의 예입니다.
onChange 클라이언트 스크립트를 만듭니다. onLoad 스크립트 또는 다른 방식으로 계산을 수행해야 하는 경우 이 스크립트를 수정할 수 있습니다.function onChange(control, oldValue, newValue, isLoading){
var strt = g_form.getValue('<start_field>');
var end = g_form.getValue('<end_field>');
var ajax = new GlideAjax('AjaxDurCalc');
ajax.addParam('sysparm_name','durCalc');
ajax.addParam('sysparm_strt',strt);
ajax.addParam('sysparm_end',end);
ajax.getXMLWait();
var answer = ajax.getAnswer();
g_form.setValue('<duration_field>', answer);}var AjaxDurCalc = Class.create();
AjaxDurCalc.prototype = Object.extendsObject(AbstractAjaxProcessor,{
durCalc:function(){return GlideDuration.subtract(this.getParameter('sysparm_strt'),this.getParameter('sysparm_end'));}});기간 필드 값 변경
var timems = current.duration.dateNumericValue();
timems = timems + 11*1000;
current.duration.setDateNumericValue(timems);해결 시간 형식 지정
format=glide_duration필드에 대한 딕셔너리 항목을 수정하고 속성을 추가합니다. 기존 속성이 있는 경우 여러 속성을 쉼표로 구분합니다.
최대 측정 단위 설정
max_unit=분인 경우 3시간 5분 15초의 기간은 185분 15초로 표시됩니다. 최대 기간 측정 단위를 설정하려면 기간 필드에 다음 딕셔너리 속성을 추가합니다.max_unit=<unit>날짜 및 시간 형식 지침
특정 날짜 및 시간 패턴 문자열의 시퀀스로 날짜 형식을 지정할 수 있습니다. 패턴 문자열은 A부터 Z까지 하나 이상의 대문자와 소문자로 구성됩니다. 따옴표 안에 있는 텍스트는 무시되고 대신 날짜 출력에 복사됩니다.
| 문자열 | 설명 | 출력 형식 | 예제 |
|---|---|---|---|
| G | 시대 지정자 | 텍스트 | 광고 |
| y | 년 | 년 | 2019; 19 |
| Y | 주/연도 | 년 | 2019; 19 |
| M | 월/연도(날짜 이내) | 월 | 7월; 7월; 07 |
| L | 월/연도(독립 실행형 값) | 월 | 7월; 7월; 07 |
| 주 | 주/연도 | 번호 | 52 |
| W | 주/월 | 번호 | 1 |
| D | 일/연도 | 번호 | 365 |
| d | 일/월 | 번호 | 2 |
| F | 요일(월 중) | 번호 | 3 |
| E | 일/주 이름 | 텍스트 | 수요일; 수 |
| u | 일(주의) | 번호 | 3 |
| a | 오전 또는 오후 | 텍스트 | 오후 |
| H | 0에서 23까지의 시간(일) | 번호 | 0 |
| k | 1시에서 24시까지의 시간(일) | 번호 | 24 |
| 천 | 오전 또는 오후 0시부터 11시까지의 시간 | 번호 | 0 |
| h | 오전 1시부터 오후 1시까지 | 번호 | 12 |
| m | 분/시 | 번호 | 59 |
| s | 초/분 | 번호 | 1 |
| S | 밀리초 | 번호 | 500 |
| z | 기본 형식의 시간대 | 기본 형식의 시간대 | 태평양 표준시; PST |
| Z | RFC 822 형식의 시간대 | RFC 822 형식의 시간대 | -0800 |
| X | ISO 8601 형식의 시간대 | ISO 8601 형식의 시간대 | -08; -0800; -08:00 |