SQLite异常:接近" "语法错误



我的SQLiteOpenHelper类:

public class MyUsersDatabaseAdapter
{
    MyUsersDatabase myUsersDatabase;
    SQLiteDatabase sqLiteDatabase;
public MyUsersDatabaseAdapter(Context context, String name, CursorFactory factory,int version)
{
    myUsersDatabase = new MyUsersDatabase(context, name, factory, version);
}
public long inserDataToDatabase(String firstName,String lastName)
{
    sqLiteDatabase = myUsersDatabase.getWritableDatabase(); // sqliteDatabase is a reference to my database
    ContentValues contentValues = new ContentValues();
    contentValues.put(MyUsersDatabase.FIRST_NAME,firstName ); // First parameter(key) is the name of the column
    contentValues.put(MyUsersDatabase.LAST_NAME, lastName);
    long id = sqLiteDatabase.insert(MyUsersDatabase.TABLE_NAME, null, contentValues);
    return id;
}
static class MyUsersDatabase extends SQLiteOpenHelper
{
    private static final int DATABASE_VERSION = 4;
    private static final String DATABASE_NAME = "usersDatabase";
    private static final String TABLE_NAME = "usersTable";
    private static final String UID = "_id"; // User identification number
    private static final String FIRST_NAME = "First Name"; // Column
    private static final String LAST_NAME = "Last Name"; // Column
    private static final String CREATE_TABLE = "CREATE TABLE " + MyUsersDatabase.DATABASE_NAME + "(" 
    + UID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 
    + FIRST_NAME + " TEXT, " 
    + LAST_NAME + " TEXT);";
    private static final String DROP_TABLE = "DROP TBALE IF EXIST " + TABLE_NAME;
    private Context context;

    public MyUsersDatabase(Context context, String name, CursorFactory factory,int version)
    {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        this.context = context;
        ToastMessage.message(context, "Constructor was called");
    }
    @Override
    public void onCreate(SQLiteDatabase db) 
    {
        ToastMessage.message(context, "onCreate() was called");
        try
        {
            db.execSQL(CREATE_TABLE);
        }
        catch (SQLException e)
        {
            ToastMessage.message(context,"" + e);
        }
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
    {
        ToastMessage.message(context, "onUpgrade() was called");
        try
        {
            db.execSQL(DROP_TABLE);
            onCreate(db);
        } 
        catch (SQLException e) 
        {
            ToastMessage.message(context,"" + e);
        }
    }
}

LogCat:

09-14 16:50:13.711: E/SQLiteLog(26257): (1) near "Name": syntax error
09-14 16:50:13.713: E/SQLiteDatabase(26257): Error inserting Last Name= First Name=
09-14 16:50:13.713: E/SQLiteDatabase(26257): android.database.sqlite.SQLiteException: near "Name": syntax error (code 1): , while compiling: INSERT INTO usersTable(Last Name,First Name) VALUES (?,?)
09-14 16:50:13.713: E/SQLiteDatabase(26257):    at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:894)
09-14 16:50:13.713: E/SQLiteDatabase(26257):    at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:505)
09-14 16:50:13.713: E/SQLiteDatabase(26257):    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
09-14 16:50:13.713: E/SQLiteDatabase(26257):    at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1570)

点击一个Button后,我看到这个LogCat

主类:

protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sign_up);
    viewsInitialization();
    getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
    myUsersDatabase = new MyUsersDatabaseAdapter(SignUpActivity.this,"UsersDatabase" , null, 1);
contentValues = new ContentValues();
    signUpButton.setOnClickListener(new View.OnClickListener()
    {   
        @Override
        public void onClick(View v) 
        {
            userFirstName = firstNameEditText.getText().toString();
            userLastName = lastNameEditText.getText().toString();
            id = myUsersDatabase.inserDataToDatabase(userFirstName, userLastName);
            if (id < 0)
            {
                ToastMessage.message(SignUpActivity.this, "Unsuccessful row insertion");
            }
            else 
            {
                ToastMessage.message(SignUpActivity.this, "Successful row insertion");
            }
        }
    });
}

还有Toast "不成功的行插入"

我的代码有什么问题?

编辑

从列名中删除空白后,我得到这个LogCat:

9-14 17:17:04.049: E/SQLiteLog(32247): (1) table usersTable has no column named LastName
09-14 17:17:04.051: E/SQLiteDatabase(32247): Error inserting LastName=hsh FirstName=hshsh
09-14 17:17:04.051: E/SQLiteDatabase(32247): android.database.sqlite.SQLiteException: table usersTable has no column named LastName (code 1): , while compiling: INSERT INTO usersTable(LastName,FirstName) VALUES (?,?)
09-14 17:17:04.051: E/SQLiteDatabase(32247):    at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
09-14 17:17:04.051: E/SQLiteDatabase(32247):    at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:894)

不应该在表名中使用空白。如果要这样做,则必须在名称周围使用反引号。更好的解决方案是不使用空格重命名列。

问题是您的表中有带有空格的列,并且列名没有被打勾字符(')包裹。有两种方法可以解决这个问题:

第1路(推荐)

将表列从"FirstName"one_answers"LastName"重命名为"FirstName"one_answers"LastName"(注意删除的空格)。完成此操作后,您需要触发对onUpgrade的调用,以便运行升级代码(在您的示例中,它将删除旧表,以便创建新表)。之后,您的列名将匹配,不会有空白字符,并且您的数据库应该运行良好。

进行此更改后,您的旧数据库仍然有效,需要使用新列进行更新。您可以删除旧列,或者使用SQLiteOpenHelperonUpgrade特性,如前一段所述。

第二种方式 (不太好),但包括完整性

在代码周围添加刻度:

private static final String CREATE_TABLE = "CREATE TABLE " + MyUsersDatabase.DATABASE_NAME + "(" 
+ UID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 
+ "`" + FIRST_NAME + "` TEXT, " 
+ "`" + LAST_NAME + "` TEXT);";

这可以工作,但是在列名中包含空白字符通常被认为是不好的做法。

最终认为

您可以在列名周围添加任何一种方式,因为标记只是定义了包装在其中的是单个对象,并且应该一起解析。此外,列名中有空格也是不好的做法,永远不要在表名中包含空格(即使可能)。

最新更新