【问题标题】:Best way to actually sort a database table with sqlite and in c++?使用 sqlite 和 C++ 对数据库表进行实际排序的最佳方法?
【发布时间】:2014-01-25 05:10:52
【问题描述】:

我需要对表格进行永久排序。我无法控制如何创建数据库或其表。我有一个用 c++ 编写的程序,它有几种方法可以对数据库及其表执行不同的操作。例如打印、召回行、更新行、下载行、更新行等等。

我目前在排序数据库中。它需要根据指定的列对数据库进行实际排序,如果用户指定一个列,则可以按另一列进行子排序。因此,如果使用第三方应用程序查看排序完成后,所有数据都会显示排序。

我知道 SELECT * FROM table1 ORDER BY Col1, Col2 将返回已排序的表,但从实际内存的角度来看,所有数据都是表仍然相同,所以如果在 ORDER BY 之后 col 1 全部乱序数据库查看器仍然会乱序显示 col 1。排序后,数据库中的数据应进行排序,在数据库查看器中查看时,一切都井井有条。

这是我第一篇文章的完整编辑。仅供参考

【问题讨论】:

  • 为什么?你不使用索引吗?我闻起来像XY problem
  • 我相信您正在尝试解决错误的问题。您想通过这一切达到什么目的?
  • 您应该在数据库中创建要排序的字段的索引,然后在这些字段上使用“排序依据”,数据库将进行排序。索引 is 正是您正在寻找的“永久存储”排序,除非我误解了您需要它的 原因
  • 可能是这里的 XY 问题,对此感到抱歉:/ 我无法控制数据库的创建方式。对于一些背景知识,用户自己创建一个数据库,然后在程序中打开该数据库。我有几个不同的命令可以执行,例如打印、调用行、更新行等。其中一个命令是排序数据库。现在,此命令需要根据他们指定的列对数据库进行排序,如果他们指定第二列,则可以进一步对数据库进行子排序。实现这一目标的最佳方法或方法是什么?我充其量是一个sqlite新手。您能否详细说明索引
  • 无论您是否创建索引,我都会根据用户的选择create a view,然后将其用作数据源。在排序列上创建索引将提高性能。

标签: c++ sorting sqlite


【解决方案1】:

通过@RogerRowland 的帮助,我能够解决这个问题,但对于那些希望和我做同样事情的人来说。我不知道为什么您实际上想要这样做,但是如果您需要对数据库表的数据进行实际排序,而不仅仅是返回排序后的数据并且使用 sqlite3 和 c++,这就是您想要做的。

步骤 1)

rc = sqlite3_prepare(this->dbPointer, "CREATE [TEMP] VIEW tempViewOfSortedTable AS SELECT * FROM tableName ORDER BY columnName", -1, &ppStmt, NULL);

步骤 2) 获取所有表信息(列名和类型等)并将其存储在一个字符串中。

rc = sqlite3_prepare_v2(this->dbPointer, "pragma table_info tableName", -1, &ppStmt, NULL);

第 3 步)创建一个具有与原始表相同的列和属性的新表。

sprintf(strQuery, "CREATE TABLE tempUserTable (%s)", strListOfFieldsAndTypes);
if (rc == SQLITE_OK)rc = sqlite3_exec (this->dbPointer, strQuery, NULL, NULL, &errMsg);

第 4 步)将视图的所有排序数据复制到新表中。

sprintf(strQuery, "INSERT INTO tempUserTable SELECT %s FROM tempViewOfSortedTable", strListOfFields);
if (rc == SQLITE_OK)rc = sqlite3_exec (this->dbPointer, strQuery, NULL, NULL, &errMsg);

第 5 步)删除旧表

if (rc == SQLITE_OK)rc = sqlite3_exec (this->dbPointer, "DROP TABLE tableName", NULL, NULL, &errMsg);

第 6 步)如果需要,将新表重命名为旧名称。

if (rc == SQLITE_OK)rc = sqlite3_exec (this->dbPointer, "ALTER TABLE tempUserTable RENAME TO 'tableName'", NULL, NULL, &errMsg);

如果您没有创建临时视图,或者即使您要在关闭数据库之前重复此操作,您可能还想删除视图,因为如果您不这样做,临时视图将持续到您关闭数据库。

也绝对不要声称这是快速路线。我使用 sqlite3_exec 的唯一原因是因为我回收了别人的旧代码,我将自己用 sqlite3_prepare_v2 替换它,但想为有相同问题的其他人解决这个问题。

来源。

http://www.sqlite.org/lang_createview.html

http://www.sqlite.org/capi3ref.html

【讨论】:

    猜你喜欢
    • 2016-04-07
    • 1970-01-01
    • 2013-12-19
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 2012-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多