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

使用Delphi 12开发多设备应用时,为何出现未涉及列的报错?

Delphi 12 跨设备SQLite表同步及FDTable报错问题解决

问题描述

  • 使用Delphi 12开发跨设备应用,SQLite数据库包含Profile表
  • 数据模块配置FDConnection和FDTable,FDTable关联Profile表,桌面端运行正常,但Android调试时仅空数据库文件被传输,表未同步
  • 从DB Browser for SQLite复制CREATE TABLE语句成功创建表后,执行FDTable1.Open报错,提示存在A.MOBILE列,但实际表中无此列,且DB Browser中可正常操作该表

代码片段

procedure TDataModule2.FDConnection1AfterConnect(Sender: TObject);
begin
 if FDConnection1.DataSetCount = 0 then
begin
    FDConnection1.ExecSQL('CREATE TABLE IF NOT EXISTS "Profile" (   "Firstname" TEXT NOT NULL,"Lastname"    TEXT NOT NULL, " Street1 " TEXT NOT NULL, " Street2 " TEXT, " City " TEXT NOT NULL, " Apartment " TEXT, " Building " TEXT, " State " TEXT NOT NULL, " Zip " TEXT NOT NULL, " Phone " TEXT," Email " TEXT, " Mobile " TEXT NOT NULL UNIQUE, " Refby " TEXT, " Starch " TEXT, " RecEmail " INTEGER DEFAULT 1," RecSMS " INTEGER DEFAULT 1, " Verified " INTEGER DEFAULT 0," RefCode " TEXT, " CustomerID " INTEGER,PRIMARY KEY(" Mobile "))');
    FDTable1.Open;
    FDTable1.Append;
end
else
begin
     FDTable1.Open;
end;
end;

procedure TDataModule2.FDConnection1BeforeConnect(Sender: TObject);
var
dbPath: String;
begin
dbPath := 'C:\ComcaMobileDelphi\database\ComcaMApp.db';

{$IF DEFINED(IOS) or DEFINED(ANDROID)}
dbPath := TPath.GetDocumentsPath + PathDelim + 'ComcaMApp.db';
{$ENDIF}

FDConnection1.Params.Values['Database'] := dbPath;
end;

解决步骤

1. 修正数据库文件同步逻辑

Android端仅传输空数据库文件,需确保首次启动时同步完整带表结构的数据库:

  • 检查BeforeConnect中的路径配置,确认移动端是否复制了正确的数据库文件(而非空文件)
  • 若采用动态建表方式,执行CREATE TABLE后可添加验证语句确认表结构:
    FDConnection1.ExecSQL('PRAGMA table_info(Profile)');
    // 读取结果集确认列名是否与预期一致
    

2. 解决A.MOBILE列报错问题

报错中的A.MOBILE是FDTable自动生成的别名格式,核心原因是FDTable字段定义与实际表结构不匹配:

  • 打开数据模块,右键FDTable选择Field Editor,点击Add All Fields,确保字段与数据库表列完全同步
  • 检查FDTable的TableName属性是否准确设置为Profile,删除手动添加的多余字段
  • 修正CREATE TABLE语句中的列名:你的语句中列名如" Street1 "包含前后空格,导致实际列名带空格,FDTable会按无空格名称匹配,需改为"Street1"、"Mobile"等无空格格式

3. 优化表创建逻辑

原代码中FDConnection1.DataSetCount = 0的判断逻辑不准确,改为直接检查表是否存在:

procedure TDataModule2.FDConnection1AfterConnect(Sender: TObject);
var
  TableExists: Boolean;
begin
  TableExists := False;
  FDConnection1.ExecSQL('SELECT name FROM sqlite_master WHERE type=''table'' AND name=''Profile''');
  if FDConnection1.ResultSet.RecordCount > 0 then
    TableExists := True;

  if not TableExists then
  begin
    FDConnection1.ExecSQL('CREATE TABLE IF NOT EXISTS "Profile" (   "Firstname" TEXT NOT NULL,"Lastname" TEXT NOT NULL, "Street1" TEXT NOT NULL, "Street2" TEXT, "City" TEXT NOT NULL, "Apartment" TEXT, "Building" TEXT, "State" TEXT NOT NULL, "Zip" TEXT NOT NULL, "Phone" TEXT,"Email" TEXT, "Mobile" TEXT NOT NULL UNIQUE, "Refby" TEXT, "Starch" TEXT, "RecEmail" INTEGER DEFAULT 1,"RecSMS" INTEGER DEFAULT 1, "Verified" INTEGER DEFAULT 0,"RefCode" TEXT, "CustomerID" INTEGER,PRIMARY KEY("Mobile"))');
  end;
  FDTable1.Open;
end;

4. 移动端数据库文件部署优化

确保首次启动时将桌面端完整数据库复制到移动端路径:

  • 将ComcaMApp.db添加到项目,设置Deployment属性,部署到移动端assets\internal目录
  • 修改BeforeConnect逻辑,先检查文件是否存在,不存在则从assets复制:
procedure TDataModule2.FDConnection1BeforeConnect(Sender: TObject);
var
  dbPath, assetPath: String;
begin
  dbPath := 'C:\ComcaMobileDelphi\database\ComcaMApp.db';

  {$IF DEFINED(IOS) or DEFINED(ANDROID)}
  dbPath := TPath.GetDocumentsPath + PathDelim + 'ComcaMApp.db';
  if not TFile.Exists(dbPath) then
  begin
    assetPath := TPath.GetAssetsPath + PathDelim + 'ComcaMApp.db';
    TFile.Copy(assetPath, dbPath);
  end;
  {$ENDIF}

  FDConnection1.Params.Values['Database'] := dbPath;
end;

内容的提问来源于stack exchange,提问作者Kim HJ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 10:11:21