使用 ADOQuery 和 Delphi 10.2 保持更新查询值不变

Leave Update Query Value Unchanged with ADOQuery and Delphi 10.2

我在两个相互交换数据的系统之间有一个接口。这是一个可以通过 GUI 修改的默认界面,例如,您可以选择在两侧使用一组字段,或者您可以选择保留值。

现在在我的代码中有 UPDATE SQL 查询看起来像那样

UPDATE TABLE1 SET
FIELD1_GROUP1=:FIELD1_GROUP1,FIELD2_GROUP1=:FIELD2_GROUP1,FIELD3_GROUP1=:FIELD3_GROUP1,
FIELD1_GROUP2=:FIELD1_GROUP2,FIELD2_GROUP2=:FIELD2_GROUP2,FIELD3_GROUP2=:FIELD3_GROUP2

ADOQuery.Parameters.ParamByName('FIELD1_GROUP1').Value := MyField1_Group1_From_SystemB;
....

现在如果我选择不使用 GROUP2,则无法保留参数未设置。我找到了一个适用于

之类的解决方案
if USE_GROUP2 then
begin
ADOQuery.SQL.add(FIELD1_GROUP2=:FIELD1_GROUP2,FIELD2_GROUP2=:FIELD2_GROUP2,FIELD3_GROUP2=:FIELD3
_GROUP2);
  ADOQuery.Parameters.ParamByName('FIELD1_GROUP1').Value := MyField1_Group1_From_SystemB;
  ...
end;

但是那种解决方案会妨碍我的系统在每个使用 SQL 的函数的开头看到完整的 SQL QUERY。它会将我们干净的代码分解成可读性差的块。

我想知道参数是否没有删除其值内参数的功能。 感谢帮助

您可以在查询中使用合并将字段更新为它已有的值:

UPDATE TABLE1 SET
  FIELD1_GROUP1=COALESCE(:FIELD1_GROUP1, FIELD1_GROUP1) 
  ... 

但这有一些潜在的问题。

首先,很清楚,这将不允许您再将字段更新为 NULL。当然,您可以通过不使用 COALESCE 来解决这个问题,而是使用一个 CASE 检查一个额外的参数,该参数指示是否应该更新第 2 组。

其次,更难确定的后果取决于您使用的数据库,这可能会或可能不会影响触发器的执行方式and/or如何计算更新语句的行数。这可能不会立即成为问题,但您可能会看到这会如何导致整个 class 难以调试的问题。

因此,虽然这可能是一个解决方案,但我建议编写一个语句来准确更新并且只更新您需要更新的字段。这意味着要么有两个语句(一个包含 group2,一个不包含),或者根据您需要更新的内容动态构建 SQL。

我也希望有确切的 SQL,所以我更喜欢有两个明确的陈述,但根据情况我可能会选择其他解决方案。这个决定取决于你。