tpcolson

Error: The selected field is a required field and cannot be deleted....whatever!

Blog Post created by tpcolson on Feb 23, 2018

Have you ever gotten this Error: The selected field is a required field and cannot be deleted ? Scratching my head, wondering how I checked "Field IsRequired". The official solution, export the feature class to another feature class and do some field mapping magic, then delete the original, import the changed one......not. See, all of my feature classes are baked into an enterprise geodatabase with all kinds of dependencies and relationships (that's kinda the point of an enterprise geodatabase, right?). 

 

There's a quicker and easier way to resolve this issue. I spend a lot of time editing metadata in its native XML (faster, and I can automate things easier), so why not edit a feature class definition, which is also in XML? Feature class definitions live in a XML column (Definition) in the GDB_ITEMS table. 

 

Click on the xml in the definition column, and you'll see the raw schema for the feature class. Look for the name of the attribute that allegedly won't let you delete it: 

<GPFieldInfoEx xsi:type="typens:GPFieldInfoEx">
<Name>GIS_LOCATION_ID</Name>
<ModelName>GIS_LOCATION_ID</ModelName>
<FieldType>esriFieldTypeGUID</FieldType>
<IsNullable>false</IsNullable>
<Required>true</Required>
<Editable>false</Editable>
</GPFieldInfoEx>

Note the Required tag. Ok, so we've figured out what's causing the problem, now, how to fix it. Updating  XML in SQL is pretty straightforward, if you're replacing the entire string. Updating specific nodes and elements in SQL is a little trickier (but possible). In the code below, note the =N'  before the xml definition. I've left out a lot of the other xml, but what I did was copied the entire XML definition and pasted it after the =N' . There's a ' at the end. Also note the WHERE [Name] = 'WETLANDS.DBO.GRSM_HYDRO_WETLAND_PT' which constrains the update to just that feature class with the supposedly undeletable attribute.

 

UPDATE [dbo].[GDB_ITEMS]
SET [Definition] =N'<DEFeatureClassInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:typens="http://www.esri.com/schemas/ArcGIS/10.5" xsi:type="typens:DEFeatureClassInfo">
<CatalogPath>\WETLANDS.DBO.GRSM_HYDRO_WETLAND_PT</CatalogPath>
<Name>WETLANDS.DBO.GRSM_HYDRO_WETLAND_PT</Name>
<ChildrenExpanded>false</ChildrenExpanded>
<DatasetType>esriDTFeatureClass</DatasetType>
<DSID>435</DSID>
<Versioned>false</Versioned>
<CanVersion>true</CanVersion>
<ConfigurationKeyword />
<RequiredGeodatabaseClientVersion>10.2</RequiredGeodatabaseClientVersion>
<HasOID>true</HasOID>
<OIDFieldName>OBJECTID</OIDFieldName>


blah blah blah

<GPFieldInfoEx xsi:type="typens:GPFieldInfoEx">
<Name>GIS_LOCATION_ID</Name>
<ModelName>GIS_LOCATION_ID</ModelName>
<FieldType>esriFieldTypeGUID</FieldType>
<IsNullable>true</IsNullable>
</GPFieldInfoEx>

blah blah blah

<ChangeTracked>true</ChangeTracked>
<FieldFilteringEnabled>false</FieldFilteringEnabled>
<FilteredFieldNames xsi:type="typens:Names" />
</DEFeatureClassInfo>'
WHERE [Name] = 'WETLANDS.DBO.GRSM_HYDRO_WETLAND_PT'

You'll see, somewhere in the middle, I changed the attribute restrictions to be just like any other attribute: one I can delete. 

 

Close and restart Arc Catalog to see the change (and delete the attribute). It goes without saying that you should pull a full back up of your SQL before doing this, and should test this on a non-production database, first! Also note this won't work on a GlobalID field (e.g if you have a GLobalID attribute but it's not named GlobalID), there's a few more changes you have to make to alter that one, and you shouldn't view this method as a way to alter the table schema physical design. 

 

Disclaimer: Editing the underlying GDB tables in this manner is not not supported by ESRI..with that out of the way, there's a lot of DB administration you can pull off with manipulation of the XML definitions. I've used this with great success in exporting a "workspace", editing the XML to implement some find and replace changes, then import as a new GDB. 

Outcomes