Select to view content in your preferred language

Use database sequence function from AGOL layer/table to generate unique integer IDs?

142
3
Sunday
Bud
by
Legendary Contributor

It’s possible to automatically populate the default value of an AGOL hosted feature layer GUID field using NEWID() WITH VALUES, using the Admin REST API.

https://community.esri.com/t5/arcgis-online-questions/add-guid-field-to-existing-agol-survey123-feat... 

Is there a way to do something similar, but instead of populating a GUID field, populate a sequential integer in a number field? (Or a textual ID with a prefix like SEWER-0000001 ?)

For example, is there a function similar to NEWID() that gets the next available integer for the layer/table from a database sequence?

An integer would be preferable over a GUID because it’s shorter and human-readable. All of our other asset IDs are integers or text-integer format, not GUIDs.

0 Kudos
3 Replies
Bud
by
Legendary Contributor

Would someone with DBA privileges in an on-prem Portal datastore database be able to poke around in a table to see if there are any database sequences used that would also be available in AGOL?

(This is more of an “out of curiosity” thing to see if we can learn anything interesting, not necessarily something that should be done in a mission-critical AGOL feature layer without testing.)

0 Kudos
RyanUthoff
MVP Regular Contributor

I'm not sure if this would be an acceptable solution for you, but you might be able to do that through AGOL Notebooks. You'd be able to define your own SQL expression to calculate the Unique ID in the format you are needing. The downside is that the calculation wouldn't be immediate. The AGOL Notebook would run either on demand or on a schedule.

https://community.esri.com/t5/arcgis-online-questions/auto-calculate-unique-id-in-hosted-feature-ser...

Attribute rules would be a good solution, but that only works on ArcGIS Enterprise and not AGOL unfortunately. 

snowdrop7934
New Contributor

This is the arcade code that comes with the sign solution I just deployed, but it requires edits be made in a web map or app, not really on the data directly like an attribute rule would. This is added in the Form Editor of the web map.

 

var layerIndex = '0'
var idField = 'assetid'
var idPrefix = 'SIGN-'
var digits = 6

/*DO NOT CHANGE ANYTHING BELOW THIS LINE
-------------------------------------------------------------------------*/

function GenerateWildcards(digits, wildcard) {
var wildcards = ''
for (var i=0; i < digits; i++) {
wildcards += wildcard
}
return wildcards
}

function GetNextId(layerIndex, idField, idPrefix, padding, sqlFilter) {
// get the feature with the greatest assetid that matches the id pattern specified in the SQL statement.
var assetid_features = Filter(FeatureSetById($datastore, layerIndex, [idField], false), sqlFilter)
var max_assetid_feature = First(OrderBy(assetid_features, `${idField} DESC`))

// If no features match the pattern the featureset will be null, return the first assetid
if(max_assetid_feature == null) {
return `${idPrefix}${Right(padding, Count(padding)-1)}1`
}

// when features do match the pattern calculate and return the next assetid
var max_assetid = max_assetid_feature[idField]

var next_assetid_number = Number(Replace(max_assetid, idPrefix, "")) + 1
return `${idPrefix}${Text(next_assetid_number, padding)}`
}

// Define the edit context so the value is only calculated when the feature is created
if ($editContext.editType == "INSERT") {
// return matching prefix pattern and get next value
var wildcards = GenerateWildcards(digits, '_')
var padding = GenerateWildcards(digits, '0')
if (idPrefix != '') {
var sqlFilter = `${idField} LIKE '${idPrefix}${wildcards}' AND ${idField} NOT LIKE '%[^0-9]'`
GetNextId(layerIndex, idField, idPrefix, padding, sqlFilter)
}

// return number id's only and get next value
else {
var sqlFilter = `${idField} NOT LIKE '%[^0-9.]%'`
GetNextId(layerIndex, idField, idPrefix, padding, sqlFilter)
}

}
else {
return $feature[idField]
}