【问题标题】:sqlite3_prepare_v2 failed (Xcode sqlite 3)sqlite3_prepare_v2 失败(Xcode sqlite 3)
【发布时间】:2016-03-26 00:50:51
【问题描述】:

我很想连接 sqlite 但不能。有人能帮我吗?我在这里根本看不到任何错误,我已经在谷歌和这里搜索了这个问题的高低,但我找不到任何方法来解决这个问题。

我正在关注教程here

请帮帮我,这个错误我快疯了。 =(

[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

sqlite3 *contactDB;  //declare pointer to database structurery
const char *dbPath = [databasePath UTF8String];  //convert NSString to UTF8String

//open database file. TRUE = success, FALSE = failed
if (sqlite3_open(dbPath, &contactDB)== SQLITE_OK){     
    NSLog(@"Opened");

sqlite3_stmt *statement;
NSString *querySQL =  @"SELECT address, phone FROM contacts";
const char *query_stmt = [querySQL UTF8String];

if (sqlite3_prepare_v2(contactDB, query_stmt, 1, &statement, NULL) == SQLITE_OK) {
    NSLog(@"Statement is OK");
}else{
    NSLog(@"Statement FAILED");
}

}else{
    NSLog(@"Failed");
}

日志只显示“Opened”然后是“Statement FAILED”

【问题讨论】:

  • 1.为什么要使用常量 NSString,然后使用 -[UTF8String]?如果是常量查询,最好使用常量 C 字符串。 2. 为什么使用复杂的 sqlite_prepare_v2 方式?我怀疑你需要 那个 太多的自定义。有一个名为 sqlite3_exec() 的函数。 3. 我使用这个的例子:github.com/H2CO3/libsqlitemanager
  • 下次发objective-c相关问题的时候记得加上objective-c标签。它告诉代码高亮显示代码实际上是 objc,而不是 sql / 其他语言。
  • 将 NSLog 更改为 NSLog(@"Statement FAILED (%s)", sqlite3_errmsg());
  • 你的 sqlite 数据库文件是否真的存在于databasePath 上?在使用数据库之前,您需要将 .sql 文件复制到应用程序的 CACHE 目录中。
  • 准备操作的返回码是什么??

标签: iphone objective-c ios sqlite


【解决方案1】:

这就是我的做法。 (我的数据库类的编译片段)
也会显示 sql 错误。

sqlite3 *_database;
sqlite3_open([databasePath UTF8String], &_database);

NSString *sqlStatement = @"SELECT address, phone FROM contacts";
const char *sql = [sqlStatement UTF8String];
static sqlite3_stmt *compiledStatement;
int result = sqlite3_prepare_v2(_database, sql, -1, &compiledStatement, NULL);
if(result != SQLITE_OK) {
    NSLog(@"Prepare-error #%i: %s", result, sqlite3_errmsg(_database));
}

result = sqlite3_step(compiledStatement);
if (result != SQLITE_DONE) {
    NSLog(@"Step-error #%i for '%@': %s", result, sqlStatement, sqlite3_errmsg(_database));
}

sqlite3_finalize(compiledStatement);

【讨论】:

  • 它说找不到表。我通过终端检查了 sqlite,它就在那里。
  • 如果您在模拟器上工作,请尝试从文件系统中删除 .sql 文件,然后重试,如果您在设备上工作;删除应用程序并重试。可能设备沙箱上的 .sql 文件已过时
  • 我在哪里可以找到那个 sql 文件?我拥有的数据库文件是 .db 格式。就像教程教我的那样
  • 如果在模拟器中运行:/Users//Library/Application Support/iPhone Simluator//Applications//
  • 请记住,您必须先将数据库复制到您的Caches 目录,然后才能使用它。像这样:dblog.com.au/iphone-development-tutorials/…
【解决方案2】:

错误就在这行代码中。

if (sqlite3_prepare_v2(contactDB, query_stmt, 1, &statement, NULL) == SQLITE_OK) {

1 是错误的。来自 SQLite 文档:

int sqlite3_prepare_v2(
  sqlite3 *db,            /* Database handle */
  const char *zSql,       /* SQL statement, UTF-8 encoded */
  int nByte,              /* Maximum length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
);

If the nByte argument is less than zero, then zSql is read up to the first zero
terminator. If nByte is non-negative, then it is the maximum number of bytes
read from zSql.

所以你强制 SQLite 只读取语句中的第一个字节。这当然是无效的。

【讨论】:

    【解决方案3】:

    确保您在项目中完成了这些要点。

    1. 验证文件是否列在 Target 的“Build Phases”下的“Copy Bundle Resources”下,而不是“Copy Files”下>" 带有自定义目标或子路径。

    2. 确保您的 sqlite 文件没有任何路径冲突。我的意思是文档 directory/database path/ 是正确的。

    3. 我已经实现了类似的 sqlite 查询

      SELECT * FROM someTable WHERE status LIKE 'someString' AND BankName LIKE 'someString' 而不是
      SELECT * FROM someTable WHERE status='someString' AND BankName='someString'

    4. 确保您没有在任何其他应用程序中包含您的 sqlite 文件

    5. 确保您没有具有相同路径的重复 sqlite 文件。

    经过很多努力,这对我有用,我希望它可以帮助一些人。如果有帮助,请投票。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-24
      • 2011-08-20
      • 1970-01-01
      • 2012-04-10
      相关资源
      最近更新 更多