【问题标题】:sqlite3 prepare statement not working, possibly improper pointers iOSsqlite3 prepare 语句不起作用,可能是不正确的指针 iOS
【发布时间】:2015-02-28 06:44:25
【问题描述】:

我已经设置了一个 GlobalVars 类来保存我的 sqlite3 数据库变量。

static sqlite3** database;
const char *dbPath;


@implementation GlobalVars : NSObject

+(GlobalVars*)sharedInstance {
    static GlobalVars *myInstance = nil;
    if(myInstance == nil) {
        myInstance = [[[self class] alloc] init];
    }

    return myInstance;
}

+(sqlite3*)getGlobalDatabase {
    return &database;
}

+(void)setGlobalDatabase:(sqlite3*)_database {
    database = &_database;
}

然后在我的头文件中

static sqlite3** database;

在界面上方。这就是我设置数据库变量的方式。

然后,当我打开数据库并准备它时,我会尝试访问它。我可以打开它,因为 open 调用返回 true。我无法正确准备它,因为该语句返回 false 并且它没有进入 if 语句。我想知道我是否弄乱了我的指针,因为准备语句不起作用,并且没有正确准备。

-(void)setAllValues:(NSMutableArray*)array {
if(sqlite3_open([GlobalVars getGlobalDBPath], [GlobalVars getGlobalDatabase]) == SQLITE_OK) {
    sqlite3_stmt *insertStatement;
    NSString *sqlInsert = [NSString stringWithFormat:@"insert into my_table ('_id', 'name', 'age', 'weight', 'height', 'description') VALUES (%i, '%@', '%i', '%i', '%@', '%@')", ID, name, age, weight, height, description];

//*********** This is not opening, and SQLITE_OK is equal to false ***********

if(sqlite3_prepare_v2(([GlobalVars getGlobalDatabase]), [sqlInsert UTF8String], -1, &insertStatement, nil) == SQLITE_OK) {
        if(sqlite3_step(insertStatement) == SQLITE_DONE) {
            NSLog(@"insert stepping done");
        }

        sqlite3_reset(insertStatement);
    }
    sqlite3_finalize(insertStatement);
    sqlite3_close([GlobalVars getGlobalDatabase]);
}
}

数据库的变量都填充了正确的数据,打开数据库似乎没有问题。在准备时,它无法正常工作并返回false。任何想法为什么。感谢您的帮助,感谢您的帮助。

【问题讨论】:

  • 当对sqlite3_prepare_v2 的调用失败时记录sqlite3_errmsg。
  • 那么,sqlite3_errmsg 是怎么说的呢?从 sqlite3_prepare_v2 返回的返回码是什么?
  • @HotLicks sqlite3_errmsg 说“库例程调用乱序”
  • 呃,你处理“GlobalDatabase”的方式坏了。您的间接方式都是错误的,并且可以肯定的是,它应该在 open 和 prepare 之间有所不同(事实并非如此)。
  • (我怀疑你不懂C语言间接。)

标签: ios objective-c pointers sqlite


【解决方案1】:

**

你必须试试这个......也许它对你有帮助:

**

    #import "DBManager.h"
#import "userRegistrationClass.h"

static DBManager *sharedInstance = nil;
static sqlite3 *database = nil;
static sqlite3_stmt *statement = nil;

@implementation DBManager


#pragma mark
#pragma mark Get shared Function
+(DBManager*)getSharedInstance{
    if (!sharedInstance) {
        sharedInstance = [[super allocWithZone:NULL]init];
        [sharedInstance createDB];
    }
    return sharedInstance;
}

#pragma mark
#pragma mark Create DataBase
-(BOOL)createDB{
    NSString *docsDir;
    NSArray *dirPaths;
    // Get the documents directory
//    http://www.mycashkit.com/my-earnings.php
    dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSLog(@"Dir Path Value is  %@",dirPaths);
    docsDir = [dirPaths objectAtIndex:0];
    NSLog(@"DocsDir Path Value is %@",docsDir);
    // Build the path to the database file
    databasePath = [[NSString alloc] initWithString:[docsDir stringByAppendingPathComponent: @"UserRegInfo.sqlite"]];
    NSLog(@"Data base Work's %@:",databasePath);
    BOOL isSuccess = YES;
    NSFileManager *filemgr = [NSFileManager defaultManager];
   // NSString *currentPath = [filemgr currentDirectoryPath];
    NSLog(@"My file managaer value is %@",filemgr);
    //NSLog(@"My current drictory path is %@",currentPath);
    //the file will not be there when we load the application for the first time
    //so this will create the database table
    if ([filemgr fileExistsAtPath: databasePath ] == NO)
    {
        const char *dbpath = [databasePath UTF8String];

        NSLog(@"Constan charcter value is %s:-",dbpath);

        if (sqlite3_open(dbpath, &database) == SQLITE_OK)
        {
            char *errMsg;
            const char *sql_stmt = "create table if not exists UserInfo(UserID integer primary key, UserName,Gender,UserEmailID,Password,RePassword,DOB, MobileNo,IsUserType)";
            const char *sql_stmt2 = "create table if not exists TestInfo(TestID integer primary key, TestName,TestType)";

//            NSString *dbPathFromApp=[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"UserRegInfo.sqlite"];[filemgr copyItemAtPath:dbPathFromApp toPath:databasePath error:nil];

            NSLog(@"Constan charcter value is %s:-",dbpath);
            if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg) && (sqlite3_exec(database, sql_stmt2, NULL, NULL, &errMsg)!= SQLITE_OK))
            {
                isSuccess = NO;
                NSLog(@"Failed to create table");
            }
            NSLog(@"Print Sqlite%d",(sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg)));
            sqlite3_close(database);
            return  isSuccess;
        }
        else {
            isSuccess = NO;
            NSLog(@"Failed to open/create database");
        }

    }
    return isSuccess;
}
#pragma mark
#pragma mark Save Data Function

-(BOOL)saveData:(NSString*)insertSQL{
    const char *dbpath = [databasePath UTF8String];
    if (sqlite3_open(dbpath, &database) == SQLITE_OK)
    {

        NSLog(@" my Sqlite Query is :- %@",insertSQL);
        const char *insert_stmt = [insertSQL UTF8String];
        sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL);
        if (sqlite3_step(statement) == SQLITE_DONE)
        {
            return YES;
        }
        else
        {
            NSLog(@"Squlite Error Msg is %s",sqlite3_errmsg(database));
            return NO;
        }
    }
    return NO;
}

【讨论】:

  • 这段代码有很多问题。 saveData 方法打开数据库但不关闭它。 saveData 方法准备了一个语句,但没有完成它。对sqlite3_exec 的两次调用没有适当的错误检查。
  • 工作和正确并不总是一回事。您需要解决问题,否则最终会遇到问题。
猜你喜欢
  • 1970-01-01
  • 2016-01-17
  • 2012-11-08
  • 1970-01-01
  • 2014-03-08
  • 1970-01-01
  • 2012-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多