【问题标题】:iPhone - Using sql database - insert statement failingiPhone - 使用 sql 数据库 - 插入语句失败
【发布时间】:2011-06-01 04:00:44
【问题描述】:

我在我的 iphone 应用程序中使用 sqlite 数据库。 我有一个有 3 个整数列的表。 我正在使用以下代码写入该数据库表。

-(BOOL)insertTestResult {
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
NSString* dataBasePath = [documentsDirectory stringByAppendingPathComponent:@"test21.sqlite3"];     

BOOL success = NO;
sqlite3* database = 0;
if(sqlite3_open([dataBasePath UTF8String], &database) == SQLITE_OK) 
{
    BOOL res = (insertResultStatement == nil) ? createStatement(insertResult, &insertResultStatement, database) : YES;
    if(res)
    {
        int i = 1;
        sqlite3_bind_int(insertResultStatement, 0, i);
        sqlite3_bind_int(insertResultStatement, 1, i);
        sqlite3_bind_int(insertResultStatement, 2, i);

        int err = sqlite3_step(insertResultStatement);
        if(SQLITE_ERROR == err) 
        {
            NSAssert1(0, @"Error while inserting Result. '%s'", sqlite3_errmsg(database));
            success = NO;
        }
        else 
        {
            success = YES;
        }
        sqlite3_finalize(insertResultStatement);
        insertResultStatement = nil;            
    }
}
sqlite3_close(database);    
return success;}

命令 sqlite3_step 总是给出 err 为 19。我无法理解问题出在哪里。

表是使用以下查询创建的:

CREATE TABLE [Patient](PID 整数 NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,PFirstName text NOT NULL,PLastName text,PSex text NOT NULL,PDOB text NOT NULL,PEducation text NOT NULL,PHandedness text,PType text)

CREATE TABLE PatientResult(PID INTEGER,PFreeScore INTEGER NOT NULL,PForcedScore INTEGER NOT NULL,FOREIGN KEY (PID) REFERENCES Patient(PID))

我在患者表中只有一个 PID = 1 的条目

BOOL createStatement(const char* query, sqlite3_stmt** stmt, sqlite3* database){
BOOL res = (sqlite3_prepare_v2(database, query, -1, stmt, NULL) == SQLITE_OK);
if(!res) 
    NSLog( @"Error while creating %s => '%s'", query, sqlite3_errmsg(database));
return res;}

【问题讨论】:

    标签: iphone insert sqlite


    【解决方案1】:

    我已更新您的代码。这样做:

    -(BOOL)insertTestResult {
        NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString* documentsDirectory = [paths objectAtIndex:0];
        NSString* dataBasePath = [documentsDirectory stringByAppendingPathComponent:@"test21.sqlite3"];     
    
        BOOL success = NO;
        sqlite3* database = 0;
        if(sqlite3_open([dataBasePath UTF8String], &database) == SQLITE_OK) 
        {
            BOOL res = (insertResultStatement == nil) ? createStatement(insertResult, &insertResultStatement, database) : YES;
            if(res)
            {
                int i = 1;
                sqlite3_bind_int(insertResultStatement, 1, i);  //updated
                sqlite3_bind_int(insertResultStatement, 2, i);  //updated
                sqlite3_bind_int(insertResultStatement, 3, i);  //updated
    
                int err = sqlite3_step(insertResultStatement);
                if(SQLITE_ERROR == err) 
                {
                    NSAssert1(0, @"Error while inserting Result. '%s'", sqlite3_errmsg(database));
                    success = NO;
                }
                else 
                {
                    success = YES;
                }
                sqlite3_finalize(insertResultStatement);
                insertResultStatement = nil;            
            }
        }
        sqlite3_close(database);    
        return success;
    }
    

    原因是你从0开始索引,这是错误的。在数据库表中插入时,需要从索引1开始插入,索引0在尝试从数据库中取数据时开始。

    【讨论】:

      【解决方案2】:

      Google 找到了this,它告诉我:

      #define SQLITE_CONSTRAINT  19   /* Abort due to constraint violation */
      

      您在某处违反了约束。我的猜测是您的 PID 不是唯一的,或者患者的外键未引用有效的患者 ID。

      【讨论】:

      • 在我的主表中,我只有一个条目。所以不存在唯一性的问题。我可以通过手动查询在 sqlitemanager 中执行相同的操作。您还可以在我的 PatientResult 表中看到我的硬编码值。
      • 停止假设你做的一切都是正确的。相信你收到的信息并开始寻找你做错了什么。
      【解决方案3】:

      我做了一点改变(基于反复试验)和它的工作原理。我不知道原因,为什么它的工作........这是我的代码更改:

      sqlite3_bind_int(insertResultStatement, 1, i);
      sqlite3_bind_int(insertResultStatement, 2, i);
      sqlite3_bind_int(insertResultStatement, 3, i);
      

      变化在于,以前我的第一个 sqlite3_bind_int 第二个参数以“0”开头,而不是以“1”开头。

      如果有人找到原因,请更新这个链......

      【讨论】:

        【解决方案4】:

        如果您还发布了您的 createStatement() 代码,将会有所帮助。没有它,我猜你没有在 INSERT 中为你的一个 NOT NULL 列指定一个值。

        【讨论】:

        • 请看我更新的描述。我添加了 createStatement() 代码。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多