如何将值从Cocoa传递给SQLite查询

时间:2009-12-07 00:53:30

标签: objective-c cocoa sqlite nsstring

首先请让我说我对客观的c开发很新。我正在为iphone编写一个供个人使用的小应用程序,但是在执行以下代码时遇到了一些问题:

NSString *sql = [[NSString alloc] initWithFormat:@"select color_r, color_g, color_b from Calendar where ROWID = %@", [calendarsID objectForKey:[arrayColors objectAtIndex:row]]];

sqlite3_stmt *selectstmt;

if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK)

编译器告诉我,我从不兼容的指针类型传递sqlite3_prepare_v2的参数2。无论如何,程序会被编译并运行,但是当它必须执行我刚刚向您显示的代码时,它会产生错误。它表示查询中存在语法错误,语法错误仅在查询的最后部分。而不是:

从日历中选择color_,color_g,color_b,其中ROWID = 63(例如)

我在最后一个数字(63)处得到奇怪的字符。我想这是一个与字符串转换有关的问题。可以请任何人帮助我吗?

非常感谢你的关注。 Alessio的

4 个答案:

答案 0 :(得分:6)

问题是NSString不是sqlite3_prepare_v2()第二个参数所期望的。它需要一个const char*。 C在这里有点松懈,它允许你隐式地将NSString*强制转换为const char*,这是错误的 - 编译器会给你一个你不应该忽略的警告。

您需要将NSString转换为const char*。最简单的方法是使用-UTF8String消息将其转换为UTF-8:

//                              V---- HERE ----V
if(sqlite3_prepare_v2(database, [sql UTF8String], -1, &selectstmt, NULL) == SQLITE_OK)

或者,在您不希望使用其他编码的情况下,您可以使用-cStringUsingEncoding:消息将字符串转换为使用特定字符编码的C字符串。

答案 1 :(得分:1)

我认为您的主要问题是您直接使用sqlite C api instead of a wrapper

答案 2 :(得分:1)

为什么不使用SQLite的value binding API?该陈述看起来像

SELECT color_r, color_g, color_b FROM Calendar WHERE ROWID = ?;

您可以将参数直接传递给SQLite,以便安全地插入查询中。这将保护您免受SQL注入攻击。 (您显示的示例可能是安全的,具体取决于这些值最终来自哪里,但使用sprintfstringWithFormat:来构建SQL查询是一个非常好的非常糟糕的习惯。不要被Little Bobby Tables 搞砸。)

至于你遇到问题的原因,SQLite不接受像NSString *这样的Cocoa类型。当您切换到使用SQLite格式化查询时,您将能够从其文档中学习您应该使用的类型。然后,您可以询问有关如何执行转换的其他问题。

答案 3 :(得分:0)

Alessio的,

用更多细节回答这个问题会更容易。例如,arrayColors中的对象类型是什么?

如果arrayColors中的对象不是NSStrings,那么你想调用一个方法(例如描述)来创建一个NSString表示。

亚伦