【问题标题】:How to execute SQL statements on a dataset which didn't come from a database?如何在不是来自数据库的数据集上执行 SQL 语句?
【发布时间】:2013-04-29 01:52:42
【问题描述】:

假设我有一个应用程序从代表数据集的服务器获取自定义 XML 数据包。然后,假设我希望通过数据集对该数据执行 SQL 语句。我可以用什么来做到这一点?我不一定需要知道代码,只需要知道使用什么来使这成为可能以及如何做的一般解释。

例如,我可以从服务器获取 XML 格式的客户列表。然后,我可以使用任何第三方解析器将 XML 数据转储到某个客户端数据集中。然后,对该数据集执行查询,例如 select * from customers where ZipCode = '12345',而无需再次从服务器获取此数据。

XML 不是唯一的限制,这只是一个示例。我可能想对从 INI 文件加载的某些应用程序设置执行相同的操作。无论哪种方式,概念都是数据的原始来源是未知的。

数据集将其临时数据存储在内存中还是磁盘上并不重要,但如果能将其保存在磁盘中就更好了。

【问题讨论】:

  • 所以,您正在寻找一个内存数据库,它会以某种方式(神奇 :-) 转换 XML、INI 和其他任何数据(数据的原始来源未知 i>) 放入一个充满数据的表结构中,这样您就可以查询它们了?
  • @TLama 没错。原始来源无所谓,只要放在临时数据结构中,可以查询即可。
  • @Jerry 当你写完后把它放到 github.com 我也很想用它。

标签: delphi dataset delphi-xe2


【解决方案1】:

TXQuery (http://code.google.com/p/txquery/) 是一个提供本地 SQL 引擎的组件,用于针对一个或多个 TDataSet 执行 SQL 查询。我遇到的唯一问题是通过连接多个表 (TDataSets) 的查询的 TDBGrid 更新数据 - 特别是正在更新哪个表。

AnyDac v6(现在的 FireDac)也有一个本地 SQL 引擎。 http://www.da-soft.com/anydac/docu/frames.html?frmname=topic&frmfile=Local_SQL.html

编辑:对于您问题中的示例 SQL,因为它只涉及一个表,所以您只需在数据集上使用一个过滤器即可。例如

ADataSet.Filtered := False;
ADataSet.Filter := 'ZipCode=' + QuotedStr('12345');
ADataSet.Filtered := True;

【讨论】:

    【解决方案2】:

    这样的功能可以使用本地数据库来完成。您只需将 TDataSet 结果插入到本地内存(或基于文件)的独立数据库中,然后就可以对其使用常规 SQL 查询,包括 JOIN。

    例如,您可以使用SQLite3,或免费版的NexusDB

    NexusDB 嵌入式具有作为原生 Delphi 数据库的优势,因此请坚持使用 DB.pas TDataSet 范式。

    另一种选择是使用所谓的Virtual Table mechanism of SQLite3,它允许向 SQLite3 引擎公开任何数据(甚至来自 TDataSet、XML、JSON 或内存中的对象),就像常规表一样。然后,您可以在这些“虚拟”表(包括 JOIN)上运行 SQL 语句。使用这种方法,您不需要将数据插入到常规表中,但数据仍保持其原始形式。当然,你会错过一些性能特性,比如索引,这些特性应该在虚拟表提供者端处理。我们使用这个功能作为我们mORMot ORM/SOA framework的数据库核心,这个功能非常强大。

    【讨论】:

      【解决方案3】:

      您要执行的一般过程由于数据表示的差异而变得复杂。 SQL 数据存储在由可区分记录组成的表中。 XML 是数据的结构化表示,但采用树形而不是表/行形式。

      这些数据形式中的每一个都可以通过为数据提供上下文的模式来限定。

      您可以遵循两条一般路径:

      1. 获取 XML,并根据架构将其插入一组相互关联的表中,然后执行 SQL 查询。 - 如果您有架构,您可以使用代码生成器来制作解析器,然后基于解析树,您可以插入到本地数据库中,并使用动态构建的表。你可以很容易地从https://dev.mysql.com/doc/refman/5.7/en/installing.html 设置我的 SQL,然后在你的 delphi 版本中连接到数据库,首先填写它,然后查询。这将满足您将数据存储在磁盘上的愿望。除非您在完成后清除表,否则数据仍然在本地计算机数据库中可用。

      这似乎比:

      1. 使用 Xpath 或 Xquery 并直接处理 XML。为此,您最喜欢的环境中的 saxon 或 python 中的 expat 这样的包会很好地工作。

      让我知道这些路径中的任何一条是否有成效。

      【讨论】:

      • 不涉及官方模式。如果我提到我的 XML 格式是某种标准格式,我会考虑这个答案,但我只是使用 XML 作为数据源 可能 的示例。我说的是“自定义 XML”
      • 我同意你不考虑这是一个答案。如果您想追求这一点,那么我想完善可用答案的可接受范围。如果您接收数据的格式只是类似于 XML 的格式,那么将 XML 映射到 SQL 数据库可能不是您想要的答案的一部分。这将使我们更接近路径 2,但如果查询必须在 SQL 中,对于路径 1,mysql [链接] (dev.mysql.com/doc/refman/5.7/en/installing.html) 的本地安装可能是下一个要找到答案的链接。
      • @ElderDelp,如果有可用于 Delphi 的轻量级内存数据库,为什么选择 MySQL?
      • 我的目标是忽略任何标准数据库引擎,例如 SQL Server 或 MySQL 或任何东西。我确信 Delphi 中已经提供了这样的东西,只是我正在寻找究竟是什么。
      • @TLama,鉴于 Delphi 内部有解决方案,那么问题是是否可以在程序运行之后使其持久化。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-02
      • 1970-01-01
      • 2011-07-11
      • 2021-12-14
      相关资源
      最近更新 更多