如何控制MyDAC的TMyQuery组件仅更新实际修改的字段
MyDAC TMyQuery 自定义字段更新报错与并发覆盖问题解决
问题场景
使用MyDAC套件的TMyQuery组件时,执行如下查询:
SELECT id, name, salary, 'n' as modified FROM employees
修改SALARY与MODIFIED字段提交时,会触发报错:Unknown column MODIFIED in field list。
目前已知的临时处理方式是手动给SQLUpdate属性指定固定更新语句:
UPDATE employees SET name = :name, salary = :salary WHERE id = :id
但该方案存在严重的并发风险:无论用户实际修改了哪个字段,写死在语句里的name、salary字段都会被同步更新。典型异常场景为:同一时间,终端A修改了NAME字段,终端B修改了SALARY字段,最后提交的更新会直接覆盖前者的修改,造成数据丢失。
正确配置方案
不需要手写固定全字段更新语句,通过组件自带属性配置即可实现「仅更新实际修改字段+跳过不存在的别名计算字段」,从根源解决报错和并发覆盖问题:
- 首先处理别名字段报错:给查询添加持久化字段,找到自定义别名生成的
modified字段,将它的ProviderFlags属性集合中的pfInUpdate标记移除。这个字段是查询时临时生成的计算字段,物理表中并不存在,标记为不参与更新后,组件生成更新SQL时会自动跳过该字段,直接解决列不存在的报错。 - 然后关闭全字段更新逻辑:找到
TMyQuery的Options.UpdateAllFields属性,将值设置为False。该属性默认值为True,会把SELECT语句查出的所有字段都放到UPDATE语句的SET子句中;设为False后,组件会自动追踪字段修改状态,仅将实际被改动的字段加入更新语句,未修改的字段不会出现在SET子句中,完全避免无意义的字段覆盖。 - 校验配置效果:可以开启MyDAC的SQL执行日志,测试单字段修改场景:仅修改
salary字段时,组件自动生成的更新语句会是UPDATE employees SET salary = ? WHERE id = ?,不会携带未修改的name字段,也不会出现不存在的modified字段。
补充说明:如果
modified字段是用来做前端界面状态标记(比如行数据被编辑过就把该字段值改为'y'提示用户),上述配置不会影响你在内存中修改该字段的值,只是不会把这个临时字段提交到数据库,不影响任何前端交互逻辑。
内容的提问来源于stack exchange,提问作者Elivaldo
相关产品推荐
相关产品推荐

