SQLite in C. sqlite3_exec:回调函数中的参数集在main()中调用时打印不完整的数据, [英] SQLite in C. sqlite3_exec: parameter set in callback function prints incomplete data when called in main()

查看:173
本文介绍了SQLite in C. sqlite3_exec:回调函数中的参数集在main()中调用时打印不完整的数据,的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现一些非常基本的东西。但不幸的是,我无法得到预期的结果。



我有一个名为 emp_info 的sqlite表,在以下字段中有9个员工记录:



SR_NO [0],NAME [1],AGE [2],SEX [3],ADDRESS [4],EMPID [5],CARDID [6]和SALARY [7] / p>

要访问表并根据sql查询获取员工记录,我在C中有以下程序:

  #include< stdio.h> 
#include< stdlib.h>
#include< sqlite3.h>
#include< string.h>

static int callback(void * param,int argc,char * argv [],char ** azColName){
int i = 0;

if(argc == 0)return 0;
char ** res =(char **)param;
* res =(char *)realloc(* res,sizeof(* res));

// for(i = 0; i // printf(%s =%s\\\
,azColName [i],argv [i ]?argv [i]:NULL);

strcpy(* res,argv [1],sizeof(* res));
printf(%s\\\
,* res);
//}
return 0;
}

int main(int argc,char * argv [])
{
sqlite3 * db;
char * zErrMsg = 0;
int rc;
char * sql;
char * param;

rc = sqlite3_open(/ DBsqlite3 / foreign_key.db,& db);

if(rc)
{
fprintf(stderr,无法打开数据库:%s\\\
,sqlite3_errmsg(db));
exit(0);
}
else
{
fprintf(stderr,\\\
Open数据库成功\\\
\\\
);
}

sql =select * from emp_info;

rc = sqlite3_exec(db,sql,callback,& param,& zErrMsg);

if(rc!= SQLITE_OK)
{
fprintf(stderr,SQL错误:%s\\\
,zErrMsg);
sqlite3_free(zErrMsg);
}
else
{
fprintf(stdout,Operation done successfully\\\
\\\
);
printf(数据的值是%s \\\
\\\
,param);
}


free(param);
sqlite3_close(db);
return 0;
}

