【问题标题】:iOS sqlite insert statments with variables带有变量的 iOS sqlite 插入语句
【发布时间】:2016-03-31 20:55:45
【问题描述】:

我正在学习如何在IOS中使用sqlite

我正在使用以下方法将记录插入表中

 int DBID =  [_db  ExecuteINSERT:@"INSERT INTO LOG(NAME , COMPANY , CATEGORY)   VALUES('txt1','txt2','txt3')"];

这很好,并将三个字符串添加到一行中

我想用硬编码的字符串交换字符串变量,但可以弄清楚该怎么做。我试过了

NSString* myString1 = @"String1";
NSString* myString2 = @"String2";
NSString* myString3 = @"String3";
int DBID = _db  ExecuteINSERT:@"INSERT INTO LOG(NAME , COMPANY,     CATEGORY) VALUES(myString1, myString2, myString3)"];

但我得到一个 sqlite 错误 1 ​​没有这样的列,但它可以与硬编码字符串一起使用

有什么想法我哪里出错了吗?

任何帮助表示赞赏

标记

【问题讨论】:

    标签: ios sqlite insert


    【解决方案1】:

    您声明了 3 次相同的字符串,但我认为这只是您问题中的一个错字,而您真正拥有(或至少意味着)的是:

    NSString* string1 = @"String1";
    NSString* string2 = @"String2";
    NSString* string3 = @"String3";
    

    您的下一个问题是您已将变量名称作为文字字符串包含在 " 中 - 这意味着 SQL 语句将包含“string1”而不是您所追求的 string1 的值。

    由于您使用 SQLite 的包装器,因此您可以使用 stringWithFormat 创建插入语句,并替换字符串变量的值

    NSString *sqlStatement=[NSString stringWithFormat:@"INSERT INTO LOG(NAME, COMPANY,CATEGORY) values (\"%@\",\"%@\",\"%@\")",string1,string2,string3];
    int DBID = [_db  ExecuteINSERT:sqlStatement];
    

    值得注意的是,这是不安全的,因为您无法防范 SQL injection 从用户输入中获取值。这在移动设备上可能不是问题;用户能做的最糟糕的事情就是影响他们自己的数据库。

    如果您不使用包装器,技术上正确的方法是使用 sqlite3_prepare_v2 -

    sqlite3_stmt *statement;
    NSString *insertSQL = @"INSERT INTO LOG(NAME, COMPANY,CATEGORY) values (?,?,?)"; 
    const char *insert_stmt = [insertSQL UTF8String];
    if (sqlite3_prepare_v2(_db, insert_stmt,-1, &statement, NULL)!= SQLITE_OK) {
        // LOG THE ERROR
        NSLog(@"Error: failed to perpare statement with message '%s'.", sqlite3_errmsg(_db));
    }
    else {
        // Bind values to the statement
        sqlite3_bind_text(statement,1,[string1 UTF8String],-1,SQLITE_TRANSIENT);
        sqlite3_bind_text(statement,2,[string2 UTF8String],-1,SQLITE_TRANSIENT);
        sqlite3_bind_text(statement,3,[string3 UTF8String],-1,SQLITE_TRANSIENT);
        double retValue = sqlite3_step(statement);
        if (retValue == SQLITE_DONE) {
                NSLog(@"Insert successful");
        }
        sqlite3_reset(statement);
        sqlite3_finalize(statement);
    }
    

    第二个代码块创建一个包含三个占位符(?,?,?) 的语句,然后用sqlite3_bind_text 将字符串替换为这些占位符。最后用 sqlite3_step 执行语句。

    最后几行刚刚清理完毕。

    【讨论】:

    • 是的,抱歉,这是一个错字副本,并且已经过去了。即使我更改为三个单独的字符串,我也会遇到同样的错误,您的代码让我感到困惑为什么它适用于硬编码字符串而不是变量
    • 它将使用我展示的第一个代码块并带有警告“不要这样做”。第二个代码块创建一个包含三个占位符 (?,?,?) 的语句,然后用“sqlite3_bind_text”将字符串替换为占位符,最后使用sqlite3_step 执行该语句。您想使用 sqlite3 有什么特别的原因吗?如果您不开发跨平台,通常使用 Core Data 更容易。虽然 Core Data 不是关系型数据库,但这通常不是移动应用程序的问题
    • 我将您的代码粘贴到我的代码中,并且到处都出现错误我不认为我可以混合使用它我习惯使用 sqlite 并在 windows、android 等上使用没有问题非常新IOS 只是在我知道有效的东西时尽量不产生全新的倾斜曲线
    • 如果您不使用 sqlite3,您可能需要更改调用,但您绝对应该查看您正在使用的库的文档,以找到准备 sql 语句的正确方法,然后绑定价值观。这被认为是 SQL 的最佳实践
    • 我刚刚修正了几个错别字
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-07
    • 1970-01-01
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多