如何处理IFeatureCursor.UpdateFeature不能更新MDB的问题?
如何处理IFeatureCursor.UpdateFeature不能更新MDB的问题?
上周有个同事要我帮忙把土地利用图斑的村名写到BLOCK_CODE字段中,因为只能根据空间关系来做,所以最好写程序。刚开始以为这样的小问题,半个小时不到应该就能解决,没想到折腾了一个下午也没有完全搞定。每次执行到UpdateFeature就出错,说数据库被锁定或者只读。实在没有办法了上ESRI的User Forums上查了查,通常别人应该也会碰到和我类似的问题,结果的确找到不少,不过感觉不是正解。他们说要用IFeature.Store代替UpdateFeature,但是UpdateFeature可以批量提交性能会好些,而且也没有找出导致不能更新的根本原因。因为我发现UpdateFeature方法不是所有情况下都不能用,比如我写了一个简单的函数,所有的Feature赋上同样的值是可以的,所以我坚信肯定是别的原因导致这个错误。因为村相对于图斑要少得多,一个区县村通常只有近百个,而图斑达数万甚至几十万。如果用区县来选择图斑可以减少查询的次数,速度应该会快一点。所以我采用一个只读的Search Cursor内嵌套可更新的Update Cursor,我发现论坛上的那些人也是这样的模式,有些人说是Update Cursor锁定了表,对象没有释放,但是即便你用完后用Set pCursor = Nothing也于事无补。周末我有空就在思考这个问题,感觉应该把Update Cursor放在外面可能能够解决问题,结果真如我想象的那样,UpdateFeature工作得很好!
关键代码如下:
featureCount=0
SetpLCursor=pLandUseFC.Update(Nothing,False)
SetpLFeature=pLCursor.NextFeature
DoWhileNotpLFeatureIsNothing
IfIsNull(pLFeature.Value(fldLBlock))Then
blockCode=""
Else
blockCode=pLFeature.Value(fldLBlock)
EndIf
SetpSpatialFilter.Geometry=pLFeature.Shape
SetpVCursor=pVillageFC.Search(pSpatialFilter,False)
SetpVFeature=pVCursor.NextFeature
DoWhileNotpVFeatureIsNothing
IfNotIsNull(pVFeature.Value(fldVBlock))Then
IfblockCode=""Then
blockCode=pVFeature.Value(fldVBlock)
Else
blockCode=blockCode&","&pVFeature.Value(fldVBlock)
EndIf
EndIf
SetpVFeature=pVCursor.NextFeature
Loop
pLFeature.Value(fldLBlock)=blockCode
pLCursor.UpdateFeaturepLFeature
featureCount=featureCount+1
IffeatureCount=1000Then
pLCursor.flush
featureCount=0
EndIf
SetpLFeature=pLCursor.NextFeature
Loop
pLCursor.flush
SetpLCursor=pLandUseFC.Update(Nothing,False)
SetpLFeature=pLCursor.NextFeature
DoWhileNotpLFeatureIsNothing
IfIsNull(pLFeature.Value(fldLBlock))Then
blockCode=""
Else
blockCode=pLFeature.Value(fldLBlock)
EndIf
SetpSpatialFilter.Geometry=pLFeature.Shape
SetpVCursor=pVillageFC.Search(pSpatialFilter,False)
SetpVFeature=pVCursor.NextFeature
DoWhileNotpVFeatureIsNothing
IfNotIsNull(pVFeature.Value(fldVBlock))Then
IfblockCode=""Then
blockCode=pVFeature.Value(fldVBlock)
Else
blockCode=blockCode&","&pVFeature.Value(fldVBlock)
EndIf
EndIf
SetpVFeature=pVCursor.NextFeature
Loop
pLFeature.Value(fldLBlock)=blockCode
pLCursor.UpdateFeaturepLFeature
featureCount=featureCount+1
IffeatureCount=1000Then
pLCursor.flush
featureCount=0
EndIf
SetpLFeature=pLCursor.NextFeature
Loop
pLCursor.flush