
ServiceNowの保存で実際に動くBusiness Ruleは何本か? problemテーブルで定義と実測を比べる
保存が重い、値が知らないうちに変わる。そんなとき「裏側で何本のBusiness Ruleが動いているのか」が気になったことはないでしょうか。sys_scriptの定義本数を数えても答えにはなりません。定義されていても、条件で弾かれて動かないものが大半だからです。ServiceNowにはDebug Business Ruleという、実際に発火した処理だけを画面に出す機能があります。今回はproblemテーブルで検証用レコードを1件だけ作成・更新し、定義27件のうち実際に何本が動いたかを実機で数えました。
検証環境:Zurich PDI / OOTB / 2026-08-10 確認
結論:定義27件のうち、動いたのは6件だけだった
先に全体像を示します。
problemテーブル自身が持つBusiness Ruleの定義は27件(有効25件)
そのうち1回のINSERT(新規保存)で実際に発火したのは、problem自身の定義だけで見ると6件
ただし保存時にはtaskテーブル(problemの継承元)の定義37件も合わせて評価されており、そちらから継承して発火した分が6件。合計すると12件が動いていました
同じレコードへの1回のUPDATE(本文の変更のみ)では、発火数はさらに絞られて6件(problem自身2件+継承4件)でした
数だけ見ると「定義の半分にも満たない本数しか動いていない」というのが今回の実測です。動いたのは少数派でした。なぜそうなるのか、どうやって確かめたのかを順に見ていきます。

図の色は6種類の意味に固定しています。濃紺は保存という起点、橙はそのスコープで評価された件数の合計です。緑は実際に発火した処理、赤は条件が満たされずスキップされた処理を表します。紫はproblem自身ではなくtaskから継承して動いた分、水色は保存の副作用として他のテーブルにも及んだ処理です。
Business Ruleの定義は「動く保証」ではない
公式ドキュメント(ServiceNow Docs / Zurich)によれば、Business Ruleはサーバー側で動くスクリプトです。レコードの表示・挿入・更新・削除、またはテーブルへの照会がトリガーになります。sys_scriptというテーブルに、1ルール=1レコードで定義が格納されます。
ここで見落としがちなのは、定義されていることと、実際に動くことは別という点です。sys_scriptの各レコードには、action_insert・action_update・filter_conditionという複数段のフィルタがあります。加えてAdvancedタブのconditionも通過して、初めてスクリプトが動きます。同じテーブルに27件のBusiness Ruleが定義されていても、1回の保存で条件をすべて満たすのはごく一部というのが自然な設計です。
「では実際には何本動いているのか」を答えるには、定義を数えるのではなく、1回保存して発火した処理そのものを見る必要があります。それができるのが、System Diagnosticsに含まれるDebug Business Ruleです。
実機で確かめる:problemに1件だけ保存してみる
Debug Business Ruleは、Application Navigator(画面左上の「All」)から検索して開きます。

System Diagnostics > Session Debug > Debug Business Rule をクリックします。別タブでScript Debugger(Session Logタブ)が開く仕組みです。これでこのセッション以降、フォームや一覧の下部に「Debug Output」というセクションが追加表示されます。
今回はこの状態で、problemテーブルに検証用のレコードを1件だけ作成しました。Problem statementに検証用の文字列を入力しただけで、他の項目は既定値のまま保存しています。

このフォームでSubmitを押した瞬間に、before insert・after insertのBusiness Ruleが評価されます。Debug Outputの「Business Rules」だけにチェックを絞ると、この1回の保存で何が起きたかが時系列で読み取れます。
INSERT 1回で実際に発火したのは12件
保存直後のDebug Outputを見ると、次のような行が並びます。

Global ==> で始まる行が実際に発火した処理、Global === Skipping で始まる行が条件不成立でスキップされた処理です。この2種類をそれぞれ数えると、problemスコープ(problem自身+継承したtask分の合算)で評価されたのは34件、そのうち発火したのは12件、スキップは22件でした。
発火した12件の内訳を、sys_scriptのcollectionフィールドで裏取りすると次のようになります。
problem自身の定義(6件):Copy State to Problem State/Problem Model: Check State Transition/Sync Workaround fields/Update Problem State to Assess/Copy Problem State to State/problem events
taskから継承した定義(6件):Task Active State Management/Link task & interaction on insert/update/Stamp Approvals/metrics events/task events/Run SLAs
problem自身が持つ27件の定義のうち、この1回のINSERTで実際に動いたのは6件だけです。割合にすると22%程度にとどまります。残りの21件は、async・display扱いで今回のような同期処理には現れなかったもの、あるいはfilter_conditionやconditionで弾かれたものです。たとえば「Abort changes on group」は、assignment_groupが変化していないためスキップされていました。「Check inactive problem model」は、prb_modelが空のためスキップされていました。
なぜtaskの定義まで一緒に動くのか
sys_scriptの各レコードは、collectionというフィールドで対象テーブルを指定します。problem用のBusiness Ruleはcollection=problemですが、これとは別にcollection=taskのBusiness Ruleが37件あります。
problemはtaskを継承するテーブルです。実機のsys_db_objectでも、problemのsuper_classがTaskになっていることを確認できました。継承関係にあるテーブルを保存すると、自分のテーブル向けの定義だけでなく、継承元テーブル向けの定義も合わせて評価されます。今回の実測でも、発火した12件のうち6件がcollection=taskの定義由来でした。
「incidentの調べ方を覚えたから、problemやchange_requestでも同じだろう」と考えるのは早計です。テーブルごとに事情は違います。継承元がtaskで共通していても、固有のBusiness Ruleの本数・内容までは共通しません。継承元の分がどれだけ乗ってくるかも、テーブルによって変わります。
UPDATEではさらに絞られて6件
同じレコードをもう一度開き、Problem statementの末尾に文言を追記してUpdateを押しました。stateフィールドはフォーム上で読み取り専用になっており、直接のドロップダウン変更はできなかったため、本文の書き換えだけで更新をかけています。