输出如下:
`
数据库成功

  AAA 
BBB
CCC
DDD
EEE $ b b FFF
GGG
HHH
III
操作成功完成

数据值为III

我预计所有的AAA,BBB,CCC,...将存储在 param 但这不是发生。 param 只能使用最后一条记录。



为什么会发生这种情况?我怀疑strcpy()正在创建问题。



请帮助。



是获取所有有效的雇员记录(按照sql查询)存储在 param 中,它应该显示所有字段(SR_NO [0],NAME [1],AGE [2],SEX [3],ADDRESS [4],EMPID [5],CARDID [6]和SALARY [7])。例如如果我向 sql 提供以下查询

  sql =SELECT * FROM emp_info WHERE AGE> ; 40; 

那么 param 应显示结果如下

  7 GGG 41 MALE G1G2G3G4 307 7777GGG 77777 

8 HHH 42 FEMALE H1H2H3H4 308 8888HHH 88888

9 III 43 FEMALE I1I2I3I4 309 9999IIII 99999

不仅仅是一个列。 / p>

提前感谢。

解决方案

CL。我开始编写基于光标的API的代码。我得到了所需的输出。

  #include< iostream> 
#include< sqlite3.h>
#include< stdlib.h>
#include< list>
#include< iterator>
#include< algorithm>

using namespace std;

class sqliteDB
{

private:
int rc;
sqlite3 * db;
char * zErrMsg
const char * sql;
sqlite3_stmt * stmt;
list< string>回答;


public:

// ======================== ====== XX ================================= //
bool connectDB()
{

rc = sqlite3_open(/ DBsqlite3 / foreign_key.db,& db);
if(rc)
{
cerr<< 无法打开数据库:< sqlite3_errmsg(db)< endl;
sqlite3_close(db);
exit(1);
}
else
{
std :: cout<<\\\
\\\
Database opened successfully\\\
\\\
;
}
}

// ============================== = XX ================================= //

allEmp()
{
int AGE;

//准备语句
rc = sqlite3_prepare(db,SELECT * FROM emp_info WHERE AGE> 40;,-1,& stmt,NULL)
if(rc!= SQLITE_OK){
throw string(sqlite3_errmsg(db));
}
else {
cout<<\\\
\\\
语句准备成功\\\
\\\
;
}

//创建列表容器//
cout<< \\\
\\\
List answer was successfully successfully\ n \\\
;
while(sqlite3_step(stmt)== SQLITE_ROW){
cout<< Rows<< endl;

int column = sqlite3_column_count(stmt);

for(int i = 0; i {
cout< 列<< endl;
answer.push_back(string((const char *)sqlite3_column_text(stmt,i)));
}
}

sqlite3_finalize(stmt);

cout<< \\\
\\\
Database已成功关闭\\\
\\\
;

}

// ========================== XX ================================= //

void printList( ){
int s = answer.size();
for(list< std :: string> :: const_iterator it = answer.begin(); it!= answer.end(); it ++)
cout< it-> c_str()<< endl;
}


// =============================== ==== XX =========================== //

};


int main()
{
sqliteDB object1;
object1.connectDB();
object1.allEmp();
object1.printList();
cout<< \\\
\\\
All语句已正确执行\\\
\\\
;

return 0;
}

// ======================代码结束======== =================== //

输出如下

 数据库已成功打开



语句已准备成功



已成功创建列表答案















$ b b





























数据库已关闭成功

7
GGG
41
MALE
G1G2G3G4
307
7777GGG
77777
9833446677
abi@gmail.com
07:08:1947
NONE
8
HHH
42
FEMALE
H1H2H3H4
308
8888HHH
88888
9833446688
abj@gmail.com
08:09:1947
NONE
9
III
43
FEMALE
I1I2I3I4
309
9999IIII
99999
9833446699
abk@gmail.com
09 :10:1947
NONE


所有语句正确执行

我遇到的主要问题是重载< <运算符。



谢谢CL。


I am trying to achieve something very basic. But unfortunately I am unable to get the expected result.

I have a sqlite table named emp_infohaving 9 employee records in following fields:

SR_NO[0], NAME[1], AGE[2], SEX[3], ADDRESS[4], EMPID[5], CARDID[6] and SALARY[7].

To access the table and fetch the employee record as per sql query, I have following program in C:

#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h> 
#include <string.h>

static int callback(void *param, int argc, char *argv[], char **azColName){
    int i=0;

    if(argc == 0) return 0;
    char **res = (char **)param;
    *res = (char *)realloc(*res, sizeof(*res));

  //for(i=0; i<argc; i++){
  //printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");

    strcpy(*res, argv[1], sizeof(*res));
    printf("%s\n", *res);
 // }
return 0;
}

int main(int argc, char* argv[])
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
char *param;

rc = sqlite3_open("/DBsqlite3/foreign_key.db", &db);

    if( rc )
    {
       fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
       exit(0);
    }
    else
    {
       fprintf(stderr, "\nOpened database successfully\n\n");
    }

sql="select * from emp_info;"

rc = sqlite3_exec(db, sql, callback, &param, &zErrMsg);

    if( rc != SQLITE_OK )
    {
      fprintf(stderr, "SQL error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
    }
    else
    {
       fprintf(stdout, "Operation done successfully\n\n");
       printf("the value of data is %s \n\n", param);
    }


free(param);
sqlite3_close(db);
return 0;
}

The output is as follows: ` Opened database successfully

AAA
BBB
CCC
DDD
EEE 
FFF
GGG
HHH
III
Operation done successfully

the value of data is III

I expected that all the AAA,BBB,CCC,.... will get stored in param and will get printed. But that's not happening. param takes only the last record only.

Why is this happening ? I suspect strcpy() is creating the problem.

