【问题标题】:Android LogCat sqlite syntax error meaningAndroid LogCat sqlite 语法错误含义
【发布时间】:2012-11-19 02:54:33
【问题描述】:

我得到下面的日志猫错误:

 11-18 21:37:49.700: E/AndroidRuntime(19122): Caused by: android.database.sqlite.SQLiteException: no such column: Home1: , while compiling: SELECT _id FROM projects WHERE _name like Home1
11-18 21:37:49.700: E/AndroidRuntime(19122):    at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
11-18 21:37:49.700: E/AndroidRuntime(19122):    at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:68)
11-18 21:37:49.700: E/AndroidRuntime(19122):    at android.database.sqlite.SQLiteProgram.compileSql(SQLiteProgram.java:143)
11-18 21:37:49.700: E/AndroidRuntime(19122):    at android.database.sqlite.SQLiteProgram.compileAndbindAllArgs(SQLiteProgram.java:361)
11-18 21:37:49.700: E/AndroidRuntime(19122):    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:127)
11-18 21:37:49.700: E/AndroidRuntime(19122):    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:94)
11-18 21:37:49.700: E/AndroidRuntime(19122):    at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:53)
11-18 21:37:49.700: E/AndroidRuntime(19122):    at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:47)
11-18 21:37:49.700: E/AndroidRuntime(19122):    at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1697)
11-18 21:37:49.700: E/AndroidRuntime(19122):    at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1582)
11-18 21:37:49.700: E/AndroidRuntime(19122):    at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1538)
11-18 21:37:49.700: E/AndroidRuntime(19122):    at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1618)
11-18 21:37:49.700: E/AndroidRuntime(19122):    at com.example.home_painter.DatabaseHandler.checkName(DatabaseHandler.java:334)
11-18 21:37:49.700: E/AndroidRuntime(19122):    at com.example.home_painter.MainActivity.addProject(MainActivity.java:37)
11-18 21:37:49.700: E/AndroidRuntime(19122):    ... 14 more

这是因为“SELECT _id FROM projects WHERE _name like Home1”的语法不正确吗?我似乎无法弄清楚这个错误的原因。

这是我的 sqldatabaseHelper 文件中的一些代码: 变量:

  // table name
private static final String TABLE_PROJECTS = "projects";
private static final String TABLE_IMAGES = "images";
private static final String TABLE_COLOR_MAP = "colorMap";
private static final String TABLE_COLORS_COLLECTION = "collection";

// Project Table columns names
private static final String KEY_ID = "_id"; // Primary, integer
private static final String KEY_NAME = "_name"; // Unique, text

OnCreate 方法:

  public void onCreate(SQLiteDatabase db) {

    // FOREIGN KEYS
    String FOREIGN_KEYS = "PRAGMA foreign_keys = ON;";

    // PROJECTS TABLE
    String CREATE_PROJECTS_TABLE = "CREATE TABLE " + TABLE_PROJECTS 
            + "(" + KEY_ID + " INTEGER NOT NULL, " + KEY_NAME + " TEXT NOT NULL, " +" PRIMARY KEY("
            + KEY_ID + "), UNIQUE( "+ KEY_NAME + "))";

    // IMAGES TABLE
    String CREATE_IMAGES_TABLE = "CREATE TABLE " + TABLE_IMAGES + "(" + KEY_IM_ID + " INTEGER NOT NULL, "
            + IM_URI + " TEXT, PRIMARY KEY(" + KEY_IM_ID+ "))";

    // COLOR MAP TABLE
    String CREATE_COLOR_MAP_TABLE = "CREATE TABLE " + TABLE_COLOR_MAP + "(" + PROJ_COLOR_ID + " INTEGER NOT NULL, "
            + COLLECTION_COLOR_ID + " INTEGER NOT NULL, FOREIGN KEY(" + PROJ_COLOR_ID + ") REFERENCES " 
            + TABLE_PROJECTS + "(" + KEY_ID + "), FOREIGN KEY(" + COLLECTION_COLOR_ID + ") REFERENCES " + TABLE_COLORS_COLLECTION
            + "(" + KEY_ID_COLLECT + "))";

    // COLLECTION COLOR TABLE
    String CREATE_COLORS_COLLECTION = "CREATE TABLE " + TABLE_COLORS_COLLECTION + "("
            + KEY_ID_COLLECT + " INTEGER NOT NULL, " + COLLECTION_HEX + " TEXT NOT NULL, "
            + COLLECTION_NAME + " TEXT NOT NULL, PRIMARY KEY(" + KEY_ID_COLLECT + "), UNIQUE("
            + COLLECTION_NAME + "))";
    /*System.out.println(CREATE_PROJECTS_TABLE);
    System.out.println(CREATE_IMAGES_TABLE);
    System.out.println(CREATE_COLORS_TABLE);*/

    db.execSQL(FOREIGN_KEYS);
    db.execSQL(CREATE_PROJECTS_TABLE);
    db.execSQL(CREATE_IMAGES_TABLE);
    db.execSQL(CREATE_COLORS_COLLECTION);
    db.execSQL(CREATE_COLOR_MAP_TABLE);


}