保存後のDebug Outputを同じ要領で数えると、evaluateされたのは46件、発火は6件、スキップは40件でした。

発火した6件のうち、problem自身の定義は2件です(Update Problem State to Assess/problem events)。残る4件はtaskからの継承分でした(Link task & interaction on insert/update/metrics events/task events/Run SLAs)。
今回はstateを変えていません。そのため、stateVALCHANGESやstateCHANGESTOを条件に持つBusiness Ruleは、すべてスキップに回っています。該当するのはCopy State to Problem StateやCopy Problem State to Stateなどです。数字だけでは、この「動かなかった側」の存在が見えません。
INSERTとUPDATEの数字を並べると、次のようになります。

同じレコードでも、INSERTとUPDATEでは評価される母数もスキップ数も変わります。保存のたびに「何本動いたか」は一定ではなく、その時点のフィールド値と操作の種類(挿入か更新か)に左右されるということが、この比較から読み取れます。
定義本数を鵜呑みにしない:27件の内訳
ここまでの「発火12件・6件」という数字の土台になっている、定義側の27件も確認しておきます。

when(実行タイミング)でグループ化すると、次のように分かれます。

problem自身の定義と、継承元であるtaskの定義を並べると次のとおりです。

problem自身の27件のうち、非activeなのは2件でどちらもafter扱いでした。少数派です。display(4件)はフォーム表示時に動く処理でINSERT/UPDATEには現れず、async(2件)は条件評価だけこのトランザクション内で行われ、実行自体は別トランザクションに回ります。今回の「34件を評価して12件発火」という数字は、before・afterのBusiness Ruleを中心に、taskから継承した分も合算したうえでの結果です。
実機で気づいたこと
数字を数えるだけでは見えてこなかった、実機ならではの気づきを3つ紹介します。
採番のBusiness Ruleは、想定より早い段階でスキップされていた
insert_problemという、number(PRB番号)を採番するためのBusiness Ruleがあります。conditionはcurrent.number.nil()で、番号が空のときだけ動く設計です。ところが今回のログでは、この行が「condition not satisfied」でスキップされていました。
ログの区切りには「before engines (order <1000)」「after engines (order >=1000)」という表記があります。採番自体は、このBusiness Ruleより前のプラットフォーム内部の処理(エンジン層)で完了していたとみられます。Business Rule一覧をいくら眺めても、この採番の実体には辿り着けません。
保存したのはproblemなのに、他8テーブルのBusiness Ruleも一緒に動いていた
今回のINSERT 1回で、problem以外にも8テーブルでBusiness Ruleの評価が走りました。対象はsys_user・sys_user_group・kb_knowledge・cxs_rel_doc_detailです。加えてsys_trigger・sys_notification_execution・cxs_relevant_doc・live_group_memberも含まれます。このうち7件が実際に発火していました。8対7。ほぼ1テーブル1件のペースで、他の処理を巻き込んでいたことになります。
フォームに表示される関連ウィジェット(ナレッジ検索やライブフィードのメンバー可視性など)が、保存のタイミングで自分のテーブルの処理を連れてきています。「problemのBusiness Ruleだけ見ておけば十分」という前提は、この時点で崩れます。
stateフィールドは、フォーム上で直接編集できなかった
Problemの項目一覧にはStateが表示されています。ただしwriteaccess="false"が明示的に付与されており、ドロップダウンとして操作できませんでした。代わりに、ヘッダのAssess・Root Cause Analysisといったボタン経由で状態を進める設計になっているようです。
状態遷移に紐づくBusiness Ruleを検証したい場合は、フィールドの直接編集ではなくこのボタンを使う必要があります。今回は本文編集のみで確認したため、ボタン経由の遷移そのものは検証範囲外です。
実務では何に使える? 自分の環境で同じことを確かめる手順
「保存が遅い」「値が勝手に変わる」といった調査に、今回の手順はそのまま使えます。
調査の手順
Application Navigatorで「Debug Business Rule」を検索して開く(System Diagnostics > Session Debug)
調査対象の画面で、実際に問題が起きる操作(保存・更新)を1回行う
表示されたDebug Outputの「Business Rules」だけにチェックし、==>(発火)とSkipping(スキップ、理由付き)を読む
想定より多く/少なく動いていたら、conditionやfilter_conditionの記述、あるいは継承元テーブル(taskなど)の定義を疑う
原因の候補を一つずつ潰していく調査より、先に結果を見てから絞り込むほうが速いことが多いです。
使い終わったら必ず解除する
調査が終わったら、必ずデバッグ表示を解除します。Application Navigatorで「Stop Debugging」を検索して開くと、無効化スクリプトが実行され、結果画面が表示されます。

