当db-journal文件存在时,准备语句会导致SQLITE_IOERR_LOCK

时间:2013-01-25 16:03:41

标签: c sqlite

我在C(Linux RHEL5,64位)中使用sqlite3 API从崩溃中恢复时出现问题,我在其中留下了.db.db-journal文件。

如果我使用.db二进制文件检查sqlite3文件并运行SELECT * from t;,则二进制文件将删除.db-journal文件并恢复正常。

在我的应用中,我会在有效的sqlite*上准备相同的声明,然后返回SQLITE_IOERR | SQLITE_IOERR_LOCK

#define SQLITE_IOERR_LOCK              (SQLITE_IOERR | (15<<8))
#define SQLITE_IOERR       10   /* Some kind of disk I/O error occurred */

如何告诉sqlite我希望它能用db-journal文件恢复?

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

int main(int argc,char* argv[])
{
    sqlite3* db_ptr = NULL;
    int sqlite_result = SQLITE_ERROR;
    sqlite3_stmt* query=NULL;
    int prepare_result=-1;

    if ( argc > 2 )
    {
        sqlite_result = sqlite3_open_v2(argv[1],
                                        &db_ptr,
                                        SQLITE_OPEN_READONLY,
                                        NULL);
        if ( sqlite_result == SQLITE_OK )
        {
            sqlite3_extended_result_codes(db_ptr,1);
            prepare_result = sqlite3_prepare_v2(db_ptr,
                                                argv[2],
                                                strlen(argv[2])+1,
                                                &query,
                                                NULL);
            sqlite3_close(db_ptr);
            if ( prepare_result != SQLITE_OK )
            {
                fprintf(stderr,"Error: %d\n",prepare_result);
            }
            else
            {
                fprintf(stdout,"Success\n");
            }
        }
    }

    return prepare_result;
}

结果:

Error: 3850

1 个答案:

答案 0 :(得分:1)

我在阅读我的问题时找到了答案......显然要恢复到db文件,程序需要使用READWRITE访问权限打开它。咄。改变:

    sqlite_result = sqlite3_open_v2(argv[1],
                                    &db_ptr,
                                    SQLITE_OPEN_READONLY,
                                    NULL);

为:

    sqlite_result = sqlite3_open_v2(argv[1],
                                    &db_ptr,
                                    SQLITE_OPEN_READWRITE,
                                    NULL);

解决了这个问题。在真正的程序中,而不是测试应用程序,我打开了远离准备声明,我甚至没有注意到在那个特定情况下它是READONLY。