Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Delphi中使用SQLite附加-分离时出错_Sqlite_Delphi_Delphi 10 Seattle - Fatal编程技术网

在Delphi中使用SQLite附加-分离时出错

在Delphi中使用SQLite附加-分离时出错,sqlite,delphi,delphi-10-seattle,Sqlite,Delphi,Delphi 10 Seattle,我在使用Delphi(Firedac)的SQLite中遇到了一个无法解决的附加和分离问题 我连接了一个数据库文件,并附加了第二个数据库文件: FDConnection1.ExecSQL('ATTACH DATABASE "' + Import_DB_filename + '" AS IMPORTDB;'); 其中,变量“Import_DB_filename”包含数据库文件的完整路径和文件名 这工作正常,我可以通过FireDac查询访问连接中的两个数据库,并且可以毫无问题地进行编码。 但是,分离

我在使用Delphi(Firedac)的SQLite中遇到了一个无法解决的附加和分离问题

我连接了一个数据库文件,并附加了第二个数据库文件:

FDConnection1.ExecSQL('ATTACH DATABASE "' + Import_DB_filename + '" AS IMPORTDB;');
其中,变量“Import_DB_filename”包含数据库文件的完整路径和文件名

这工作正常,我可以通过FireDac查询访问连接中的两个数据库,并且可以毫无问题地进行编码。 但是,分离时会出现问题:

FDConnection1.ExecSQL('DETACH DATABASE IMPORTDB;');
在调试模式下,我总是得到错误:

调试器异常通知
E Project My_Program.EXE引发异常类$C0000005,消息为“0x00405d7b处的访问冲突:读取地址0x00000000”

显然内存分配出了问题,因为调试器在(汇编)函数
sysfreemm(p:Pointer):Integer中停止
GETMEM.INC

无论我尝试什么,错误都会持续存在,并导致内存泄漏,最终导致编译器崩溃(Delphi Seattle Enterprise)

即使在不传递任何代码的情况下附加和随后分离数据库,也会导致相同的错误

(FD连接:锁定模式=lmNormal; JournalMode=jmOff或jmWALL或jmdelete)


我真的希望你能帮我解决这个持久的问题。

如果你运行下面的项目,你会发现:

  • 您可以使用单独的FDConnections和FDTables非常愉快地访问两个Sqlite数据库

  • 可以使用FireDAC FDDataMove组件将数据从一个db中的表移动到另一个db中同名的表

代码:


可以肯定的是:您已经有了一个正确的连接,现在您想使用添加另一个数据库文件到当前连接?请将您的问题包括在Delphi版本中。为什么需要对两个数据库文件使用相同的FD连接?为什么不为它们各自建立一个单独的连接呢?老实说,我不确定我是否已经尝试过了。我会检查的。谢谢你的建议。我想使用一个FDConnection,因为我使用“insert…select”语句将数据从第二个数据库复制到现有数据库中。不管怎样,如果你在代码中生成Sql语句,你都可以这样做。谢谢MartynA,谢谢MartynA,您让我相信,使用两个FDConnection组件是避免使用ATTACH和DETACH的好方法。我已经相应地更改了代码。但是,错误仍然存在。显然,它和连接关系不大,而是和记忆分配有关。我一定是在什么地方搞砸了。也许你能提示我如何解决这些错误。我安装了MadExcept,但它没有给我任何线索。不幸的是,十六进制地址对我来说就像中文一样。好吧,“读取地址0x00000000”表明有些东西没有正确初始化,可能是一个Delphi对象,它以前被访问过。Create()被调用过。确保在项目选项中启用了“使用调试DCU”,然后进行项目构建并运行。当错误发生时,在IDE中转到查看|调试窗口|调用堆栈,然后您应该能够向下查看堆栈并查看异常发生的位置。
unit BatchMoveu;

interface

[...]

type
  TForm3 = class(TForm)
    FDConnection1: TFDConnection;
    DBGrid1: TDBGrid;
    DataSource1: TDataSource;
    DBNavigator1: TDBNavigator;
    FDGUIxWaitCursor1: TFDGUIxWaitCursor;
    FDPhysSQLiteDriverLink1: TFDPhysSQLiteDriverLink;
    Button1: TButton;
    FDTable1: TFDTable;
    FDConnection2: TFDConnection;
    DataSource2: TDataSource;
    DBGrid2: TDBGrid;
    btnBatchMove: TButton;
    FDDataMove1: TFDDataMove;
    FDTable2: TFDTable;
    procedure btnBatchMoveClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    procedure PopulateTable1;
    procedure TestDataMove;
  public
    procedure CreateDatabase(DBName : String; FDConnection : TFDConnection;
      FDTable : TFDTable);
  end;

var
  Form3: TForm3;

implementation

{$R *.dfm}

const
  DBName1 = 'd:\delphi\code\sqlite\db1.sqlite';
  DBName2 = 'd:\delphi\code\sqlite\db2.sqlite';

procedure TForm3.Button1Click(Sender: TObject);
begin
  CreateDatabase(DBName1, FDConnection1, FDTable1);
  CreateDatabase(DBName2, FDConnection2, FDTable2);

  PopulateTable1;

  FDTable2.Open;

end;

procedure TForm3.CreateDatabase(DBName : String; FDConnection : TFDConnection;
  FDTable : TFDTable);
var
  AField : TField;
  i : Integer;
begin
  if FileExists(DBName) then
    DeleteFile(DBName);

  AField := TLargeIntField.Create(Self);
  AField.FieldName := 'ID';
  AField.DataSet := FDTable;
  AField.Name := AField.DataSet.Name + 'IDField';

  AField := TWideStringField.Create(Self);
  AField.Size := 80;
  AField.FieldName := 'Name';
  AField.DataSet := FDTable;
  AField.Name := AField.DataSet.Name + 'NameField';

  FDConnection.Params.Values['database'] := DBName;
  FDConnection.Connected:= True;
  FDTable.CreateTable(False, [tpTable]);
end;

procedure TForm3.PopulateTable1;
var
  i : Integer;
begin
  FDTable1.Open;

  for i:= 1 to 1000 do begin
    FDTable1.InsertRecord([i, 'Row ' + IntToStr(i)]);
  end;
  FDTable1.Close;
  //FDConnection1.Commit;

  FDTable1.Open;
end;

procedure TForm3.TestDataMove;
var
  Item : TFdMappingItem;
begin
  Item := FDDataMove1.Mappings.Add;
  Item.SourceFieldName := 'ID';
  Item.DestinationFieldName := 'ID';

  Item := FDDataMove1.Mappings.Add;
  Item.SourceFieldName := 'Name';
  Item.DestinationFieldName := 'Name';

  FDDataMove1.Source := FDTable1;
  FDDataMove1.Destination := FDTable2;
  FDDataMove1.Options := FDDataMove1.Options - [poOptimiseSrc];
  FDDataMove1.Execute;

  FDConnection2.Connected := False;
  FDTable2.Open;
end;
procedure TForm3.btnBatchMoveClick(Sender: TObject);
begin
  TestDataMove;
end;

procedure TForm3.FormDestroy(Sender: TObject);
begin
  FDConnection1.Close;
end;

end.