Delphi / ADO:使用哪些组件?TADODataSet 和 TADOCommand 还是 TADOQuery?

5
根据http://www.delphigroups.info/2/3/181838.html (archive),使用ADO组件的首选方法是使用TADODataSet和TADOCommand。TADOQuery(以及TADOTable和TADOStoredProc)是为了兼容性而提供的。对于返回结果集的SQL,请使用TADODataSet,对于不返回结果集的SQL,请使用TADOCommand。作为一个毫无头绪的初学者,我将要编写大量的ADO代码。上述说法正确吗?

顺便问一下,有没有好的开源Windows程序可以让我可视化和探索我的数据库内容?

对于返回/不返回结果的操作,应该使用哪些组件?


3
我相信链接和你自己的问题已经提供了回答的线索。使用TADOCommand和TADODataSet。此外,为UI使用DB Aware控件。 - PA.
5个回答

7

这个说法是正确的。TADODataset和TADOCommand是直接与本地ADO对象进行交互的接口,可以执行其他三种接口能够执行的所有任务,这些接口存在的目的是为了方便移植使用BDE(Borland数据库引擎)编写的应用程序,实现类似的接口 - 最终它们会调用前两个接口。


你能帮忙吗?当我使用TADODataset.Execute()时,会得到一个_Recordset,请问如何循环遍历以查看结果? - Mawg says reinstate Monica
1
如果你使用 TADODataset 来执行一个 SELECT,只需打开它(或将 Active 设置为 True)。现在你可以使用 First/Last/Next/Prev 方法来迭代结果。如果你使用 TADOCommand,Execute 返回一个 ADO 接口,它有 MoveXXXX 方法来迭代结果集,请查阅 ADO 文档。 - user160694

4

我会去半个相反的地方!;-)

在某些情况下,TADOQuery适用于两种任务。 如果您的查询将返回数据,请使用TADOQuery.Active := True, 如果需要执行更新\插入\删除,请使用TADOQuery.ExecSQL。

例如,您可以编写一个查询来更新\插入和选择记录,并在一个组件中完成,而不是引入两个组件。

DECLARE @ID int, @Mode int, @SomeValue varchar(20)

SET @ID = :ID
SET @Mode = :Mode
SET @SomeValue = :SomeValue 

IF (@Mode = 1) //INSERT
BEGIN
  INSERT INTO dbo.YourTable(ID, SomeColumn) VALUES(@ID, @SomeValue)
END ELSE
IF (@Mode = 2) //UPDATE
BEGIN
  UPDATE dbo.YourTable SET SomeValue = @SomeValue WHERE ID = @ID
END ELSE
IF (@Mode = 3) //DELETE
BEGIN
  DELETE FROM dbo.YourTable WHERE ID = @ID
END ELSE
IF (@Mode = 4) //SELECT
BEGIN
  IF (@ID = -1) //SELECT ALL
  BEGIN
    SELECT * FROM dbo.YourTable
  END ELSE
  BEGIN
    SELECT * FROM dbo.YourTable WHERE ID = @ID
  END
END

这只是一个例子,现在写的。我希望你能理解。


2

你使用哪种数据库? SqlBuddy是一款开源的IDE,用于探索数据库。


+1 谢谢,看起来很不错(等我弄明白怎么运行它就好了;-) - Mawg says reinstate Monica

2
这里有两种不同的分类方式,一种是根据SQL对象的性质(TADOTable、TADOQuery和TADOStoredProc),另一种是根据操作/结果(TADODataSet和TADOCommand)。Delphi历史上的方法更偏向于前者,而ADO本质上更偏向于后者。根据你想要做什么,两者都可以很有用。
我建议你阅读Delphi帮助文件中关于ADO组件的内容。例如,你会发现以下提示很有用: “ADOdb.TADODataSet和SQLExpr.TSQLDataSet具有一个CommandType属性,允许你指定它们是否表示表、查询或存储过程。属性和方法名称与查询类型数据集最相似,尽管TADODataSet允许你像表类型数据集一样指定索引。”
如果你确定要坚持使用ADO,并且永远不需要更改和移植到其他数据层,则应选择“ADO路线”并使用TADODataSet和TADOCommand。这样可以最大限度地利用ADO,并且使用MS文档和示例会更容易。

