在插入DB之前清理字符串

时间:2013-06-19 20:55:10

标签: mysql objective-c sqlite escaping

尝试将数据插入我的sqlite数据库时出现以下错误:

"sqlite near "t": syntax error"

我不知道这意味着什么: - (

背景:我正在使用mysql_real_escape_string来“清理”来自在线表单的数据(该表单提示用户将其信息输入文本字段并按“提交”) - 这完美地运行好吧:它允许接受所有单引号和双引号字符并将其输入数据库而不会出错。

接下来,我的iPhone应用程序查询此数据库并解析传入的数据 - 有趣的是,我随后得到了\“和\”所有地方(as-in:不要或\“The Odyssey \ “而不是没有或”奥德赛“)

为了解决这个问题,我使用[stringVar stringByReplacingOccurrencesOfString:@"\\" withString:@""] - 所以我基本上用无空间替换所有斜线 - 这完全可行(我得到:不要+“奥德赛”。)

但是,当我现在尝试将这个新下载和解析的数据写入我的 on-device sqlite数据库时 - 应用程序崩溃了。而且我相当肯定这与他们所有的单身&双引号,斜线,谁知道还有什么。

为了测试一些东西,我创建了一些不包含任何这些棘手字符的快速虚拟数据,将其插入数据库(在运行时)并且一切正常 - 应用程序没有崩溃,并且在设备上sqlite数据库显示一切正常 - 所以我相当确定我的sqlite数据库,我的sql语句等没有任何问题。它必须是下载的数据/字符串仍然以某种方式被破坏。

毋庸置疑,我不是SQL专家 - 我基本上都知道了最低限度,并且在我去的时候尝试学习。我已经研究了这个,并认为我找到了mysql_real_escape_string的解决方案,但似乎只有一种方式 - 除了我需要往返解决方案。

任何提示或建议?

======================================

编辑#1 - 这是我正在使用的代码 - 一个混合的建议和我在这本iPhone书中找到的内容:

NSString *sqlString = [NSString stringWithFormat:@"INSERT OR REPLACE INTO '%@' ('%@', '%@', '%@', '%@') VALUES (?, ?, ?, ?)", tableName, @"Title", @"Source", @"Date", @"StoryCopy"];

NSLog(@"The sql string is = '%@'", sqlString);
const char *sql = [sqlString UTF8String];
sqlite3_stmt *stmt;
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, nil);
if (rc == SQLITE_OK) {
    sqlite3_bind_text(stmt, 0, [sTitle UTF8String], -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(stmt, 1, [sSource UTF8String], -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(stmt, 2, [sDate UTF8String], -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(stmt, 3, [sCopy UTF8String], -1, SQLITE_TRANSIENT);
}

if (sqlite3_step(stmt) != SQLITE_DONE) {
    NSAssert(0, @"Error updating table!!!");
}

sqlite3_finalize(stmt);

问题是它将值插入到不应插入的列中。它到处都是。任何想法在这里有什么问题?

1 个答案:

答案 0 :(得分:3)

听起来你错误地执行了查询。没有必要先“消毒”任何东西。确保不使用字符串格式来构建查询。相反,请正确使用sqlite3_bind_xxx函数。

示例:

sqlite3_stmt *stmt;
int rc = sqlite3_prepare_v2(dbHandle, "INSERT INTO table_name (field1, field2) VALUES (?, ?)", -1, &stmt, nil);
if (rc == SQLITE_OK) {
    sqlite3_bind_text(stmt, 1, [someValue UTF8String], -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(stmt, 2, [otherValue UTF8String], -1, SQLITE_TRANSIENT);
}

其中someValueotherValueNSString个对象。该文本可以包含任何Unicode文本。使用sqlite_bind_text负责转义任何需要转义的字符。

稍后,当您使用sqlite3_column_text从查询中读取值时,您将返回原始文本。