执行预置查询DatabaseRead/Bind

预置查询是使用 DatabaseReadDatabaseReadBind 函数执行的。第一个函数会从数据库中提取结果,以便稍后可以从响应中依次接收到的每条记录中读取单个字段;第二个函数则以结构体的形式完整地提取每个匹配的记录。

bool DatabaseRead(int request)

Database PrepareDatabaseReset之后首次调用时,DatabaseRead 函数会执行查询并将内部查询结果指针设置为检索到的第一条记录(如果查询期望返回记录)。而 DatabaseColumn函数 能够读取记录字段的值,即查询中指定的列。

在后续调用中,DatabaseRead 函数会跳转到查询结果中的下一条记录,直到到达末尾。

函数成功完成时返回 truefalse 值用作错误指示(例如,数据库可能被锁定或繁忙),以及正常到达结果末尾时,因此应该分析 _LastError 中的代码。特别是,ERR_DATABASE_NO_MORE_DATA (5126) 值表示结果已结束。

注意!如果使用 DatabaseRead 执行不返回数据的查询(如 INSERT、UPDATE 等),并且请求成功,则该函数立即返回 false 并将错误代码设置为 ERR_DATABASE_NO_MORE_DATA。

该函数的通常使用模式通过以下伪代码说明(不同类型的 DatabaseColumn 函数将在 下一节中介绍)。

int r = DatabasePrepare(db"SELECT... WHERE...?",
   param));                            //compiling the query(optional with parameters)
while(DatabaseRead(r))                 // query execution (on the first iteration)
{                                      //    and loop through result records
   int count;
   DatabaseColumnInteger(r0count); // read one field from the current record
   double number;
   DatabaseColumnDouble(r1number); // read another field from the current record
   ...                                 // column types and numbers in record are determined by program
                                       // process the received values of count, number, etc.
}                                      // loop is interrupted when the end of the results is reached
DatabaseFinalize(r);

请注意,由于查询(读取条件数据)实际上只执行一次(在第一次迭代时),因此无需像记录变化数据时那样调用 DatabaseReset。但是,如果我们想再次运行查询并“遍历”新的结果,则需要调用 DatabaseReset

bool DatabaseReadBind(int request, void &object)

DatabaseReadBind 函数的运作方式与 DatabaseRead 类似:第一次调用执行 SQL 查询,并在成功(结果中有合适的数据)的情况下,用第一条记录的字段填充通过引用传递的 object 结构体;后续调用继续在查询结果中移动内部指针,用下一条记录的数据填充该结构体。

该结构体必须仅包含数字类型和/或字符串作为成员(不允许数组),它不能继承自对象类型或包含对象类型的静态成员。

object 结构体中的字段数量不应超过查询结果中的列数;否则,我们将收到错误。可以使用 DatabaseColumnsCount 函数动态获取列数,但是,调用者通常需要根据原始请求预先“知道”预期的数据配置。

如果结构体中的字段数量少于记录中的字段数量,则将执行部分读取。其余数据可以使用相应的 DatabaseColumn函数来获取。

假定结构体的字段类型与结果列中的数据类型匹配。否则,将执行自动的隐式转换,这可能导致意外后果(例如,读入数字字段的字符串将得到 0)。

在最简单的情况下,当我们为数据库记录计算某个总值时,例如,通过调用像 SUM(column)COUNT(column)AVERAGE(column) 这样的聚合函数,查询的结果将是具有单个字段的单个记录。

SELECT SUM(swap) FROM trades;

由于读取结果与 DatabaseColumn 函数相关,我们将把示例的开发推迟到下一节,下一节中介绍这些函数。