以数据库不可知的方式构建查询

Kar*_*rim 5 c++ sql

在几乎可以使用任何关系数据库的 C++ 应用程序中,生成可以轻松扩展以允许数据库引擎的怪癖的查询的最佳方法是什么?

换句话说,代码可能需要以在各种数据库引擎之间不一致的方式检索数据。在客户端设计代码以生成查询的最佳方法是什么,使支持新的数据库引擎变得相对轻松。

例如,如果我有如下所示的 (MFC) 代码:

CString query = "SELECT id FROM table"
results = dbConnection->Query(query);
Run Code Online (Sandbox Code Playgroud)

我们决定支持一些使用“AVEC”而不是“FROM”的数据库。现在,只要用户使用该数据库引擎,此查询就会失败。

到目前为止的选项:

  • 最坏的选择:让查询的代码检查数据库类型。
  • 更好的选择:在 db 连接对象上创建查询请求方法,该方法采用唯一的查询“代码”并根据使用的数据库引擎返回适当的查询。
  • 更好的选择:创建一个查询构建器类,允许调用者在不直接使用任何 SQL 的情况下构建查询。查询完成后,调用者可以调用“生成”方法,该方法返回适用于活动数据库引擎的查询字符串
  • 最佳选择:??

注意:数据库引擎本身是通过我们自己创建的一些薄层抽象出来的。查询本身是唯一剩下的问题。

解决方案:
出于两个原因,我决定使用“更好”选项(查询“选择器”)。

  1. 调试:正如下面提到的,使用选择器方法调试会稍微容易一些,因为查询是预先构建的,并在代码中以可读的形式列出。
  2. 灵活性:我突然想到有些数据库可能具有更好且完全不同的解决特定查询的方法。例如,使用 Access 我每次都对多个表执行复杂的查询,因为我必须这样做,但是在 Sql Server 上我想设置一个视图。从视图和多个表中进行选择是完全不同的查询(我认为),这个查询选择器可以轻松处理它。

tva*_*son 0

我认为,如果您需要支持多个数据库的能力,您想要做的就是创建一个数据提供者接口(或抽象类)和关联的具体实现。数据提供程序需要支持您的标准查询运算符以及支持您的查询操作所需的其他常见受支持功能(请查看 .NET 3.5 中的 IEnumerable 扩展方法)。然后,每个具体提供者将根据目标数据库引擎将这些转换为特定查询。

本质上,您所做的就是创建一个数据库抽象层并让您的代码与其交互。如果你能找到其中一个用于 C++ 的工具,那么购买它可能比编写它更值得。您可能还想寻找 C++ 的控制反转 (IoC) 容器,它基本上可以完成此操作以及更多操作。我知道有几个针对 Java 和 C# 的,但我对 C++ 的都不熟悉。