如何从sqlite3_exec()获取COUNT(*)值?

时间:2017-10-01 10:45:06

标签: c sqlite

在我的C程序中,我必须检查数据库中的表的计数是1还是0,为此我执行查询,如下所示:

char *sql = "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name=family;";
int table_count = sqlite3_exec(db, sql, 0, 0, &err_msg);
printf("\n%d\n", table_count);

我希望table_count为1,因为只有一个表存在名称family,而printf输出table_count为' 21'哪个不对。我们怎样才能以正确/正确的方式从C程序中获取C / C ++ API的COUNT(*)值?

1 个答案:

答案 0 :(得分:1)

在阅读SQLite文档并在问题评论中遵循其他类型的隐式/显式建议后,我意识到我在问题中引用的代码段中的错误。

错误1: 在SQL查询执行后,我没有实现回调函数来接收结果集。 [已实现此回调:请参阅以下代码中的 checkTable_Callback ]

错误2: 那个' 21'的输出实际上是错误代码,并且根据SQLite文档,错误代码对应于SQLite_MISUSE这可能是生成的,因为我使用单独的函数来打开我的测试数据库文件和该打开的数据库的实例,我假设,留在那个 openDb 函数中,当我使用另一个函数 checkTableCount 从我把那个凌乱的片段引用到我的问题中时,db实例可能是null,因此21如果这就是为什么我收到错误代码21,专家可以进一步详细说明。无论如何,现在我已经修复了这个功能并使 openDb 返回一个打开的数据库实例(更好的词?)现在21错误消失了。 [见下面的代码]

以下内容已修复且 改编为我的案例'代码

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include "sqlite3.h" /* sqlite3.dll and sqlite3.h both reside in
                            my <program_source.c>'s folder */
    static int checkTable_Callback(
                void *unnecessary_here,
                int number_of_columns_in_result_row, /* will always be 1 in this case */
                char **value_of_count, /* will be either 0 or 1 in this case */
                char **label_for_count) { /* will be COUNT(*) normally,
                 but modified via 'AS table_tablename' in this case*/
      printf("COUNT(*) %s\t=>\t%s\n", label_for_count[0], value_of_count[0] );
      return 0;
    } // end of checkTable_Callback()

    char * build_sql(const char *sql_partA, const char *sql_partB) {
      size_t size = strlen(sql_partA) + strlen(sql_partB);
      char *sql_final = malloc(size + 1);
      strcpy(sql_final, sql_partA);
      strcat(sql_final, sql_partB);
      return sql_final;  /* allocated memory to be freed at the end of calling function */
    } // end of build_sql()

    checkTableCount(sqlite3 *db, char *tablename) {
      char *sql  = build_sql(
                      build_sql(
                         build_sql(
                            build_sql(
                            "SELECT COUNT(*) AS table_",
                            tablename),
                      " FROM sqlite_master WHERE type='table' AND name='"),
                      tablename),
                   "';");
      sqlite3_exec(db, sql, checkTable_Callback, 0, NULL); 
    /* error checking sacrificed for brevity of sample */
      free(sql);
    }// end of checkTableCount()

    sqlite3 * openDb(char * db_name){
      sqlite3 *db;
      int result_code = sqlite3_open(db_name, &db);
      if( result_code != 0 )
           fprintf(stderr, "\tError: %s\n\n", sqlite3_errmsg(db));
      return db;
    } // end of openDb()

    int main() {
      sqlite3 * db = openDb("testing.db"); /* testing.db already has one table 'family'*/
      checkTableCount(db, "family");
      checkTableCount(db, "fam"); /* no such table exist */
      sqlite3_close(db);
      return 0;
    } // end of main()

现在引用&#39; 改编为我的案例&#39;代码正确并正确输出COUNT(*),如下所示:

<强>输出

 COUNT(*) table_family   =>      1
 COUNT(*) table_fam      =>      0

请注意,我在编写一个名为 checkTable_Callback 的回调函数中编写一个for循环,以便遍历列,如回调函数on this page的官方示例所示,因为我没有办法事实上,我们的预期结果行肯定只有一个包含只有一列且标签被修改,通过&#39; AS&#39;子句,进入&#39; table_tablename&#39;。如果未通过&#39; AS子句&#39;进行修改,则返回的列标签将为&#39; COUNT(*)&#39;在结果行中。