我是一个新手,发现Delphi帮助文档令人困惑 :-/ 我想当有多种选择时,通常都会这样,所以我想请教大师们。我想象我的命令类型将始终为文本。 - Mawg says reinstate Monica
2
如果您使用 Delphi 7 之后的任何版本,帮助文档可能会让最熟练的 Delphi 开发人员感到困惑。 - user160694
我想这是一个权衡。你可以选择更简单、更老的、兼容(即不特定于ADO)的TADOQuery/TADOStoredProc范例,或者更“本地”的ADO方式。虽然你可以这样做,但尽量不要混合使用它们。 - Francesca
如果您使用的是 Delphi 7 之后的版本,即使是最熟练的 Delphi 开发人员也可能会被帮助文档所困扰。这是非常正确的说法...... - Fabricio Araujo

2

SELECT语句

用于发出返回数据集的DQL语句(例如SELECT)

  • TADOQuery

    qry.Sql.Text := 'SELECT * FROM Users WHERE Name = :username';
    qry.Parameters.ParamByName('username').Value := 'ian';
    qry.Open;
    
  • TADODataSet

    ds.CommandText := 'SELECT * FROM Users WHERE Name = :username';
    ds.Parameters.ParamByName('username').Value := 'ian';
    ds.Open;
    
  • TADOCommand

    cmd.CommandText := 'SELECT * FROM Users WHERE Name = :username';
    cmd.Parameters.ParamByName('username').Value := 'ian';
    rs: _Recordset;
    rs := cmd.Execute;
    

    The ADOCommand will return a native ADO IRecordset. You can use the Recordset interface directly (it's not that hard), or you can wrap it in a friendly Delphi wrapper class:

    ds.Recordset := rs;
    

    or

    qry.Recordset := rs;
    

插入、更新、删除语句

用于执行不返回数据集的 DML 语句(例如 INSERT、UPDATE、DELETE)

  • TADOQuery

    qry.Sql.Text := 'DELETE FROM Users WHERE Name = :username';
    qry.Parameters.ParamByName('username').Value := 'ian';
    qry.ExecuteOptions := [eoExecuteNoRecords];
    qry.ExecSql;
    
  • TADOCommand

    cmd.CommandText := 'DELETE FROM Users WHERE Name = :username';
    cmd.Parameters.ParamByName('username').Value := 'ian';
    cmd.ExecuteOptions := [eoExecuteNoRecords];
    cmd.Execute;
    
  • TADODataSet: Cannot be done. TADODataSet will throw an exception if no dataset is returned by the statement

    ds.CommandText := 'DELETE FROM Users WHERE Name = :username';
    ds.Parameters.ParamByName('username').Value := 'ian';
    ds.ExecuteOptions := [eoExecuteNoRecords];
    ds.Open; // <-- Exception: "CommandText does not return a result set"
    

图表形式

| Component   | Issue command | Return rows |
|-------------|---------------|-------------| 
| TADODataSet |  No           |  Yes        |
| TADOCommand |  Yes          |  Yes¹       |
| TADOQuery   |  Yes          |  Yes        |

¹ Recordset interface

继承层次结构

  • TComponent
    • TADOCommand (近似本地的 ADO 访问)
    • TDataSet (Delphi 的基础数据集模型)
      • TCustomADODataSet (将 ADO 显示为 DataSet)
        • TADODataSet (无法发出 DML)
        • TADOQuery (可以发出 DML 和 DQL)
      • TCustomClientDataSet (将内存表格显示为 DataSet)
      • TBDEDataSet (将 BDE 显示为 DataSet)
      • TCustomSQLDataSet (将 dbExpress 显示为 DataSet)

TADOCommand 是发出原始查询的最接近底层的方法。

TADODataSetTADOQuery 使用 Delphi 现有的数据库对象模型来显示 ADO 数据源。

TADODataSet 只能用于表示数据集。

TADOQuery 是一个全能型的工具,可以完成各种任务。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接