Insert语句不检查重复值

时间:2011-08-28 13:23:10

标签: iphone objective-c ios sqlite

我正在尝试在创建表时使用UNIQUE标识符来防止重复输入我的sqlite数据库。信息(包括主键)通过Web服务返回的一些json数据插入。

虽然我理解不使用自动生成的主键的含义,但对业务模型是必要的。

如果Web服务偶然返回已存在的记录,那么您将认为它不会再次插入数据,而是抛出错误。事实并非如此。

有没有人知道防止这种情况发生的方法?

创建声明

CREATE TABLE "Data" ("Id" INTEGER PRIMARY KEY NOT NULL UNIQUE , "DataText" TEXT NOT NULL , "CategoryId" INTEGER NOT NULL )

插入代码

if (sqlite3_open([[self getDatabaseConnection] UTF8String], &database) == SQLITE_OK)
    {        
        const char *sql = "INSERT INTO Data (Id, CategoryId, DataText) Values(?, ?, ?)";
        if(sqlite3_prepare_v2(database, sql, -1, &addStatement, NULL) != SQLITE_OK)
        {
            NSLog(@"Error while creating add statement. '%s'", sqlite3_errmsg(database));
        }
        else
        {
            sqlite3_bind_int64(addStatement, 1, dataId);
            sqlite3_bind_int64(addStatement, 2, categoryId);
            sqlite3_bind_text(addStatement, 3, [dataText UTF8String], -1, SQLITE_TRANSIENT);

            if(SQLITE_DONE != sqlite3_step(addStatement))
            {
                NSLog(@"Error while inserting data. '%s'", sqlite3_errmsg(database), nil);
            }
        }
        //Reset the add statement.
        sqlite3_reset(addStatement);
    }
    sqlite3_close(database);

1 个答案:

答案 0 :(得分:2)

假设您有一个名为PRODUCTS的表,它包含此值:

               ProductID|ProductName
               50|widget

ProductID是主键。

除非您在[productname]上有唯一索引,否则可以插入此记录:

              60|widget

但是,即使您在productname上没有唯一索引,也无法插入产品为50的任何其他记录,无论产品名称是什么,因为主键值为50的行已经存在

附录:

现在让我们假设您愿意接受“小部件”的多个实例但不属于同一类别。你可以拥有“屋顶小工具”和“地板小工具”。在这种情况下,除了整数id列上的主键唯一约束外,您还可以在此备用复合键上放置一个唯一约束:(productname,categoryid)。

ADDENDUM2:

INTEGER PRIMARY KEY应该足够了。你不应该需要NOT NULL UNIQUE。 http://www.sqlite.org/lang_createtable.html#rowid