Error when trying to copy CI attributes
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-15-2024 11:25 AM
I'm working on a catalog item that takes some of the attributes of a CI (old CI) and updates the new/replacement CI with those attributes. Some of the attributes I'm copying are assigned_to, cost_center, and department. When I run the script (as a background script) it gets the values fine (new CI values=old CI values. However, whenever I add the update() function at the end of the script, I get this error:
*** Script: New Assigned To: 0e61011813340f00728879566144b0db
*** Script: New Cost Center: ea3db199dbc7034499d35434ce9619fc
*** Script: New Department: c17d7b28e438ce44165ea2fa95c10b6c
*** Script: Duplicate asset generation (Existing asset) prevented for CI 2001-1SGPH13
FAILED TRYING TO EXECUTE ON CONNECTION glide.8 (connpid=698838): INSERT INTO cmdb ...
java.sql.BatchUpdateException: (conn=698838) Duplicate entry 'd3dc09e41be60cd09f1ecb392a4bcbec' for key 'PRIMARY'
Here is my script:
var oldAssetID = '1705-7C18JH2';
var newAssetID = '2001-1SGPH13'
var asset = new GlideRecord('cmdb_ci');
asset.addActiveQuery('name', oldAssetID);
asset.query();
gs.print('Old AssetID: ' + oldAssetID);
gs.print('New AssetID: ' + newAssetID);
if (asset.get(oldAssetID)){
var oldAssignedTo = asset.assigned_to; //get assigned to value of old device
gs.print('Old Assigned To: ' + asset.assigned_to);
var oldCostCenter = asset.cost_center; //get cost center value of old device
gs.print('Old Cost Center: ' + asset.cost_center);
var oldDept = asset.department; //get dept name of old asset
gs.print('Old Dept: ' + asset.department);
}
var newAsset = new GlideRecord('cmdb_ci');
newAsset.addActiveQuery('name', newAssetID);
newAsset.query();
if (newAsset.get(newAssetID)){
newAsset.assigned_to = oldAssignedTo;
gs.print('New Assigned To: ' + newAsset.assigned_to);
newAsset.cost_center = oldCostCenter;
gs.print('New Cost Center: ' + newAsset.cost_center);
newAsset.department = oldDept;
gs.print('New Department: ' + newAsset.department);
newAsset.update();
}
When I remark out the newAsset.update() line, everything works fine - the sysIDs from the new ci fields match up with the old CI fields. Any idea on what I'm doing wrong? Is there a better way to do it?
I appreciate any/all help!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-17-2024 01:01 AM
Hi @KeithM1
The error you're encountering suggests that there's a primary key violation when you try to update the new CI. This typically indicates that the newAssetID you're using already exists in the database, so when you try to update it, the system considers it a duplicate entry.
To resolve this, you need to ensure that the newAssetID you're using is unique and does not already exist in the cmdb_ci table. If you're certain that it's unique, then there might be something else causing the issue.
Here are a few steps you can take to troubleshoot and potentially resolve the issue:
Check if the new CI already exists: Before attempting to update, you can check if the newAssetID already exists in the database. If it does, handle it accordingly (e.g., update the existing record instead of creating a new one).
Verify the uniqueness of the newAssetID: Ensure that the newAssetID you're using is indeed unique and not already present in the database. You can manually verify this in the cmdb_ci table.
Check for other constraints: Apart from the primary key constraint, there might be other constraints (unique constraints, foreign key constraints, etc.) that are causing the issue. Ensure that you're not violating any other constraints when performing the update.
Error handling: Implement error handling in your script to catch any exceptions that might occur during the update process. This will help you identify the exact cause of the issue.
Test with a different newAssetID: Try updating the new CI with a different newAssetID to see if the issue persists. This will help you determine if the problem is specific to the newAssetID you're using.
Additionally, consider using ServiceNow's built-in features like Business Rules or Workflows to handle CI updates. These features provide a more structured and efficient way to automate processes like this.
Here's a revised version of your script with error handling and additional checks:
// Your existing code...
if (newAsset.get(newAssetID)) {
// Check if the new CI already exists
gs.print('New CI already exists with ID: ' + newAssetID);
// Handle accordingly
} else {
// If new CI doesn't exist, proceed with update
newAsset.assigned_to = oldAssignedTo;
gs.print('New Assigned To: ' + newAsset.assigned_to);
newAsset.cost_center = oldCostCenter;
gs.print('New Cost Center: ' + newAsset.cost_center);
newAsset.department = oldDept;
gs.print('New Department: ' + newAsset.department);
try {
newAsset.update();
gs.print('Update successful!');
} catch (ex) {
gs.print('Error updating new CI: ' + ex);
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-18-2024 02:19 PM
The CI does exist. I'm just trying to copy some of the attributes from the "old CI" to the "new CI". The old CI has information like dept, location, who it's assigned to, etc. I just need that copied to the new CI. I could understand getting that message if I were trying to do an insert, but just an update, it is throwing me off. Is there a better way to copy those attributes from 1 CI to another within a workflow?