【问题标题】:Show sqlite database in Delphi XE6 using firedac programmatically以编程方式使用 fireac 在 Delphi XE6 中显示 sqlite 数据库
【发布时间】:2014-11-23 17:20:13
【问题描述】:

我是使用 Delphi 的数据库新手。实际上我需要使用firedac在gridview中显示所有表格及其数据。 youtube 和 docwiki 上的几个视频教授了如何通过可视化组件访问数据库,即在表单上抛出 FDConnetion、FDTable、DataSource 等。

但我想以编程方式做同样的事情,以便我可以更专注于编码并将表单与业务逻辑分开。

这是我在 C# 中访问 MSAccess 数据时所做的:

public void LoadUsersInfo()
        {

            try {
                OleDbConnection Connection = new OleDbConnection();        
                Connection.ConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;DataSource=dbCyberNet.accdb;Persist Security Info=False;";        
                Connection.Open();
                OleDbCommand command = new OleDbCommand();
                command.Connection = Connection;
                String query = "SELECT * FROM tblUsersInfo";
                command.CommandText = query;

                OleDbDataAdapter adapter = new OleDbDataAdapter(command);
                DataTable dt = new DataTable();
                adapter.Fill(dt);
                dbGrid.DataSource = dt;
            }
            catch (Exception ex) {
                MessageBox.Show("Error occured while loading users information . " + ex.Message.ToString());
            }
            finally { Connection.Close(); }
        }

我想在 delphi 中为 sqlite 数据库做类似的事情。这是我尝试过的(已编辑)。

procedure TForm1.Button1Click(Sender: TObject);
var
  con: TFDConnection;
  table: TFDTable;
  ds: TDataSource;
begin
  con := TFDConnection.Create(nil);
  con.LoginPrompt := False;
  table := TFDTable.Create(nil);
  table.TableName := 'Students';
  ds := TDataSource.Create(nil);
  ds.DataSet := table;

  try
    con.Open('DriverID=SQLite;Database=‪studentsDB.sqlite;');
    table.Connection := con;
    table.Active := True;
    con.Connected := True;
    DBGrid1.DataSource := ds;
  finally
    con.Close;
    con.Free;
    table.Free;
    ds.Free;
  end;
end;

每当我运行此代码时,都会出现错误对话框,显示:$759AF097 的第一次机会异常。带有消息“[FireDAC][Phys][SQLite] 错误:没有这样的表:STUDENTS”的异常类 ESQLiteNativeException。处理 Project1.exe (3836)

虽然表中存在相同的表名并使用可视化的firedac组件,但我可以看到数据网格很容易填充。

【问题讨论】:

  • 到目前为止你尝试过什么?您是否尝试过像在 C# 中那样声明对象实例并在代码中创建它们?
  • 问题已编辑。请看一看。

标签: sqlite delphi database-connection delphi-xe6 firedac


【解决方案1】:

您可以通过调用查询的Open 方法来执行您的Select 查询,这样您的代码将如下所示:-

procedure TStudents.executeQuery;
var
  con: TFDConnection;
  query: TFDQuery;
begin
  con := TFDConnection.Create(nil);
  query := TFDQuery.Create(con);
  con.LoginPrompt := False;
  con.Open('DriverID=SQLite;Database=studentsDB.sqlite;');
  query.Connection := con;
  query.SQL.Text := 'SELECT * FROM Students';
  query.Open;
  query.First;
  While Not Query.EOF Do
  Begin
    // Populate your object or do whatever processing you like here.
    Query.Next;
  End;
end;

然后,您可以通过编程方式创建 TDataSource 和 Grid,并以类似的方式将它们连接到代码中。您需要将 Connection 和 Query 对象移出对象的 executeQuery 方法,因为它们是局部变量,并且该方法之外的任何东西都无法访问它们。

请注意,Delphi 不像 C# 那样进行垃圾收集,因此代码会泄漏内存。

顺便说一句,您的代码似乎是一个对象方法,看起来您正在尝试创建一组知道如何加载和保存自己的业务对象。与其自己动手,不如通过查看现有的一个框架(tiOPF、InstantObjects、mORMot 或 TMS Aurelius)来实现这一点,为您提供更好的服务。这些将使您能够专注于解决手头的问题,而不必担心创建、加载和保存对象的细节。

【讨论】:

  • 您的示例代码正在泄漏内存! con 和 query 变量没有被释放。这远不是很好的参考代码来展示...... :(顺便说一句,OP根本没有指定对象持久性,而只是填充了一个可视网格。
  • @ArnaudBouchez 你说得对,代码确实会泄漏内存,但我采用了 OP 的原始代码,只是附加了必要的步骤,而不是为他重写整个代码。我已经更新了我的答案,包括对内存泄漏的评论。
  • @Andy_D:正如我所见,它可以使用您的代码,但似乎存在内存泄漏问题。请原谅我在 Delphi 中的孩子技能,但我无法使用 try..finally 块释放这些连接和查询对象。它显示了 invlaid 指针操作错误对话框。顺便说一句,我已经更新了我的代码,请看一下。
  • @RabiJayasawal 不要建立连接并查询局部变量。 Delphi 有 Datamodules 的概念,它为您的数据访问组件提供了一个中心点。有关更多信息,请参阅文档docwiki.embarcadero.com/RADStudio/XE6/en/Using_Data_Modules
  • 是的,数据模块是最好的方法。我个人真的很讨厌它,但这就是 rad 的工作方式。
【解决方案2】:

您可以执行与 C# 相同的操作:将您的 TFDQuery 实例分配为 VCL 网格的 DataSource!

TDataSource 添加到表单,将其DataSet 属性设置为您的TFDQuery,并将其分配给您的网格。

参见the official Delphi documentation 和其他SO questions

【讨论】:

  • 我尝试过这样的事情。 link 但这似乎不是正确的方法,我猜。顺便说一句,请原谅我的菜鸟技能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-30
  • 2016-12-07
  • 1970-01-01
  • 1970-01-01
  • 2011-02-15
  • 1970-01-01
相关资源
最近更新 更多