【问题标题】:Delphi / ADO : Which components? TADODataSet and TADOCommand or TADOQuery?Delphi / ADO:哪些组件? TADODataSet 和 TADOCommand 还是 TADOQuery?
【发布时间】:2010-06-01 08:34:53
【问题描述】:

根据http://www.delphigroups.info/2/3/181838.html (archive)

ADO 的首选方法 组件是使用 TADODataSet 和 TADO 命令。 TADOQuery(和 TADOTable 和 TADStoredProc) 提供给 兼容性。

对返回的 SQL 使用 TADODataSet SQL 的结果集和 TADOCommand 没有。

我是一个无知的 n00b - 即将编写大量 ADO 代码。上述说法正确吗?


p.s. 有没有什么好的开源 Windows 程序可以让我可视化和探索我的数据库的内容?

我应该将哪些组件用于返回/不返回结果的东西?

【问题讨论】:

  • 我相信链接的参考资料和您自己的问题已经提供了回答您的线索。使用 TADOCommand 和 TADODataSet。此外,为 UI 使用 DB Aware 控件。

标签: delphi ado


【解决方案1】:

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

【讨论】:

  • 你能帮忙吗?当我使用 TADODataset.Execute();我最终得到一个 _Recordset 你能告诉我如何循环查看结果吗?
  • 如果您使用 TADODataset 执行 SELECT,只需打开它(或将 Active 设置为 True)。现在您可以使用 First/Last/Next/Prev 方法来迭代结果。如果您使用 TADOCommand,Execute 返回一个 ADO 接口,它有 MoveXXXX 方法来迭代结果集,请查看 ADO 文档。
【解决方案2】:

我会选择半对立! ;-)

在某些情况下,TADOQuery 可能非常适合两种工作。 如果您的查询将导致数据使用TADOQuery.Acvite := True, 如果您需要执行更新\插入\删除使用TADOQuery.ExecSQL.

例如,您可以编写一个查询到 UPDATE\ INSERT 并选择一条记录,然后在一个组件中执行此操作,而不是引入两个。

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

只是一个例子,现在写。我希望你能明白。

【讨论】:

    【解决方案3】:

    您使用哪个数据库。 SqlBuddy 是用于探索数据库的开源 IDE。

    【讨论】:

    • +1 谢谢,看起来不错(当我弄清楚如何运行它时 ;-)
    【解决方案4】:

    您在此处有 2 种不同的分类,这取决于 SQL 对象的 性质(TADOTable、TADOQuery 和 TADOStoredProc)操作/结果(TADODataSet 和TADOCommand)
    历史上的 Delphi 方法更多的是第 1 种,而 ADO 本质上更多的是第 2 种。

    两者都可能有用,具体取决于您想要做什么。

    我建议您阅读有关 ADO 组件的 Delphi 帮助
    例如,您会发现有用的注释,例如: “ADOdb.TADODataSet 和 SQLExpr.TSQLDataSet 有一个 CommandType 属性,可让您指定它们是表示表、查询还是存储过程。属性和方法名称与查询类型的数据集最相似,尽管 TADODataSet 允许您指定像表类型数据集。”

    如果您确定坚持使用 ADO 并且永远不需要更改和移植到其他数据层,那么使用 TADODataSet 和 TADOCommand 走“ADO 路线”。 您将使用它充分利用 ADO,并且更容易使用 MS 文档和示例。

    【讨论】:

    • 我太牛了,我发现 Delphi 的帮助令人困惑:-/ 我想当提供替代品时通常总是这样,所以我想我会问大师。我想我的命令类型将永远是文本。
    • 如果您使用 Delphi 7 之后的任何版本,帮助可能会使最熟练的 Delphi 开发人员感到困惑。
    • 我想这是一种权衡。您可以选择更简单、更旧、兼容(即不是 ADO 特定)的范式与 TADOQuery/TADOStoredProc 或更“本机”的 ADO 方式。虽然可以,但尽量不要混合使用。
    • If you use any version after Delphi 7 the help can confuse the most proficient Delphi developer.非常真实的话......
    【解决方案5】:

    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;
      

      ADOCommand 将返回一个本地 ADO IRecordset。你可以直接使用Recordset接口(没那么难),也可以把它包装在一个友好的Delphi包装类中:

      ds.Recordset := rs;
      

      qry.Recordset := rs;
      

    INSERT、UPDATE、DELETE 语句

    用于发出不返回数据集的 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:做不到。如果语句没有返回数据集,TADODataSet 会抛出异常

      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
    

    继承层次结构

    • T 组件
      • TADOCommand (接近原生 ADO 访问)
      • TDataSet (Delphi 的基础数据集模型)
        • TCustomADODataSet (将 ADO 公开为数据集)
          • TADODataSet (无法发出 DML)
          • TADOQuery (可以发出DML和DQL)
        • TCustomClientDataSet (将内存中的表作为数据集公开)
        • TBDEDataSet (将 BDE 暴露为数据集)
        • TCustomSQLDataSet (将 dbExpress 暴露为数据集)

    TADOCommand 是最接近用于发出原始查询的金属。

    TADODataSetTADOQuery 使用 Delphi 现有的数据库对象模型来公开 ADO 数据源

    TADODataSet只能用于表示数据集

    TADOQuery 是万事通。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多