onUpgrade方法:

   public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    //Drop older tables if existing
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_PROJECTS);
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_IMAGES);
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_COLORS_COLLECTION);
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_COLOR_MAP);
    // Create tables again
    onCreate(db);
}

我认为与我从 project.java 获取信息以放入数据库的方法相关的代码:

values_PT.put(KEY_NAME, project.getName()); // project name
long project_id = db.insert(TABLE_PROJECTS, null, values_PT); // insert into database and save id for use

checkName 方法的代码:

  public boolean checkName(String name) {

    boolean resultName = false;
    SQLiteDatabase db = this.getReadableDatabase();

    Cursor c = db.query(TABLE_PROJECTS, new String[]{KEY_ID}, KEY_NAME + " like " + name, null, null, null, null);

    if (c != null) {

        resultName = true;
    }

    return resultName;
}

【问题讨论】:

  • _name like Home1 中的 Home1 是一个 SQL 标识符,您需要一个 LIKE 可以理解的字符串模式。对占位符做一些阅读,不要将字符串粘贴在一起来构建 SQL,除非您确切知道自己在做什么并且非常小心。
  • 另一个提示:Home1 是一个标识符,'Home1' 是一个字符串,? 是一个占位符,您可以让驱动程序用正确引用的字符串替换它。我不太了解 Android 库,无法提供真正的答案,但这应该足以让您入门。
  • 这样吗? db.query(TABLE_PROJECTS, new String[]{KEY_ID}, KEY_NAME + "=?", new String[] {name}, null, null, null);
  • 我不知道 Android API 在我的脑海中,但看起来你正在朝着正确的方向前进。
  • @muistooshort 如果您将此作为答案发布,我会接受。它似乎已经解决了这个问题。

标签: android database sqlite logcat android-sqlite


【解决方案1】:

您发送到 SQLite 的 SQL 如下所示:

SELECT _id FROM projects WHERE _name like Home1

SQLite 将您的 Home1 解释为列名,因为,一个不带引号的字符串值是 SQL 中的标识符。这就是您的“未知列”错误的来源。你想要这样的东西进入 SQLite:

SELECT _id FROM projects WHERE _name like 'Home1'

或(可能)更好:

SELECT _id FROM projects WHERE _name = 'Home1'

如果您没有使用_% 通配符,那么LIKE 通常只是= 的一个过于复杂且昂贵的版本。

我们如何解决这个问题?您可以尝试手动引用name,但这在 2012 年很愚蠢,我们有占位符将引用和转义问题推送到它们所属的数据库中。我想你想用这样的db.query call:

db.query(TABLE_PROJECTS, new String[]{KEY_ID}, KEY_NAME + "=?", new String[] {name}, null, null, null);

? 占位符将替换为 name 的值(正确引用和转义)。使用占位符还有助于保护您免受 SQL 注入问题的影响,因此这是一个好习惯。

【讨论】:

    【解决方案2】:

    你使用查询:

    "SELECT _id FROM projects WHERE _name like Home1"
    

    但是,在您的表 PROJECTS 中没有 _id 和 _name 列。你有 key_id 和 key_name。因此将查询更改为:

    "SELECT key_id FROM projects WHERE key_name like Home1"
    

    【讨论】:

    • 对不起,我编辑了我的问题,因为我忘了包含变量。 KEY_ID = "_id"
    • 但是Home1 还是个问题,看我对这个问题的评论。
    【解决方案3】:

    您的查询必须是:

    Cursor c = db.query(TABLE_PROJECTS, new String[]{KEY_ID}, KEY_NAME + " like ?",new String[]{"'"+name+"%'"}, null, null, null);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-05
      • 2014-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-15
      • 2015-03-25
      相关资源
      最近更新 更多