Debug Business Ruleは、対象ページの表示のたびに評価結果を集計する仕組みです。有効なままだと、通常より応答が重くなります。共有の検証環境で作業する場合は特に、確認が終わり次第オフに戻すことをおすすめします。切り忘れは禁物です。
まとめ
problemテーブルには27件のBusiness Ruleが定義されていますが、1回のINSERTで実際に発火したのは、problem自身の定義だけで見ると6件でした。保存時にはtaskからの継承分も合わさるため、発火の総数としては12件になります。同じレコードへのUPDATE(本文編集のみ)では、発火はさらに絞られて6件です。
定義本数は「その機能がどれだけ作り込まれているか」を示す数字であり、「1回の操作で何が起きるか」を示す数字ではありません。後者を知りたいときは、Debug Business Ruleで実際に1回動かして数えるのが近道です。
一覧の件数を見て「これだけ動くのか」と身構える必要はありません。動くのはごく一部です。数えるだけでは足りません。次に似たテーブルを調べるときも、まず定義を数え、次に1回動かして実測する、という2段構えを崩さないことをおすすめします。
用語
PDI:Personal Developer Instance(無料の検証用インスタンス)
OOTB:Out of the Box(初期設定のまま)
sys_script:Business Ruleを格納するテーブル
collection:Business Ruleの対象テーブルを指すフィールド名
Debug Business Rule:Session Debugの機能の1つ。有効化したセッションで発火・スキップしたBusiness Ruleを画面下部に表示する
エンジン層:sys_script上のBusiness Ruleとは別に、採番など保存処理の一部としてプラットフォームが内部で行う処理(今回のログ表記から推測される呼び方)
自分の環境で確認するときのURL
sys_script_list.do?sysparm_query=collection=problem^active=true^ORDERBYwhen^ORDERBYorder(対象テーブルのBusiness Rule一覧)
sys_script_list.do?sysparm_query=collection=problem^GROUPBYwhen(whenでグループ化した件数)
sys_script_list.do?sysparm_query=collection=task^active=true^ORDERBYwhen(継承元テーブルのBusiness Rule一覧)
検証環境と未検証範囲
確認した範囲(PDI/Zurich/2026-08-10確認):
problem・taskのBusiness Rule定義件数とwhen別内訳
Debug Business Ruleを使った、INSERT1回・UPDATE1回それぞれの発火数・スキップ数
発火した処理がproblem自身の定義か、taskからの継承かの内訳
保存に伴い他テーブルのBusiness Ruleが評価される範囲(テーブル数・発火数)
確認していない範囲:
Debug Outputは表示から保存までの一連のトランザクションを含み、保存処理だけを厳密に切り出した出力ではありません
今回のUPDATEはstateを変更していません。ヘッダのボタン経由で状態遷移させた場合は、発火するBusiness Ruleの本数・内訳が変わる可能性があります
taskの37件について、条件別の詳細な内訳までは調べていません
async扱いのBusiness Ruleは、条件評価はこのトランザクション内で行われますが、実行自体は別トランザクションに遅延するため、今回の発火数には含まれていません
継承時の実行順(taskとproblem由来がどう混ざって並ぶか)は、ログの時系列から読み取れる範囲にとどめています
検証用のレコードを1件作成し、確認後に削除しました(作業前後でproblemテーブルの件数が一致することを確認済みです)。
次に読むなら
ServiceNowのBusiness Ruleはいつ動く? before/after/asyncの違いを実機の件数で確認 — sys_scriptの構造そのものを扱った基礎編。本記事の「定義27件」はこの記事と同じ数え方です
Business Ruleはどの順番で動くか:incidentの39本を並べて確かめる — when・orderという実行順の理屈を扱った記事。本記事はそこから一歩進み、実際に発火した本数を数えています
どの処理が動いたかを確認する方法(Session Debug / Field Watcher) — Debug Business Rule以外のデバッグ機能もまとめた一覧。症状別にどれを使うかはこちらを参照してください