Avoid duplicating attachment - GlideSysAttachment.copy()
We often come across a common business requirement that is to make the attachments available from one table to another.
For eg. Attachments from RITM (sc_req_item) table to Approval (sysapproval_approver) or Catalog Task (sc_task) table. We all are quite familiar with this & know there exists GlideSysAttachment.copy() method that can be used & works well as expected.
For instance, a scenario to copy attachments from REQ (sc_request) to RITM (sc_req_item) table would simply require a Business rule that runs after insert/update on Attachment (sys_attachment) table with code as below.
(function executeRule(current, previous /*null when async*/ ) {
if (current.table_name == 'sc_request') //ensure it only works for Request as sys_attachment has attachment from all tables.
{
var getritm = new GlideRecord('sc_req_item');
getritm.addQuery('request', current.table_sys_id);
getritm.query();
if (getritm.next()) {
GlideSysAttachment.copy('sc_request', current.table_sys_id, 'sc_req_item', getritm.sys_id);
}
}
})(current, previous);
Above can be used to copy attachments to any table by just altering the table name & addQuery()
Though we use it frequently we are not well aware that this is duplicating the attachment which anytime is not best practice.
As this duplication of attachments in turn increases the attachment (sys_attachment) table size.
If there are attachments with larger size this might even cause some issues when there is a need to perform some server side operation like adding new field, indexing or even changing the data type for any field for the Attachment table. I came across this from one of documents that had details about attachment management for Customer Databases.
Also, Attachment (sys_attachment) & Attachment Documents (sys_attachment_doc) are the top tables that occupy most of memory on the disk for an instance.
So, instead of duplicating attachment by use of GlideSysAttachment.copy() simplest approach is to create a relationship from System Definition >> Relationship & then display it as a Related list on required set of Tables were attachments are to be shown.
So, for a case where attachments from REQ (sc_request) are to be on RITM (sc_req_item) table then a relationship as below would suffice.
(function refineQuery(current, parent) {
var queryString = "table_nameINsc_request^table_sys_idIN" + parent.getValue("request");
var gr = new GlideRecord("sc_req_item");
gr.addQuery("request", parent.getValue("request"));
gr.query();
while (gr.next()) {
queryString += "," + gr.sys_id.toString();
}
current.addEncodedQuery(queryString);
})(current, parent);
Now, just add the Related List (REQ - Attachments) on the RITM form which ensures there is no duplication but you see all of related REQ's attachments.
Output:
REQ has 2 attachments.
RITM form shows 2 as below (Related list)
Thanks,
Jaspal Singh
https://www.servicenow.com/community/itsm-articles/avoid-duplicating-attachment-glidesysattachment-copy/ta-p/2315555