sqlite3_exec的使用

sqlite3_exec的使用,c,sqlite,C,Sqlite,我有下一个SQLITE3命令,它生成一个包含超过6000万条记录的文件: .mode csv .output matppp.csv select mat, ppp from matppp order by mat; .output stdout 如何使用以下命令将这些命令包含到C程序中: sqlite3_exec(db, "..........", NULL, 0, &db_err); ? 当我尝试自己执行时,c程序在执行时会生成一个表达式错误 谢谢 我认为您真的想,也许是fpr

我有下一个SQLITE3命令,它生成一个包含超过6000万条记录的文件:

.mode csv
.output matppp.csv
select mat, ppp from matppp order by mat;
.output stdout
如何使用以下命令将这些命令包含到C程序中:

 sqlite3_exec(db, "..........", NULL, 0, &db_err); 
?

当我尝试自己执行时,c程序在执行时会生成一个表达式错误


谢谢

我认为您真的想,也许是fprintf()将格式化输出写入文件。幸运的是,回调指针的原型包含一个额外的(可选)void*,它可以用作文件流,使回调在将来更可重用

另外,sqlite3_exec()不提供与sqlite3 CLI相同的接口。它只是用于查询,而不是输出修饰符


查看我给出的链接底部的示例代码,它很容易使用回调函数。

如果您想在C语言中实现这一点(而不是将某些内容传送到具有漂亮点命令的sqlite3命令行程序),那么您必须使用回调函数

为了便于剪切和粘贴,以下是从Apophenia库中破解出来的用于统计计算的代码

第一部分:

sqlite3 *db=NULL; //The global database handle.

static int apop_db_open(char *filename){
    if (!filename)  
        sqlite3_open(":memory:",&db);
    else            
        sqlite3_open(filename,&db);
    if (!db)
        printf("Not sure why, but the database didn't open.\n");
    return 0;
}

//From the SQLite manual:
#define ERRCHECK {if (err!=NULL) {printf("%s\n",err); sqlite3_free(err);  return 0;}}

apop_data * apop_sqlite_query_to_screen(char *query){
  char *err = NULL;
    if (db==NULL) 
        apop_db_open(NULL);
    sqlite3_exec(db, query, The_Callback, a_param, &err); 
    ERRCHECK
}
第二部分:

回调将具有以下形式,并为返回的每一行运行一次。注意参数a_param是如何传输的;如果您不需要它(如本例中所示),只需在上面将其设置为NULL即可

