windows – 我需要避免尝试更新连接到TSQLQuery的Delphi TClient
Precis:我的代码试图更新Delphi XE TClientDataset中的非物理字段(连接到带有SQL属性集的TSQLQuery),这些字段是作为运行时Open命令创建的.
我有一个连接到连接到TSQLConnection的TSQLQuery的TDatasetProvider的TClientDataset.这些对象中的前3个被封装在库中的几个类中,我在几个项目的许多地方使用它们.这些类在运行时创建这3个对象,并消除了大量的重复代码,因为我有很多很多这样的三元组. 通常我会通过在TSQLQuery的SQL属性中指定一些SQL并在TClientDataSet上调用Open来从数据库加载TClientDataset. TClientDataset中的字段是通过调用Open ie创建的.它们在Open之前不存在. 在TClientDataset中生成的三个字段是非物理的情况下,我遇到了一个问题.也就是说,SQL会进行计算以生成它们.不幸的是,在TClientDataset中,这3个字段的创建方式与物理字段没有任何不同;他们的FieldKind是fkData(理想情况下它是fkInternalCalc),Calculated属性是False(理想情况下它是True),它们的ProviderFlags包括pfInUpdate(理想情况下它不应该).毫不奇怪,当需要在TClientDataset上执行ApplyUpdates时,会抛出异常… Project XXX.exe raised exception class TDBXError with message SQL State: 42S22,SQL Error Code: 207 Invalid column name 'Received'. SQL State: 42S22,SQL Error Code: 207 Invalid column name 'Issued'. SQL State: 42S22,SQL Error Code: 207 Invalid column name 'DisplayTime'. 我可以通过清除TDatasetProvider的OnUpdateData事件处理程序中的这些字段的pfInUpdate标志来避免此错误.但是,此解决方案要求此函数知道特定的字段名称,该函数位于上述泛型类中,从而破坏了代码的通用性. 我正在寻找的是将这些字段的计算性质用信号通知给事件处理函数的通用方法. 在Open调用之后,我无法更改其FieldKind或Calculated属性(分别为fkInternalCalc和True),因为这会生成WorkCDS:无法对打开的数据集异常消息执行此操作.并且,我无法在Open调用之前更改这些属性,因为Fields还不存在. 我可以在打开后从这些Field的ProviderFlags属性中删除pfInUpdate标志,但这不会传递到到达OnUpdateData事件处理程序的“Delta”TClientDatset.我还尝试设置字段的FieldDefs.InternalCalcField属性;再次,这不会传递到Delta数据集. 所以,我尝试过的所有信号传递方法都没有奏效.我会对任何新想法或替代方法表示感谢. 我遇到的所有互联网搜索结果 – 包括Cary Jensen的优秀文章 – 处理的设计时或非SQL生成的设置都不适用于我的情况.
您可以在类中创建一种机制,为要在更新过程中忽略的各个字段预先配置ProviderFlags.
根据您对问题的评论,我建议您在类中创建一个新方法来打开内部ClientDataSet,所有魔法都将在此方法中进行. 首先,一个简单的机制是包含一个新的TStringList属性,该属性列出了您要忽略的所有字段,您将按名称进行匹配.随意采用这个或创建一个新的更好的机制,重要的是你能够识别出你想要配置哪个字段. type TMyClass = class // all your current class here private FUpdateIgnoredFields: TStringList; public property UpdateIgnoredFields: TStringList read FUpdateIgnoredFields write SetUpdateIgnoredFields; //don't forget to create this in your constructor,free it in the destructor //and Assign any new value in the SetUpdateIgnoreFields method,as usual. procedure OpenInnerCDS; //the magic goes here end; procedure TMyClass.OpenInnerCDS; var FieldName: string; AFieldToIgnore: TField; begin //opens the inner cds,but before that,configures the update-ignored //fields in the underlying dataset //Let's call it InnerBaseDataSet; FInnerBaseDataSet.Open; //this opens the DataSet and creates all the fields for it. try for FieldName in FUpdateIgnoredFields do begin AFieldToIgnore := FInnerBaseDataSet.FindField(FieldName); if Assigned(AFieldToIgnore) then AFieldToIgnore.ProviderFlags := AFieldToIgnore.ProviderFlags - [pfInUpdate,pfInWhere]; end; //now,let's open the ClientDataSet; FInnerClientDataSet.Open; finally //I suggest no matter what happens,always close the inner data set //but it depends on how the CDS->Provider->DataSet interaction is configured FInnerBaseDataSet.Close; end; end; //the way you use this is to replace the current ClientDataSetOpen with something like: var MyInsance: TMyClass; begin MyInstance := TMyInstance.Create(); //params try //configuration code here //MyInstance.InnerCDS.Open; <-- not directly now MyInstance.UpdateIgnoreFields.Add('CALCULATED_SALARY'); MyInstance.OpenInnerCDS; //use the CDS here. MyInstance.InnerCDS.ApplyUpdates(-1); //safely apply updates now. finally MyInstance.Free; end; end; 把它作为一个想法. 我在这里编写了所有代码,也许语法错了,但它显示了整个想法. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- .net – 如何打包单个文件的Windows EXE进行下载
- 用户友好的端口敲门器(端口敲门客户端)适用于Win
- windows – 如何找出远程主机上启用的SMB版本?
- windows-phone-7.1 – Windows Phone – PhotoCh
- 在Windows服务上C#&NHibernate“无法编译映射
- windows – WinRT和软件ClearType字体渲染
- 为什么我的编辑控件在我的win32 c应用程序中看起
- 如何使用wamp在windows上烘焙cakephp 2.0应用程序
- windows-server-2008 – Hyper-V服务器上的神秘状
- 批处理文件 – Windows CMD批处理:具有DelayedE