ServiceNow開発部ブログ第2回目です。
今回はsys_class_nameの仕様に関する調査です。
sys_class_nameの仕様
テーブルを作成した際や既存のテーブルのカラムを参照した際、"sys_class_name"というカラムが作成されているのをご覧になったことがあるかと思います。
このカラムが何の情報を持っているか、どんな時に使うのか、などについてまとめました。
sys_class_nameは、対象レコードが実際に存在するテーブルの物理名を持っているカラムです。
このカラムは、
(1)Table作成時、ないし設定画面のControlsタブで”Extensible”にチェックを入れたとき
(2)Table作成時にほかのテーブルを継承して作成したとき
に自動的に生成されます。
このカラムを参照するメリットは、子テーブル、親テーブルを区別してテーブル名を返してくれることです。
具体的にスクリプトとその実行結果から見ていきます。
以下に示すのは、バックグラウンドで実行したサーバ側のスクリプトです。
// sys_class_nameの使用例1
var gr = new GlideRecord("incident");
gr.get("2173267587c5811020e31f4bbbbb3565");//Incidentレコードのsys_id gs.info(gr.sys_class_name); //=>実行結果:"incident"
// sys_class_nameの使用例2
var gr = new GlideRecord("task");
gr.get("2173267587c5811020e31f4bbbbb3565");//Incidentレコードのsys_id gs.info(gr.sys_class_name); //=> 実行結果:"incident"
使用例1ではIncidentテーブルのGlideRecordオブジェクトを新規作成し、テスト用に作成したIncidentレコードのオブジェクトを取得します。このオブジェクトのsys_class_nameには、当該レコードが格納されているIncident[incident]テーブルを示す値が入っています。
対して使用例2で作成しているのTaskテーブルのGlideRecordオブジェクトです。Incident[incident]テーブルはTask[task]テーブルを拡張して作られています。そのため、Incidentレコードは親テーブルであるTaskにも存在しています。しかしながら、TaskのGlideRecordオブジェクトを作成してsys_class_nameの中身を見ると、子テーブルであるIncident[incident]を示す値が入っています。
このように、sys_class_nameの値を利用すれば、親子関係を持つテーブルに格納されたレコードの正確な所在を取得することが出来ます。
getTableName()との違い
他方、比較として、sys_class_nameの代わりにgetTableName()というAPIを使ったスクリプトを実行してみます。
// getTableName()の使用例1
var gr = new GlideRecord("incident");
gr.get("2173267587c5811020e31f4bbbbb3565");//Incidentレコードのsys_id gs.info(gr.getTableName()); //=>実行結果:"incident"
// getTableName()の使用例2
var gr = new GlideRecord("task");
gr.get("2173267587c5811020e31f4bbbbb3565");//Incidentレコードのsys_id gs.info(gr.getTableName()); //=>実行結果:"task"
こちらの実行結果はそれぞれ"incident"と"task"となりました。これは、getTableName()というAPIが、参照するGlideRecordオブジェクトに紐づくテーブル名を取得するGlideRecord APIだからです。
とはいえ、sys_class_nameを使ったときと同様の処理は、currentオブジェクトが使えるBusiness RuleやEmail Scriptといったサーバ側スクリプトでなら、getTableName()を使っても実装することが可能です。
たとえば、current.getTableName()などとすれば、現在参照しているレコードのテーブル名が得られます。そのテーブルが他のテーブルを継承していたとしても、親テーブルの名前が取得されることはありません。なので、current.sys_class_nameとcurrent.getTableName()とでは、どちらを使ったとしても同じアウトプットが得られます。
また、クライアント側のスクリプトでも、getTableName()というGlideForm APIがありますが、これも現在のレコードが属しているテーブル名を返してくれます。
したがって、sys_class_nameのメリットが発揮されるのは、サーバ側スクリプトでもcurrentオブジェクトが使えないScheduled Jobや、クライアント側のスクリプトでGlideRecordオブジェクトを使ってDB操作を行うときなどであろうと考えられます。