int The_Callback(void *a_param, int argc, char **argv, char **column){
    for (int i=0; i< argc; i++)
        printf("%s,\t", argv[i]);
    printf("\n");
    return 0;
}
int_回调(void*a_参数,int argc,char**argv,char**column){
对于(int i=0;i
本书的配套网站上有一些例子。特别是,第7章有一些C/C++API的示例


示例代码:

我正在使用一个简单的测试工具,使用一个包含字符字符串键和一个整数值的表,对SQLite进行一些实验。以下是我正在使用的实验测试工具的源代码。我拉取这些片段是为了显示表的创建以及使用SQLite的回调功能从select SQL语句创建记录集的函数。在不同的地方有
printf()
语句和
fprintf()
语句,因此我可以看到操作的结果,因为这是测试线束的一个简单控制台类型应用程序

请注意,有时您不需要回调参数,因此SQLite允许您指定一个空指针,指示您不需要回调

当你阅读源代码时,请记住这是一个实验性的黑客

创建表的函数如下所示:

int CreateSetupTable (sqlite3 *db)
{
    char *zErrMsg = 0;
    int rc;
    char  *aszSqlCreate = "create table tbl1(one varchar(10), two smallint)";
    char  *aszSqlCreateIndex01 = "create unique index index1 on tbl1 (one)";

    do {
        rc = sqlite3_exec(db, aszSqlCreate, 0, 0, &zErrMsg);
        if( rc!=SQLITE_OK ){
          fprintf(stderr, "SQL error: %s\n", zErrMsg);
          sqlite3_free(zErrMsg);
          break;
        }

        rc = sqlite3_exec(db, aszSqlCreateIndex01, 0, 0, &zErrMsg);
        if( rc!=SQLITE_OK ){
          fprintf(stderr, "SQL error: %s\n", zErrMsg);
          sqlite3_free(zErrMsg);
          break;
        }
    } while (0);  // loop only once to allow breaks on errors

    return rc;
}
int SelectRecord (sqlite3 *db, char *cSelect, char *cKey)
{
    char *zErrMsg = 0;
    int rc;
    char aszSqlSelect[128];
    Tbl1Record  myRec[20];
    RecordProcessor myProcessor;

    myProcessor.pRecordSet = myRec;
    myProcessor.nRecordSetActual = 0;
    myProcessor.nRecordSetMax = 20;

    if (cKey) {
        sprintf (aszSqlSelect, "select %s from tbl1 where one='%s'", cSelect, cKey);
    } else {
        sprintf (aszSqlSelect, "select %s from tbl1", cSelect);
    }
    rc = sqlite3_exec(db, aszSqlSelect, MyRecordProcessor, &myProcessor, &zErrMsg);
    if( rc!=SQLITE_OK ){
      fprintf(stderr, "SQL error SelectRecord: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
    } else {
        int i;
        for (i = 0; i < myProcessor.nRecordSetActual; i++) {
            printf ("Rec #%d cKey = %s iValue = %d\n", i+1, myRec[i].cKey, myRec[i].iValue);
        }
    }

    return rc;
}
我在这个表中插入一些记录,然后调用一个函数,使用select SQL语句从表中获取一个或多个记录。select函数检索记录并使用回调将返回的每个记录转换为C结构。C结构看起来像:

typedef struct {
    char cKey[20];
    int  iValue;
} Tbl1Record;
用于记录集的回调使用包含记录选择管理数据的结构。我的意思是,回调的第一个参数是指向结构的指针,该结构反过来指向放置转换数据的位置以及有关内存区域大小的一些信息。由于select可能会根据where子句返回多个记录,因此回调函数使用回调结构来了解它可以将多少转换记录放入内存区域以及索引,以便在放入记录时,它可以通过内存区域进行索引,以返回多个转换记录

回调管理结构如下所示:

typedef struct _RecordProcessor {
    void  *pRecordSet;
    int   nRecordSetMax;
    int   nRecordSetActual;
} RecordProcessor;
static int MyRecordProcessor (void *callBackArg, int argc, char **argv, char **azColName)
{
    int iRetStatus = 0;
    char *colNameTable[] = {
        "one",
        "two"
    };
    Tbl1Record *pTbl1Record = (Tbl1Record *)((RecordProcessor *)callBackArg)->pRecordSet;

    if (((RecordProcessor *)callBackArg)->nRecordSetActual < ((RecordProcessor *)callBackArg)->nRecordSetMax) {
        int i, j;
        int iIndex = ((RecordProcessor *)callBackArg)->nRecordSetActual;

        memset (pTbl1Record + iIndex, 0, sizeof(Tbl1Record));
        ((RecordProcessor *)callBackArg)->nRecordSetActual++;
        for (i = 0; i < argc; i++){
            int j;
            for (j = 0; j < sizeof (colNameTable)/sizeof(colNameTable[0]); j++) {
                if (strcmp (azColName[i], colNameTable[j]) == 0) {
                    switch (j) {
                        case 0:
                            strncpy (pTbl1Record[iIndex].cKey, (argv[i] ? argv[i] : "NULL"), 19);
                            break;
                        case 1:
                            pTbl1Record[iIndex].iValue = atoi (argv[i] ? argv[i] : "0");
                            break;
                        default:
                            break;
                    }
                    break;
                }
            }
        }
    }

    return iRetStatus;
}
select函数如下所示:

int CreateSetupTable (sqlite3 *db)
{
    char *zErrMsg = 0;
    int rc;
    char  *aszSqlCreate = "create table tbl1(one varchar(10), two smallint)";
    char  *aszSqlCreateIndex01 = "create unique index index1 on tbl1 (one)";

    do {
        rc = sqlite3_exec(db, aszSqlCreate, 0, 0, &zErrMsg);
        if( rc!=SQLITE_OK ){
          fprintf(stderr, "SQL error: %s\n", zErrMsg);
          sqlite3_free(zErrMsg);
          break;
        }

        rc = sqlite3_exec(db, aszSqlCreateIndex01, 0, 0, &zErrMsg);
        if( rc!=SQLITE_OK ){
          fprintf(stderr, "SQL error: %s\n", zErrMsg);
          sqlite3_free(zErrMsg);
          break;
        }
    } while (0);  // loop only once to allow breaks on errors

    return rc;
}
int SelectRecord (sqlite3 *db, char *cSelect, char *cKey)
{
    char *zErrMsg = 0;
    int rc;
    char aszSqlSelect[128];
    Tbl1Record  myRec[20];
    RecordProcessor myProcessor;

    myProcessor.pRecordSet = myRec;
    myProcessor.nRecordSetActual = 0;
    myProcessor.nRecordSetMax = 20;

    if (cKey) {
        sprintf (aszSqlSelect, "select %s from tbl1 where one='%s'", cSelect, cKey);
    } else {
        sprintf (aszSqlSelect, "select %s from tbl1", cSelect);
    }
    rc = sqlite3_exec(db, aszSqlSelect, MyRecordProcessor, &myProcessor, &zErrMsg);
    if( rc!=SQLITE_OK ){
      fprintf(stderr, "SQL error SelectRecord: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
    } else {
        int i;
        for (i = 0; i < myProcessor.nRecordSetActual; i++) {
            printf ("Rec #%d cKey = %s iValue = %d\n", i+1, myRec[i].cKey, myRec[i].iValue);
        }
    }

    return rc;
}
int-SelectRecord(sqlite3*db,char*cSelect,char*cKey)
{
char*zErrMsg=0;
int rc;
char aszSqlSelect[128];
tbl1记录myRec[20];
记录处理器;
myProcessor.pRecordSet=myRec;
myProcessor.nRecordSetActual=0;
myProcessor.nRecordSetMax=20;
如果(cKey){
sprintf(aszSqlSelect,“从tbl1中选择%s,其中一个='%s',cSelect,cKey);
}否则{
sprintf(aszSqlSelect,“从tbl1中选择%s”,cSelect);
}
rc=sqlite3_exec(db、aszSqlSelect、MyRecordProcessor和myProcessor以及zErrMsg);
如果(rc!=SQLITE_OK){
fprintf(stderr,“SQL错误选择记录:%s\n”,zErrMsg);
无sqlite3_(zErrMsg);
}否则{
int i;
对于(i=0;i
处理select返回的每条记录的回调如下所示:

typedef struct _RecordProcessor {
    void  *pRecordSet;
    int   nRecordSetMax;
    int   nRecordSetActual;
} RecordProcessor;
static int MyRecordProcessor (void *callBackArg, int argc, char **argv, char **azColName)
{
    int iRetStatus = 0;
    char *colNameTable[] = {
        "one",
        "two"
    };
    Tbl1Record *pTbl1Record = (Tbl1Record *)((RecordProcessor *)callBackArg)->pRecordSet;

    if (((RecordProcessor *)callBackArg)->nRecordSetActual < ((RecordProcessor *)callBackArg)->nRecordSetMax) {
        int i, j;
        int iIndex = ((RecordProcessor *)callBackArg)->nRecordSetActual;

        memset (pTbl1Record + iIndex, 0, sizeof(Tbl1Record));
        ((RecordProcessor *)callBackArg)->nRecordSetActual++;
        for (i = 0; i < argc; i++){
            int j;
            for (j = 0; j < sizeof (colNameTable)/sizeof(colNameTable[0]); j++) {
                if (strcmp (azColName[i], colNameTable[j]) == 0) {
                    switch (j) {
                        case 0:
                            strncpy (pTbl1Record[iIndex].cKey, (argv[i] ? argv[i] : "NULL"), 19);
                            break;
                        case 1:
                            pTbl1Record[iIndex].iValue = atoi (argv[i] ? argv[i] : "0");
                            break;
                        default:
                            break;
                    }
                    break;
                }
            }
        }
    }

    return iRetStatus;
}
静态int-MyRecordProcessor(void*callBackArg、int-argc、char**argv、char**azColName)
{
int-iRetStatus=0;
char*colNameTable[]={
“一个”,
“两个”
};
Tbl1Record*pTbl1Record=(Tbl1Record*)((RecordProcessor*)callBackArg)->预编码集;
如果(((RecordProcessor*)callBackArg)->nRecordSetActual<((RecordProcessor*)callBackArg)->nRecordSetMax){
int i,j;
int iIndex=((RecordProcessor*)callBackArg)->nRecordSetActual;
memset(pTbl1Record+iIndex,0,sizeof(Tbl1Record));
((RecordProcessor*)callBackArg)->nRecordSetActual++;
对于(i=0;i