You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi 10.4代码报E2029错误:期望'('却找到'THEN'求助

问题解决:Delphi 10.4中E2029语法错误及日期数据处理问题

错误原因分析

你遇到的E2029语法错误,根源是**TDateTime是值类型而非类类型**,不能直接和TJSONValue.ClassType(返回TClass类型)做比较。编译器误以为你要调用TDateTime()函数,因此提示需要左括号(。

另外,你的代码还存在其他逻辑问题:

  • 仅在循环外调用了一次MemTable.Insert,无法正确插入多条JSON数据
  • 内层循环每次都调用MemTable.Edit,属于冗余操作
  • 直接将JSON值转为字符串赋值给字段,未处理日期类型的转换,会导致程序崩溃

修复后的代码

procedure InjectJSONIntoTable(Query: TFDQuery;
                              MemTable: TFDMemTable; Edit: TEdit);
var
  jsonString: string;
  jsonArr: TJSONArray;
  jsonItem: TJSONObject;
  jsonValue: TJSONValue;
  i, j: Integer;
  FieldName: string;
begin
  // 执行SQL查询
  Query.SQL.Text := Edit.Text;
  Query.Open;
  try
    // 获取JSON字符串
    jsonString := Query.FieldByName('jdoc').AsString;
    jsonArr := TJSONObject.ParseJSONValue(jsonString) as TJSONArray;
    if not Assigned(jsonArr) then Exit;
    try
      // 准备内存表
      MemTable.Close;
      MemTable.CreateDataSet;
      MemTable.Open;

      // 遍历JSON数组中的每个对象
      for i := 0 to jsonArr.Count - 1 do begin
        jsonItem := jsonArr.Items[i] as TJSONObject;
        if not Assigned(jsonItem) then Continue;

        // 插入新行
        MemTable.Append;
        try
          // 遍历内存表的每个字段
          for j := 0 to MemTable.FieldDefs.Count - 1 do begin
            FieldName := MemTable.FieldDefs[j].Name;
            jsonValue := jsonItem.GetValue(FieldName);
            if Assigned(jsonValue) then begin
              // 根据字段类型处理JSON值
              case MemTable.FieldDefs[j].DataType of
                ftDateTime: begin
                  // 处理日期类型:JSON中通常为字符串或时间戳
                  if jsonValue is TJSONString then
                    MemTable.Fields[j].AsDateTime := StrToDateTime(TJSONString(jsonValue).Value)
                  else if jsonValue is TJSONNumber then
                    MemTable.Fields[j].AsDateTime := UnixToDateTime(TJSONNumber(jsonValue).AsInt64);
                end;
                else begin
                  // 其他类型直接赋值字符串
                  MemTable.Fields[j].AsString := jsonValue.Value;
                end;
              end;
            end;
          end;
          // 提交当前行
          MemTable.Post;
        except
          MemTable.Cancel;
          raise;
        end;
      end;
    finally
      jsonArr.Free;
    end;
  finally
    Query.Close;
  end;
end;

关键修复点

  1. 修正类型判断逻辑:
    • 不再错误地将TDateTime和ClassType比较,而是通过jsonValue is TJSONString/TJSONNumber判断JSON值类型,结合内存表字段的DataType来处理日期转换
  2. 修复数据插入逻辑:
    • 每个JSON对象对应内存表的一行,每次循环调用MemTable.Append创建新行
    • 用try...except包裹行操作,出错时取消当前行插入,避免数据异常
  3. 资源安全处理:
    • 添加try...finally确保TFDQuery和TJSONArray资源被正确释放,避免内存泄漏
  4. 日期转换处理:
    • 针对JSON中常见的日期存储形式(字符串、Unix时间戳),分别用StrToDateTime和UnixToDateTime转换为Delphi的TDateTime类型,避免崩溃

内容的提问来源于stack exchange,提问作者Rafael Sampaio Moura

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 16:55:27