Kindly help.

Apart from this, my real aim is to get all the valid employee record (as per sql query) to get stored in param and it should display all the fields(SR_NO[0], NAME[1], AGE[2], SEX[3], ADDRESS[4], EMPID[5], CARDID[6] and SALARY[7]). say for example if i provide following query to sql

sql="SELECT * FROM emp_info WHERE AGE>40";

then the param should display result as follow

7           GGG         41          MALE        G1G2G3G4    307         7777GGG     77777     

8           HHH         42          FEMALE      H1H2H3H4    308         8888HHH     88888

9           III         43          FEMALE      I1I2I3I4    309         9999IIII    99999

And not just a column.How can I achieve this ?

Thank you in advance.

解决方案

working on the suggestions suggested by CL. I started working on writing the code on cursor-based API. And I got the desired output.

#include <iostream>
#include <sqlite3.h>
#include <stdlib.h>
#include <list>
#include <iterator>
#include <algorithm>

using namespace std;

class sqliteDB
{

private:
  int rc;
  sqlite3 *db;
  char *zErrMsg;
  const char *sql;
  sqlite3_stmt * stmt;
  list<string> answer;


public:

//================================XX=====================================//
  bool connectDB()
  {

      rc = sqlite3_open("/DBsqlite3/foreign_key.db", &db);
      if( rc )
      {
        cerr << "Can't open database: " << sqlite3_errmsg(db) << endl;
        sqlite3_close(db);
        exit(1);
      }
      else
      {
            std::cout<<"\n\nDatabase opened successfully\n\n";
      }
   }

//===============================XX=====================================//

  void allEmp()
  {
     int AGE;

     //Preparing the statement
     rc=sqlite3_prepare(db,"SELECT * FROM emp_info WHERE AGE>40;", -1, &stmt, NULL ); 
     if (rc != SQLITE_OK){
     throw string(sqlite3_errmsg(db));
     }
     else{
     cout<<"\n\nThe statement was prepared successfully\n\n";
     }

    // Creating List Container //
    cout << "\n\nList answer was created successfully\n\n";
    while(sqlite3_step(stmt) == SQLITE_ROW) {
    cout << "Rows" << endl;

    int column = sqlite3_column_count(stmt);

       for(int i = 0; i < column; i++)
       {
          cout << "Columns" << endl;
          answer.push_back(string((const char *) sqlite3_column_text(stmt, i)));
       }
     }

    sqlite3_finalize(stmt);

    cout << "\n\nDatabase was closed successfully\n\n";

 }

//==============================XX=====================================//

 void printList(){
    int s = answer.size();
    for( list<std::string>::const_iterator it = answer.begin(); it != answer.end(); it++)
      cout << it->c_str() << endl;
  } 


//===================================XX===============================//    

};


int main()
{
  sqliteDB object1;
  object1.connectDB();
  object1.allEmp();
  object1.printList();
  cout << "\n\nAll the statement were executed properly\n\n";

 return 0;
}

//========================END OF CODE===========================//

The Output is as follows

 Database opened successfully



 The statement was prepared successfully



 List answer was created successfully

 Rows
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns


 Rows
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns


 Rows
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns
 Columns

 Database was closed successfully

 7
 GGG
 41
 MALE
 G1G2G3G4
 307
 7777GGG
 77777
 9833446677
 abi@gmail.com
 07:08:1947
 NONE
 8
 HHH
 42
 FEMALE
 H1H2H3H4
 308
 8888HHH
 88888
 9833446688
 abj@gmail.com
 08:09:1947
 NONE
 9
 III
 43
 FEMALE
 I1I2I3I4
 309
 9999IIII
 99999
 9833446699
 abk@gmail.com
 09:10:1947
 NONE


 All the statement were executed properly

The major problem I faced was with the overloading of "<<" operator.

Thank you CL.

这篇关于SQLite in C. sqlite3_exec:回调函数中的参数集在main()中调用时打印不完整的数据,的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