How to bulk update records without changing sys_updated_on or firing business rules
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
23m ago
Hi Guys, This is Iron
Do you happen to know that you can achieve this with setWorkflow(false) + autoSysFields(false) + updateMultiple(), and by only touching records whose value is actually different. This keeps audit columns clean and makes the job safe to rerun.
Step 1: Group first, then write once per group
Instead of looping every record, find the distinct combinations that decide the result.
var ga = new GlideAggregate('cmdb_software_instance');
ga.addNotNullQuery('u_raw_appname');
ga.groupBy('u_raw_appname');
ga.groupBy('u_raw_fullversion');
ga.addAggregate('COUNT');
ga.query();
// millions of rows -> a few thousand combinations
Step 2: Update only what changed
var gr = new GlideRecord('cmdb_software_instance');
gr.addQuery('u_raw_appname', name);
gr.addQuery('u_raw_fullversion', version);
gr.addEncodedQuery('u_eol_status!=' + status + '^ORu_eol_statusISEMPTY'); // skip rows already correct
gr.setWorkflow(false); // no business rules, notifications, audit
gr.autoSysFields(false); // sys_updated_on / sys_updated_by / sys_mod_count stay as they are
gr.setValue('u_eol_status', status);
gr.setValue('u_eol_date', eolDate);
gr.updateMultiple();
Step 3: Add a dry-run switch
initialize: function (opt) { opt = opt || {}; this.dry = !!opt.dry; },
run: function () {
var st = { dry: this.dry, updated: 0 }; // return dry in the result so you can verify it later
// ... count first ...
if (this.dry) return st;
// ... write ...
return st;
}
// Background script
var job = new MyBulkUpdater({ dry: true });
gs.info('dry=' + job.dry); // confirm before running
gs.info(JSON.stringify(job.run()));
When NOT to use this
- setWorkflow(false) also skips business rules you may need (e.g. CMDB reconciliation). Use it only for fields your own process owns.
- Leaving out autoSysFields(false) on a cleanup job stamps your user on every touched record. We saw this on ~29K CIs before adding it.
If this helped, please mark it as Helpful 👍
sys_updated_on を変えず、ビジネスルールも動かさずに一括更新する方法
setWorkflow(false) + autoSysFields(false) + updateMultiple() を使い、さらに値が実際に異なるレコードだけを更新することで実現できます。監査用の列が汚れず、ジョブを何度再実行しても安全です。
Step 1: 先にグループ化し、グループごとに 1 回だけ書き込む
全レコードをループするのではなく、結果を決める組み合わせを先に取ります。
var ga = new GlideAggregate('cmdb_software_instance');
ga.addNotNullQuery('u_raw_appname');
ga.groupBy('u_raw_appname');
ga.groupBy('u_raw_fullversion');
ga.addAggregate('COUNT');
ga.query();
// 数百万行 -> 数千の組み合わせ
Step 2: 変わったものだけ更新する
var gr = new GlideRecord('cmdb_software_instance');
gr.addQuery('u_raw_appname', name);
gr.addQuery('u_raw_fullversion', version);
gr.addEncodedQuery('u_eol_status!=' + status + '^ORu_eol_statusISEMPTY'); // すでに正しい行はスキップ
gr.setWorkflow(false); // ビジネスルール・通知・監査を動かさない
gr.autoSysFields(false); // sys_updated_on / sys_updated_by / sys_mod_count を変えない
gr.setValue('u_eol_status', status);
gr.setValue('u_eol_date', eolDate);
gr.updateMultiple();付ける
initialize: function (opt) { opt = opt || {}; this.dry = !!opt.dry; },
run: function () {
var st = { dry: this.dry, updated: 0 }; // 後で確認できるよう結果に dry を入れる
// ... まず件数を数える ...
if (this.dry) return st;
// ... 書き込み ...
return st;
}// バックグラウンドスクリプト
var job = new MyBulkUpdater({ dry: true });
gs.info('dry=' + job.dry); // 実行前に確認
gs.info(JSON.stringify(job.run()));
使うべきでない場面
- setWorkflow(false) は必要なビジネスルール(CMDB の照合など)も止めます。自分の処理が所有するフィールドだけに使ってください。
- クリーンアップジョブで autoSysFields(false) を忘れると、触った全レコードに自分のユーザー名が残ります。実際に約 2.9 万件の CI で発生しました。
参考になれば Helpful をお願いします 👍
0 REPLIES 0