开发者社区 问答 正文

obj-c中动态ALTERsqlite 3_BIND_Text语句的语法错误

此代码引发错误。[logging] near "?": syntax error in "ALTER TABLE jobs ADD COLUMN ? TEXT NOT NULL"

NSArray *uArray = [NSArray arrayWithObjects:@"string1", @"string2", @"etc", nil];

    const char *query = "ALTER TABLE jobs ADD COLUMN ? TEXT NOT NULL";
    sqlite3_stmt *compiledStatement = nil;

    sqlite3_exec((sqlite3 *)(db), "BEGIN EXCLUSIVE TRANSACTION", 0, 0, 0);
    if(sqlite3_prepare((sqlite3 *)(db), query, -1, &compiledStatement, NULL) == SQLITE_OK)
    {
      for (NSString *obj in uArray)
      {
          sqlite3_bind_text(compiledStatement, 1, [obj UTF8String], -1, SQLITE_STATIC);
          if (sqlite3_step(compiledStatement) != SQLITE_DONE) NSLog(@"DB not updated. Error: %s",sqlite3_errmsg((sqlite3 *)(db)));
          if (sqlite3_reset(compiledStatement) != SQLITE_OK) NSLog(@"SQL Error: %s",sqlite3_errmsg((sqlite3 *)(db)));
      }
    }

我看不出它在说什么?不能与ALTERT一起使用

展开
收起
游客5akardh5cojhg 2019-12-05 21:37:29 468 分享 版权
阿里云 AI 助理回答

这个错误是因为在SQLite SQL语句中,你不能直接使用问号(?)作为列名的占位符。问号通常用于绑定变量的值,而不是列名或者表名。当你需要动态地添加列时,你需要先构造完整的SQL字符串,然后再执行。

基于你的需求,你可以通过以下方式修改代码来避免这个错误:

// 假设你想动态添加的是uArray中的第一个元素作为列名
NSString *columnName = uArray[0];

// 构建完整的ALTER TABLE语句
NSString *query = [NSString stringWithFormat:@"ALTER TABLE jobs ADD COLUMN %@ TEXT NOT NULL", columnName];

// 转换为UTF8编码的C字符串
const char *sql = [query UTF8String];

sqlite3_stmt *compiledStatement = nil;

// 开始事务
sqlite3_exec((sqlite3 *)(db), "BEGIN EXCLUSIVE TRANSACTION", 0, 0, 0);

if(sqlite3_prepare((sqlite3 *)(db), sql, -1, &compiledStatement, NULL) == SQLITE_OK) {
    // 执行预编译的SQL语句
    if(sqlite3_step(compiledStatement) != SQLITE_DONE) {
        NSLog(@"Error adding column: %s", sqlite3_errmsg((sqlite3 *)(db)));
    }
} else {
    NSLog(@"Error preparing statement: %s", sqlite3_errmsg((sqlite3 *)(db)));
}

// 清理和结束事务
sqlite3_finalize(compiledStatement);
sqlite3_exec((sqlite3 *)(db), "COMMIT", 0, 0, 0);

这段代码首先从uArray中取出一个字符串作为列名,然后将其格式化到ALTER TABLE语句中,最后执行这个完整的SQL语句。这样可以确保SQL语法正确,同时也能动态地添加列。注意,这样做存在SQL注入的风险,因此在实际应用中,如果列名来源于不可控的输入,应当进行适当的验证和清理。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答分类:
SQL
问答地址: